【问题标题】:java process builder: run program with user input from command linejava process builder:从命令行使用用户输入运行程序
【发布时间】:2016-03-04 21:51:28
【问题描述】:

我需要使用进程构建器运行 shell 脚本或系统命令。在某些情况下,该命令会要求用户输入。例如,我有一个 java 程序“TestScanner”,它从命令行获取一个整数并将其打印出来。如果我直接在终端中运行它,就像

$bash -c "java TestScanner"
Enter a number:3
Number entered:3
$

程序显示输入消息。然后我输入“3”,然后它打印出结果,程序终止。

现在我需要运行命令

bash -c "java TestScanner"

来自 java 进程构建器。代码是

// cmdList has 3 elements: bash, -c, java TestScanner
ProcessBuilder pb = new ProcessBuilder(cmdList);
pb.redirectErrorStream(true);
pb.directory(new File(workDir));
Process p = pb.start();
InputStream in = p.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line = null;
while ((line = br.readLine()) != null)
{
    System.out.println("Line: " + line);
}

当我运行上面的代码 sn-p 时,它只是挂在那里。我什至看不到“输入数字”的消息。我不确定这是否是因为 p.getOutputStream() 正在等待?如何检测程序请求输入?我从这里Java Process with Input/Output Stream 尝试了代码 sn-p,但它在我的情况下不起作用。谢谢

【问题讨论】:

  • 类似thisthis
  • 这很有帮助。谢谢

标签: java processbuilder


【解决方案1】:

假设您有一个进程 p,您可以让 InputStream 读取进程打印的内容,就像您所做的那样。但是,如果您想提供一些输入,则必须使用该过程的 OutputStream。

Process p=pb.start();
OutputStream os = p.getOutputStream();
PrintWriter writer=new PrintWriter(os);
writer.write("1\n"); //'\n' to simulate enter key

在您的情况下,“输入数字:”行似乎没有换行符或末尾的 '\n' 字符,所以从技术上讲它不是一行。因此,使用缓冲读取器读取行将无济于事。对于长时间挂在那里的程序来说,这可能是一个问题。

【讨论】:

    【解决方案2】:

    您必须使用 ProcessBuilder 吗?使用 java.io.Console 类也可以实现同样的目的。

    【讨论】:

      【解决方案3】:

      在学习了 MadProgrammer 的精彩教程(参见他的 cmets)之后,我明白了我的问题发生了什么。

      InputStream in = p.getInputStream();
      BufferedReader br = new BufferedReader(new InputStreamReader(in));
      String line = null;
      while ((line = br.readLine()) != null) {...}
      

      这里 BufferedReader 试图读取一行(由 EOL 终止),但在用户向 OutputStream 输入内容并按 Enter 之前,流程对象返回的 InputStream 从未到达 EOL。这就是为什么没有出现提示信息“输入数字”的原因。将读取方法更改为

      is.read() != -1
      

      在while循环中会显示提示信息。那么问题是如何检测用户输入。当用户输入内容并按回车键时,数据位于 OutputStream 的缓冲区中。我们需要实现的是“感知”输出流中存在某些东西并且需要写入和刷新的逻辑。在我的例子中,我有一个 SWT Text 供用户输入数据,所以我向 Text 控件添加了一个 SWT.DefaultSelection 事件侦听器来响应键盘输入。然后我看到了正确的程序输出。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-22
        • 2021-12-10
        • 1970-01-01
        • 1970-01-01
        • 2014-08-28
        • 2016-03-12
        相关资源
        最近更新 更多