[英]BufferedReader.read() hangs when running a perl script using Runtime.exec()
我正在尝试从Java代码运行perl脚本,并使用以下代码读取其输出:
String cmd = "/var/tmp/./myscript";
Process process = Runtime.getRuntime().exec(cmd);
stdin = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while((line = stdin.readLine()) != null) {
System.out.println(line);
}
但是代码始终挂在readLine()上。
我尝试使用
stdin.read();
相反,但这也挂起了。 尝试将cmd修改为
cmd = "perl /var/tmp/myscript";
并且
cmd = {"perl","/var/tmp/myscript"};
但这也挂了。 尝试在单独的线程中读取标准输入。 尝试在单独的线程中读取stdin和stderr。 仍然没有运气。
我知道这里有很多问题要处理由于未读取流而挂起Process.waitFor(),以及BufferedReader.read()挂起,尝试了所有建议的解决方案,但还是没有运气。
当然,在CLI上运行相同的脚本本身会将输出写入标准输出(控制台),并且存在退出代码0。我在Centos 6.6上运行。
任何帮助将不胜感激。
我假设直接从命令行运行时,脚本会运行到完成,产生预期的输出,并干净地终止。 如果不是,请先修复您的脚本。
几乎肯定会挂起readLine()
调用,这意味着既不会遇到行终止符,也不会遇到文件结尾。 换句话说,该方法被阻止等待脚本。 在这种情况下,脚本可能根本不产生任何输出,但不会终止。 例如,如果它希望在继续进行之前从其自己的标准输入中读取数据,则可能会发生这种情况。 如果它在输出到stderr时被阻塞,也可能会发生。
通常,您必须通过getInputstream()
和getErrorStream()
提供的InputStream
并行读取Process
的stdout及其stderr。 您还应该通过向getOutputStream()
提供所需的标准输入数据(也与读取并行)或关闭它来处理getOutputStream()
提供的OutputStream
。 如果正在运行的特定进程没有向这些流发送数据,则可以用关闭进程的流代替来读取它们,并且通常在没有更多数据时应关闭Process
的OutputStream
。 即使您不关心从它们读取的内容,也需要阅读这两个InputStreams
,因为如果不这样做,则该过程可能会阻塞或无法终止。 这样做很棘手,但是对于特定情况,要比编写通用支持要容易。 无论如何,还有ProcessBuilder
,它在某种程度上ProcessBuilder
了通用接口。
尝试像这样使用ProcessBuilder
:
String cmd = "/var/tmp/./myscript";
ProcessBuilder perlProcessBuilder = new ProcessBuilder(cmd);
perlProcessBuilder.redirectOutput(ProcessBuilder.Redirect.PIPE);
Process process = perlProcessBuilder.start();
stdin = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while((line = stdin.readLine()) != null) {
System.out.println(line);
}
从ProcessBuilder javadoc ( 链接 )
公共ProcessBuilder redirectOutput(ProcessBuilder.Redirect目标)
设置此流程构建器的标准输出目标。 随后由该对象的
start()
方法start()
子流程将其标准输出发送到此目标。如果目的地是
Redirect.PIPE
(初始值),则可以使用Process.getInputStream()
返回的输入流读取子流程的标准输出。 如果目标设置为任何其他值,则Process.getInputStream()
将返回空输入流。参数:
destination-新的标准输出目标
返回值:
这个过程的建设者
抛出:
IllegalArgumentException-如果重定向不对应于有效的数据目的地,即类型为READ
以来:
1.7
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.