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被拋出