我有一个程序需要调用为一个带有python的子进程。这个程序是用java编写的。是啊我知道..。
无论如何,我需要捕捉所有的输出从上述程序。
不幸的是,当我用通信调用subprocess.popen2或subprocess.Popen时,当我使用分配给stdout的subprocess.PIPE和使用分配给stdout的文件描述符(从打开的返回)时,我损失了大约10%的输出数据。
子流程中的文档非常明确,如果您试图捕获子进程的所有输出,那么使用subprocess.PIPE是不稳定的。
我目前正在使用pexpect将输出转储到一个tmp文件中,但出于显而易见的原因,这需要花费很长时间。
我希望将所有数据保存在内存中,以避免磁盘写入。
欢迎任何推荐!谢谢!
import subprocess
cmd = 'java -Xmx2048m -cp "/home/usr/javalibs/class:/home/usr/javalibs/libs/dependency.jar" --data data --input input"
# doesn't get all the data
#
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
output = p.communicate()[0]
OR
# doesn't get all the data
#
fd = open("outputfile",'w')
p = subprocess.Popen(cmd, stdout=fd, shell=True)
p.communicate()
fd.close() # tried to use fd.flush() too.
# also tried
# p.wait() instead of p.communicate(), but wait doesn't really wait for the java program to finish running - it doesn't block
OR
# also fails to get all the data
#
import popen2
(rstdout, rstdin) = popen2.popen2(cmd)预期输出是一系列ascii线(几千条)。这些行包含一个数字和一行字符的末尾。
0\n
1\n
4\n
0\n
...发布于 2012-05-21 18:29:10
我使用的subprocess在stdout上的输出要大得多,但没有见过这样的问题。很难从你所展示的东西中得出什么是根本原因。我将检查以下情况:
因为p.wait()不为你工作。可能的情况是,当您阅读您的PIPE时,您的java程序仍然忙于打印最后10%。先把p.wait()直接拿出来:
PIPE之前插入足够大的等待时间(比如30秒),您的10%会出现吗?p.wait()没有阻止您的java程序。您的java程序是否进一步对其他program?p.wait()的返回值)进行子处理。您的java程序是否正常终止?如果问题不在并发模型中,那么检查java程序中的打印是否正确:
stdout?您是否倾向于或忽略IOException发布于 2012-05-21 19:06:17
这一定是与你实际调用的过程有关的东西。您可以通过使用另一个响应行的python脚本进行简单测试来验证这一点:
out.py
import sys
for i in xrange(5000):
print "%d\n" % i
sys.exit(0)test.py
import subprocess
cmd = "python out.py"
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
output = p.communicate()[0]
print output因此,您可以验证问题不是数据的大小,而是与您正在调用的进程的通信。
您还应该确认您正在运行的python版本,正如我以前所读过的关于Popen内部缓冲区的问题(但是使用一个单独的文件句柄,就像您通常为我建议的那样)。
如果子进程调用无限期挂起,将是一个缓冲区问题。但是如果这个过程是完成的,只是缺少线条,那么Popen就在做它的工作。
https://stackoverflow.com/questions/10689998
复制相似问题