您的目标是创建一个在 bash shell 中执行命令的 Java 程序,并且收集他们的输出。但是,您遇到了多个输出流在第一次读取后无法工作以及“管道损坏”异常的问题。
1.使用 ProcessBuilder:
替换 Process process = Runtime.getRuntime().exec("/bin/bash"); with:
ProcessBuilder builder = new ProcessBuilder("/bin/bash"); builder.redirectErrorStream(true); Process process = builder.start();
ProcessBuilder 允许将标准错误重定向到标准输出,从而无需为 stderr 和 stdout 使用单独的线程。
2.等待输出完成:
从输出流读取的循环 (reader.readline()) 将阻塞,直到进程退出或发送文件结尾。为了避免挂起,请确保仅在收到预期输出时才进行循环迭代。
3.使用“魔线”标记输出结束:
要可靠地确定执行命令的输出何时完成,请考虑写出特定行(例如“--EOF--”)表示输出结束。下面的代码片段演示了这种技术,有助于处理进程不以换行符终止的情况:
while (scan.hasNext()) { String input = scan.nextLine(); if (input.trim().equals("exit")) { writer.write("exit\n"); } else { writer.write("((" + input + ") && echo --EOF--) || echo --EOF--\n"); } writer.flush(); line = reader.readLine(); while (line != null && ! line.trim().equals("--EOF--")) { System.out.println("Stdout: " + line); line = reader.readLine(); } if (line == null) { break; } }
注意:这种方法可确保执行命令的所有输出在输入另一个命令之前捕获。它允许在线程计划任务中连续执行命令,而不会遇到“Broken pipeline”异常。
以上是如何在 Java 中可靠地执行 Bash 命令并捕获其输出?的详细内容。更多信息请关注PHP中文网其他相关文章!