使用Java获取正在运行的Bash脚本的输出

24 浏览
0 Comments

使用Java获取正在运行的Bash脚本的输出

这个问题已经在这里有答案了:

Java中wait()和sleep()方法的区别

通常我使用这段代码来运行一个bash脚本并获取其输出

ProcessBuilder pb = new ProcessBuilder("/home/myscript");
Process p = pb.start();
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
String inputRead;
p.waitFor();
while((inputRead=stdInput.readLine()) != null){
    Helper.log(inputRead);
}

这个方法很有效,但是这次我使用的bash脚本没有终止,它一直处于活动状态,当它检测到一些东西时它会打印出来。我想启动这个脚本,等待一段时间,然后检查它是否检测到了一些东西。我尝试使用p.wait(periode);

p.wait(10000);
while((inputRead=stdInput.readLine()) != null){
    Helper.log(inputRead);
}

我不确定这是否是解决我的问题的正确方法,但无论如何,我使用这段代码时出现了错误

java.lang.IllegalMonitorStateException

我的问题并不是真正的等待,而是如何在等待之后停止进程,同时仍然能够获取输出

admin 更改状态以发布 2023年5月21日
0
0 Comments

下面是解决方案的完整示例。一个单独的线程切换标志以终止主线程,然后输出收集到的行:

private static boolean triggerToClose = false;
  public static void main(String[] args) throws IOException,
      InterruptedException {
    ProcessBuilder pb =
        new ProcessBuilder("/home/myscript");
    Process p = pb.start();
    java.io.InputStream is = p.getInputStream();
    BufferedReader stdInput = new BufferedReader(new InputStreamReader(is));
    String inputRead;
    new Thread(new Runnable() {
      public void run() {
        try {
          Thread.sleep(10000);
        } catch (InterruptedException e) {
        }
        triggerToClose = true;
      }
    }).start();
    StringBuilder sb = new StringBuilder();
    while ((inputRead = stdInput.readLine()) != null) {
      if (triggerToClose) {
        p.destroy();
        break;
      }
      sb.append(inputRead).append('\n');
    }
    System.out.println(sb);
  }

0
0 Comments

对于你的情况使用 .wait(1000) 完全是错误的。这也是异常告诉你的原因。
对于你的使用情况,有一个名为 waitFor(long timeout, TimeUnit unit) 的方法:

p.waitFor(10, TimeUnit.SECONDS);

0