2016-11-16 47 views
0

我有一个java restful服务方法,它使用processBuilder执行myscript.sh。我的脚本需要一个输入(例如 - myscript.sh/path/to-a /文件夹)。 里面的脚本是这样的如何等待多线程shell脚本执行完成后在我的web服务中调用?

-> execute a command which is multithreaded i.e parallel processing 
-> echo "my message" 

现在从Linux命令行把我的脚本时,它执行罚款。首先运行完所有线程,然后显示终端上显示的线程命令执行的一些文本输出,然后显示回显我的消息。

但是当我使用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脚本获得相同的行为吗?

+0

你也可以上传你的脚本是干什么的?上述看起来很好,除了一些异常处理。 –

+0

你是否在shell脚本内运行任何可执行文件?如果是这样,你的脚本可能会在它结束之前返回...并因此杀死可执行文件(或者让它成为孤儿)。 – blackpen

+0

您是否希望脚本在完成其平行工作之前被阻止?还是不等待脚本完成的Java代码? – alok

回答

1

使用ProcessBuilder.redirectErrorStream(boolean redirectErrorStream)与参数true将错误合并到输出。或者,您也可以使用shell命令语法cmd 2>&1将错误与输出合并。

这些都是一些的情况下,为什么你可能立即得到最后echo声明(而不是脚本需要时间来运行和返回正确的结果)的输出:

  • 缺少环境变量
  • 将推出的bash只需源.bashrc或者一些这样的林资源文件
  • 将推出的bash可能无法在正确的目录中运行(您可以在设定的ProcessBuilder本)
  • 推出的bash可能无法在其路径是寻找一些脚本/可执行
  • 将推出的bash可能无法在路径中寻找合适的库的任何可执行的

一旦合并错误,你就可以自己调试并查看错误。

+0

谢谢。它像一个魅力 –

0

在你的情况下,独立的进程可以用两种方式产生了:

1)猛砸

/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()(在获取流之前)

以下是用于Process的JavaDoc。waitFor():

导致当前线程在必要时等待,直到此Process对象表示的进程终止。如果子进程已经终止,则此方法立即返回。如果子进程尚未终止,则调用线程将被阻塞,直到子进程退出。

返回: 由此Process对象表示的子进程的退出值。按照惯例,值0表示正常终止。 抛出: InterruptedException - 如果当前线程被另一个线程在等待时,则等待结束中断,一个InterruptedException被抛出