在其他语言(如 bash 和 Python )中,当我们生成子进程时,这个新进程将从父进程继承stdout和stderr。这意味着子进程的任何输出都将打印到终端以及父进程的输出。
我们如何在Java中实现相同的行为?
我的第一次尝试是:
proc = Runtime.getRuntime().exec(cmd);
但它不起作用。基于this answer和this answer,我已将代码替换为:
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectOutput(System.out);
pb.redirectError(System.err);
但是这甚至都没有编译,因为参数与预期的方法参数不兼容。
答案 0 :(得分:15)
您需要读取您创建的进程的输出和错误流,并将输出写入您希望的位置(在您的情况下为System.out和System.err)。
编辑。上面的答案对于java< 7.从javadoc 7开始,它似乎可以改为调用
processBuilder.redirectOutput(Redirect.INHERIT)
答案 1 :(得分:3)
这不是太糟糕。我最初说" easy"然后我意识到我必须编写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();
}
答案 2 :(得分:1)
这当然是可能的。当fork设置为true时,Ant Java任务会执行此操作。我不记得所有细节,但快速看来,似乎大多数魔法都在PumpStreamHandler。您可以尝试从中找到一些灵感。