繁体   English   中英

使用Runtime.exec()运行Perl脚本时,BufferedReader.read()挂起

[英]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 如果正在运行的特定进程没有向这些流发送数据,则可以用关闭进程的流代替来读取它们,并且通常在没有更多数据时应关闭ProcessOutputStream 即使您不关心从它们读取的内容,也需要阅读这两个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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM