2016-10-03 213 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捕获了所有的错误输出,在这种情况下只是“错误”。