我尝试使用Apache commons来运行脚本,从终端运行的脚本看起来输出类似于以下内容的数据 -
编辑 - 编辑按照建议引入waitFor。
$./old-regress.sh
End with '*' as postcode !
postcode: city: street: house number: country: name: PDC:
postcode :
city :
street :
house_num :
routing_code :
post_freight_centre:
ic_c_err_code : 0260
post_code_err_code : ----
city_error_code : g---
street_error_code : ---f
local_gov_number 1 :
local_gov_number 2 :
State :
admin. district :
district :
local gov. unit :
routing_code :
error_text_address :
./old-regress.sh: line 2: 9722 Segmentation fault ./ictest < /tmp/tmp_inp_file
预期分段错误就是二进制ictest
(第三方)的工作方式。
现在,当我尝试使用Apache Commons exec通过我的应用程序执行相同的脚本时,它似乎只是打印错误而不是输出。 我尝试运行脚本的代码片段如下 -
public class Test {
public String execToString(String command) throws Exception {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
CommandLine commandline = CommandLine.parse(command);
DefaultExecutor exec = new DefaultExecutor();
exec.setWorkingDirectory(new File("/home/vigna"));
PumpStreamHandler streamHandler = new PumpStreamHandler(outputStream);
exec.setStreamHandler(streamHandler);
exec.setExitValue(139);
DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
exec.execute(commandline,resultHandler);
resultHandler.waitFor();
return(outputStream.toString());
}
public static void main(String[] argv) throws Exception {
Test test = new Test();
System.out.println(test.execToString("./old-regress.sh"));
}
上述代码段返回的输出如下 -
./old-regress.sh: line 2: 15981 Segmentation fault ./ictest < /tmp/tmp_inp_file
编辑2 - 我尝试使用ProcessBuilder。以下是我的代码 -
public class PBTest
{
public static void main(String[] args) throws Exception
{
ProcessBuilder pb = new ProcessBuilder("./old-regress.sh");
pb.directory(new File("/home/xxx/"));
Process p = pb.start();
String output = loadStream(p.getInputStream());
String error = loadStream(p.getErrorStream());
int rc = p.waitFor();
System.out.println("Process ended with rc=" + rc);
System.out.println("\nStandard Output:\n");
System.out.println(output);
System.out.println("\nStandard Error:\n");
System.out.println(error);
}
private static String loadStream(InputStream s) throws Exception
{
BufferedReader br = new BufferedReader(new InputStreamReader(s));
StringBuilder sb = new StringBuilder();
String line;
while((line=br.readLine()) != null)
sb.append(line).append("\n");
return sb.toString();
}
}
使用ProcessBuilder的结果如下 -
Process ended with rc=139
Standard Output:
Standard Error:
./old-regress.sh: line 2: 3975 Segmentation fault ./ictest < /tmp/tmp_inp_file
我认为139是因为分段错误而可能导致它失败。有什么建议吗?
任何关于我在这里做错了什么的指针?我如何捕获输出?
答案 0 :(得分:1)
我建议使用org.apache.commons.exec.LogOutputStream
而不是ByteArrayOutputStream。单个参数PumpStreamHandler构造函数捕获stdout和stderr - 所以你很擅长。创建LogOutputStream实例,并将其作为单个参数传递给PumpStreamHandler(就像您是BAOS一样)。
由于您只是在Handler上调用waitFor(),只需在DefaultExecutor上使用同步执行方法:int exitValue = exec.execute(commandline)
。
我会尝试将退出代码设置为null,然后从执行的响应中自己检查exitValue。我希望问题是你的ByteArrayOutputStream会从异常中截断,击败stdout,而不是完全刷新内容。
答案 1 :(得分:0)
你在做。
exec.execute(commandline);
// gives the program no time to start or run.
return(outputStream.toString());
你应该做一些像
这样的事情exec.execute(commandline).waitFor();
// get the output only after the program has finished.
return(outputStream.toString());