我正在使用Apache Commons Exec并尝试启动可在整个应用程序期间工作的子进程。它应该启动进程,接受两个输入命令并保持在后台。现在它只接受一个命令(至少是什么stdout显示)并终止。你能救我吗?
CommandLine cmdLine = new CommandLine("app.exe");
cmdLine.addArgument("argument");
DefaultExecutor executor = new DefaultExecutor();
OutputStream os = new ByteArrayOutputStream();
InputStream is = new ByteArrayInputStream(("command1;\ncommand2;\n").getBytes());
executor.setStreamHandler(new PumpStreamHandler(os,null,is));
DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
executor.execute(cmdLine,resultHandler);
System.out.println(os.toString());
resultHandler.waitFor();
答案 0 :(得分:1)
我认为这两行的顺序错误:
System.out.println(os.toString());
resultHandler.waitFor();
应该是这样的(允许进程完成它的输出):
resultHandler.waitFor();
System.out.println(os.toString());
修改强>
仍然不能100%确定你的目标,但我认为我错过了原始请求中的“只留在后台”部分。实现这一目标的一种方法是使用PipedInputStream
& PipedOutputStream
对与流程进行对话。完成后,您可以关闭输出流。如果您希望在完成之前访问流程的输出,则可以使用类似的技术进行输出,方向相反。
我没有方便的Windows机器,但以下适用于我:
public static void main(String[] args) {
try {
CommandLine cmdLine = new CommandLine("/bin/bash");
DefaultExecutor executor = new DefaultExecutor();
OutputStream os = new ByteArrayOutputStream();
PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = new PipedInputStream(pos);
executor.setStreamHandler(new PumpStreamHandler(os, null, pis));
DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
executor.execute(cmdLine, resultHandler);
PrintWriter pw = new PrintWriter(pos);
pw.println("ls -l /usr");
pw.println("pwd");
pw.close();
resultHandler.waitFor();
System.out.println(os.toString());
} catch (Exception e) {
e.printStackTrace();
}
}