我正在尝试从Java代码运行perl脚本并使用以下代码读取它的输出:
stdin.read();
但代码总是挂在readLine()上。
我尝试使用
cmd = "perl /var/tmp/myscript";
相反,但也挂起。 尝试将cmd修改为
cmd = {"perl","/var/tmp/myscript"};
还
{{1}}
但那也挂了。 尝试在单独的线程中读取stdin。尝试在单独的线程中读取stdin和stderr。仍然没有运气。
我知道这里有很多问题因为没有读取流来处理Process.waitFor(),以及BufferedReader.read()挂起,尝试了所有建议的解决方案,但仍然没有运气。
当然,在CLI上运行相同的脚本会将输出写入标准输出(控制台),并且存在退出代码0。 我在Centos 6.6上运行。
任何帮助将不胜感激。
答案 0 :(得分:1)
我认为直接从命令行运行时,脚本会运行完成,产生预期的输出,并彻底终止。如果没有,请先修复您的脚本。
readLine()
调用几乎肯定意味着既不会遇到行终止符也不会遇到文件结尾。换句话说,该方法被阻止等待脚本。也许脚本在条件下根本不产生输出,但不会终止。例如,如果它希望在进行之前从其自己的标准输入中读取数据,则可能发生这种情况。如果它在输出到它的stderr时被阻止,也可能发生。
在一般情况下,您必须通过Process
和InputStream
提供的getInputstream()
并行读取getErrorStream()
的标准输出和stderr。您还应该通过提供所需的标准输入数据(也与读数并行)或关闭它来处理OutputStream
提供的getOutputStream()
。如果您运行的特定进程没有向这些流发送数据,您可以替换关闭流程的流来读取它们,并且您通常应关闭Process
的{{1}}当你没有更多的数据时。您需要阅读两个OutputStream
,即使您不关心从中读取的内容,因为如果您不这样做,过程可能会阻止或无法终止。这对于特定情况来说是正确的,但对于编写广义支持更容易。无论如何,有InputStreams
,它在某种程度上可以实现更简单的通用界面。
答案 1 :(得分:1)
尝试使用import numpy as np
import theano
import theano.tensor as T
x,y,z = T.dmatrices('x','y','z')
A = theano.shared(np.random.rand(3,4), borrow=True, name='A')
B = theano.shared(np.random.rand(3,4), borrow=True, name='B')
f = x+y+B
,如下所示:
ProcessBuilder
来自ProcessBuilder javadoc (link)
public ProcessBuilder redirectOutput(ProcessBuilder.Redirect destination)
设置此进程构建器的标准输出目标。随后由此对象的
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); }
方法启动的子进程将其标准输出发送到此目标。如果目标是
start()
(初始值),则可以使用Redirect.PIPE
返回的输入流读取子进程的标准输出。如果目标设置为任何其他值,则Process.getInputStream()
将返回空输入流。<强>参数:强>
目的地 - 新标准输出目的地
<强>返回:强>
此流程构建器
<强>抛出:强>
IllegalArgumentException - 如果重定向与数据的有效目标不对应,即类型为READ
<强>时间:强>
1.7