我有一个Java微服务器,用于执行程序然后监视stderr,直到没有返回任何内容:
Process p = Runtime.getRuntime().exec("/bin/sh /var/task/bin/iTMSTransporter " + commandLine);
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
logger.log("StdErr:\n");
while ((s = stdError.readLine()) != null && p.isAlive()) {
System.out.println("stderr: " + s);
if (s.indexOf("DBG-X") == -1) {
result.stdErr += s + "\n";
}
}
this.logger.log("finished reading stderr\n");
这对于检测外部程序的完成是有效的,并且它始终有效。现在外部程序已经更新,它似乎开始输出stderr但是然后停止(应该更多地去 stderr 流)并最终超时。
然后我添加了p.isAlive()
以尝试捕获炮轰程序的完成。这似乎没有任何影响。现在这是令人沮丧的部分...在我的微服务的旧版本中,我使用NodeJS而不是Java来运行该程序。 NodeJS版本仍然可以通过监听close
事件来运行:
shell.stdout.on('data', data => {
stdout += data;
});
shell.stderr.on('data', data => {
stderr += data;
});
shell.on('error', error => {
reject(error);
});
shell.on('close', () => {
resolve({
stdout: stdout,
stderr: stderr
});
});
我能用Java做些什么吗?
----加法-----
我尝试了一些我在网上看过的东西:
Runtime rt = Runtime.getRuntime();
rt.addShutdownHook(new Thread(new Runnable() {
public void run() {
System.out.println("\nGOT HERE\n");
}
}));
Process p = rt.exec("/bin/sh /var/task/bin/iTMSTransporter " + commandLine);
以为我会在新线程中检测到它并输出“GOT HERE”但从未发送到控制台。
答案 0 :(得分:1)
如果您只是想等待该过程完成,waitFor
应该是合适的。
Process p = Runtime.getRuntime().exec("/bin/sh /var/task/bin/iTMSTransporter " + commandLine);
try {
p.waitFor();
// now, the process has terminated
} catch (InterruptedException e) {
// something went wrong
e.printStackTrace();
}
如果您确实希望捕获out-err-stream,那实际上有点复杂,因为您需要为此创建新线程(不是那个问题,而是一个很大的问题,但是如果您只是想知道该过程已经完成,那就是OTT。