如何将子进程stdout / stderr重定向到Java中的主进程stdout / stderr?

在其他语言(如bashPython )中,当我们生成子进程时,这个新进程将从父进程inheritancestdout和stderr。 这意味着子进程的任何输出都将打印到终端以及父进程的输出。

我们如何在Java中实现相同的行为?

我的第一次尝试是:

proc = Runtime.getRuntime().exec(cmd); 

但它不会起作用。 基于这个答案和这个答案 ,我已经用以下代码替换了代码:

 ProcessBuilder pb = new ProcessBuilder(cmd); pb.redirectOutput(System.out); pb.redirectError(System.err); 

但是这甚至都没有编译,因为参数与预期的方法参数不兼容。

您需要读取已创建的进程的输出和错误流,并将输出写入您希望的位置(在您的情况下为System.out和System.err)。

编辑。 上面的答案对于java <7是正确的。从javadoc开始,它看起来可以代替调用

 processBuilder.redirectOutput(Redirect.INHERIT) 

这不是太糟糕。 我最初说“简单”,然后我意识到我必须编写InputStreamConsumer代码:

 public static class InputStreamConsumer extends Thread { private InputStream is; public InputStreamConsumer(InputStream is) { this.is = is; } @Override public void run() { try { int value = -1; while ((value = is.read()) != -1) { System.out.print((char)value); } } catch (IOException exp) { exp.printStackTrace(); } } } private void captureOutput(Process p) { InputStreamConsumer stdout; InputStreamConsumer errout; errout = new InputStreamConsumer(p.getErrorStream()); stdout = new InputStreamConsumer(p.getInputStream()); errout.start(); stdout.start(); } 

….在…之类的东西里面跑

  ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/D", "/C", myCommand, parm, parm...); try { System.out.println("Start "+myCommand); Process myProcess = pb.start(); captureOutput(myProcess); int returnCode = myProcess.waitFor(); System.out.println("myProcess: return code : "+returnCode); } catch (IOException e) { e.printStackTrace(); } 

这当然是可能的。 当fork设置为true时,Ant Java任务会执行此操作。 我不记得所有的细节,但快速看来,大多数魔法都出现在PumpStreamHandler中 。 您可以尝试从中找到一些灵感。