Java Process.getErrorStream不';无法捕获所有错误
我使用ProcessBuilder创建一个在Linux上运行脚本的进程。我需要检查执行此脚本时是否有错误Java Process.getErrorStream不';无法捕获所有错误,java,Java,我使用ProcessBuilder创建一个在Linux上运行脚本的进程。我需要检查执行此脚本时是否有错误 public static String contentInStream(InputStream stream) throws IOException { return contentInReader(new InputStreamReader(stream)); } public static String contentInReader(Reader reader) throw
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
问题是字符串错误只包含“Error”,而不是来自命令“date>in”的错误。未按预期创建文件“in”。如果我尝试“/testScript.sh>/tmp/std 2>/tmp/err”,这两个错误都在/tmp/err中,正如预期的那样
字符串错误包含:错误
脚本自行运行时的输出:/apps/testScript.sh:第2行:输入:权限被拒绝
错误
PS:我还按照测试脚本中最后两行的顺序进行了测试。我得到了相同的结果,因此错误可能不在contentInReader中。我解决了它。显然,当脚本从Java进程启动时,它是在另一个目录中执行的,在Java进程中脚本具有写权限。因此没有错误,getErrorStream捕获了所有错误输出,在本例中只捕获了“错误”。您是否尝试将
脚本
作为ProcessBuilder的唯一参数?将第一个参数设为sh
是多余的,因为pb.start()
调用了sh-c
@walsht:你是对的,但是删除sh并不能解决问题。你做错了。您需要捕获输出和错误流,并且在调用waitFor()
之前需要这样做。否则,生产过程可能会受到干扰。您应该启动两个线程,每个线程一个,然后等待它们完成,或者合并输出流和错误流并使用当前代码,然后调用waitFor()
@EJP:我在寻找解决方案时发现了这一点。但是,脚本的输出保证是短的,因此不会有问题。合并输出和错误流不是一个选项,因为如果有错误,我必须抛出一个异常。如果我不知道输出是否为错误,我无法决定是否必须抛出异常。如果有错误,脚本应返回非零值,您可以通过exitStatus()
获取该值。