2016-10-03 216 views
-1

我使用ProcessBuilder創建一個在Linux上運行腳本的進程。我需要檢查執行此腳本時是否有錯誤。Process.getErrorStream不捕獲所有錯誤

public static String contentInStream(InputStream stream) throws IOException 
{ 
    return contentInReader(new InputStreamReader(stream)); 
} 

public static String contentInReader(Reader reader) throws IOException 
{ 
    BufferedReader br = new BufferedReader(reader); 
    String line; 
    String content = ""; 
    while ((line = br.readLine())!=null) 
    { 
     content += line+"\n"; 
    } 
    return content; 
} 

public static void execScript(String script) 
{ 
    ProcessBuilder pb = new ProcessBuilder("sh", script); 
    Process process = pb.start(); 
    process.waitFor(); 
    String errors = contentInStream(process.getErrorStream()); 
    if (!errors.isEmpty()) 
    { 
     throw new RuntimeException(errors); 
    } 
} 

在測試腳本我通過嘗試寫入一個文件,其中劇本沒有寫權限明確寫入錯誤通道,和一個產生兩個錯誤,一個。

echo Warning 
date > in 
>&2 echo Error 

問題是,字符串錯誤只包含「錯誤」,而不是命令「date> in」中的錯誤。按照預期,不會創建「in」文件。如果我嘗試「./testScript.sh>/tmp/std 2>/tmp/err」,兩個錯誤都在/ tmp/err中,正如預期的那樣。

字符串錯誤包括:時腳本本身運行Error

輸出:
/apps/testScript.sh: line 2: in: Permission denied Error

PS:我還與反向測試腳本的最後兩行的測試順序。我得到了同樣的結果,所以錯誤可能不在contentInReader中。

+0

您是否嘗試過使用'script'作爲ProcessBuilder的唯一參數?自從'pb.start()'調用'sh -c'以來,讓第一個參數成爲'sh'是重複的。 – walsht

+0

@walsht:你說的對,但刪除sh並不能解決問題。 –

+0

你做錯了。您需要捕獲輸出和錯誤流,並且在調用waitFor()之前需要這樣做*。否則,該過程可能會卡住產生輸出。您應該啓動兩個線程,每個線程都有一個線程,然後等待它們完成,或者合併輸出和錯誤流並使用您的當前代碼,然後*然後*調用waitFor()。 – EJP

回答

-2

我解決了它。顯然,當腳本從Java進程啓動時,該腳本在不同的目錄中執行,其中該腳本具有寫入權限。所以沒有錯誤,並且getErrorStream捕獲了所有的錯誤輸出,在這種情況下只是「錯誤」。