如何等待多线程 shell 脚本执行完成在我的网络服务中调用?
How to wait for multi-threaded shell script execution to finish called inside my web service?
我有一个 java restful 服务方法,它使用 processBuilder 执行 myscript.sh。我的脚本需要一个输入(示例 - myscript.sh /path/to-a/folder)。
在脚本里面是这样的
-> execute a command which is multithreaded i.e parallel processing
-> echo "my message"
现在,当从 linux 命令行调用我的脚本时,它执行得很好。首先,所有线程 运行ning 完成,然后在终端上显示线程命令执行的一些文本输出,然后显示回显我的消息。
但是当我使用 processBuilder 从 java 调用相同的脚本时,最后一条回显消息立即出现并且执行结束。
按照我从 java
调用脚本的方式
ProcessBuilder processBuilder = new ProcessBuilder("/bin/bash","/path/to/myscript.sh","/path/to/folder/data");
Process proc = processBuilder.start();
StringBuffer output = new StringBuffer();
BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = "";
while((line = reader.readLine()) != null){
output.append(line + "\n");
}
System.out.println("### " + output);
我不知道发生了什么,也不知道如何调试。
当从终端或 java processBuilder 运行 时,有人能告诉我如何从 shell 脚本获得相同的行为吗?
使用带有参数 true
的 ProcessBuilder.redirectErrorStream(boolean redirectErrorStream)
将错误合并到输出中。或者,您也可以使用 shell 命令语法 cmd 2>&1
将错误与输出合并。
在某些情况下,您可能 立即获得最后一个 echo
语句的输出 (而不是脚本花时间 运行 和 return 正确的结果):
- 缺少环境变量
- 启动的 bash 需要 source .bashrc 或一些这样的资源文件
- 启动的 bash 可能 运行 不在正确的目录中(您可以在 ProcessBuilder 中设置)
- 已启动的 bash 可能无法在其 PATH
中找到一些 script/executable
- 已启动的 bash 可能无法在任何可执行文件的路径中找到合适的库
合并错误后,您将能够自行调试并查看错误。
在您的上下文中,可以通过两种方式生成单独的进程:
1) Bash
/path/to/executables/executable &
这将生成一个新的可执行文件,您需要等待它完成。
Here's an answer that will help you.
2) Java
Process exec = Runtime.getRuntime().exec(command);
status = exec.waitFor();
本质上,您需要等待进程结束,然后才能开始读取其 std/err 流。
如果我正确理解了这个问题,只需将这一行添加到您的代码中就足够了:status = exec.waitFor()
(在您获取流之前)
这是 JavaProcess.waitFor() 的文档:
Causes the current thread to wait, if necessary, until the process represented by this Process object has terminated. This method returns immediately if the subprocess has already terminated. If the subprocess has not yet terminated, the calling thread will be blocked until the subprocess exits.
Returns:
the exit value of the subprocess represented by this Process object. By convention, the value 0 indicates normal termination.
Throws:
InterruptedException - if the current thread is interrupted by another thread while it is waiting, then the wait is ended and an InterruptedException is thrown
我有一个 java restful 服务方法,它使用 processBuilder 执行 myscript.sh。我的脚本需要一个输入(示例 - myscript.sh /path/to-a/folder)。 在脚本里面是这样的
-> execute a command which is multithreaded i.e parallel processing
-> echo "my message"
现在,当从 linux 命令行调用我的脚本时,它执行得很好。首先,所有线程 运行ning 完成,然后在终端上显示线程命令执行的一些文本输出,然后显示回显我的消息。
但是当我使用 processBuilder 从 java 调用相同的脚本时,最后一条回显消息立即出现并且执行结束。
按照我从 java
调用脚本的方式ProcessBuilder processBuilder = new ProcessBuilder("/bin/bash","/path/to/myscript.sh","/path/to/folder/data");
Process proc = processBuilder.start();
StringBuffer output = new StringBuffer();
BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = "";
while((line = reader.readLine()) != null){
output.append(line + "\n");
}
System.out.println("### " + output);
我不知道发生了什么,也不知道如何调试。 当从终端或 java processBuilder 运行 时,有人能告诉我如何从 shell 脚本获得相同的行为吗?
使用带有参数 true
的 ProcessBuilder.redirectErrorStream(boolean redirectErrorStream)
将错误合并到输出中。或者,您也可以使用 shell 命令语法 cmd 2>&1
将错误与输出合并。
在某些情况下,您可能 立即获得最后一个 echo
语句的输出 (而不是脚本花时间 运行 和 return 正确的结果):
- 缺少环境变量
- 启动的 bash 需要 source .bashrc 或一些这样的资源文件
- 启动的 bash 可能 运行 不在正确的目录中(您可以在 ProcessBuilder 中设置)
- 已启动的 bash 可能无法在其 PATH 中找到一些 script/executable
- 已启动的 bash 可能无法在任何可执行文件的路径中找到合适的库
合并错误后,您将能够自行调试并查看错误。
在您的上下文中,可以通过两种方式生成单独的进程:
1) Bash
/path/to/executables/executable &
这将生成一个新的可执行文件,您需要等待它完成。
Here's an answer that will help you.
2) Java
Process exec = Runtime.getRuntime().exec(command);
status = exec.waitFor();
本质上,您需要等待进程结束,然后才能开始读取其 std/err 流。
如果我正确理解了这个问题,只需将这一行添加到您的代码中就足够了:status = exec.waitFor()
(在您获取流之前)
这是 JavaProcess.waitFor() 的文档:
Causes the current thread to wait, if necessary, until the process represented by this Process object has terminated. This method returns immediately if the subprocess has already terminated. If the subprocess has not yet terminated, the calling thread will be blocked until the subprocess exits.
Returns: the exit value of the subprocess represented by this Process object. By convention, the value 0 indicates normal termination. Throws: InterruptedException - if the current thread is interrupted by another thread while it is waiting, then the wait is ended and an InterruptedException is thrown