我遇到了一些困难,从子流程标准输出管道获取输出。我正在通过它启动一些第三方代码,以提取日志输出。直到最近更新的第三方代码,一切正常。更新之后,python已经无限期地开始阻塞,并且没有实际显示任何输出。我可以手动启动第三方应用程序并查看输出。窗口上的Python子流程输出?
我正在使用的代码的基本版本:
import subprocess, time
from threading import Thread
def enqueue_output(out):
print "Hello from enqueue_output"
for line in iter(out.readline,''):
line = line.rstrip("\r\n")
print "Got %s" % line
out.close()
proc = subprocess.Popen("third_party.exe", stdout=subprocess.PIPE, bufsize=1)
thread = Thread(target=enqueue_output, args=(proc.stdout,))
thread.daemon = True
thread.start()
time.sleep(30)
这工作完全,如果我代替third_party.exe这个脚本:
import time, sys
while True:
print "Test"
sys.stdout.flush()
time.sleep(1)
所以我不清楚魔需要完成这项工作才能使用原始命令。
这些都是我没有成功尝试subprocess.Popen线的所有变体:
proc = subprocess.Popen("third_party.exe", stdout=subprocess.PIPE, bufsize=0)
proc = subprocess.Popen("third_party.exe", stdout=subprocess.PIPE, shell=True)
proc = subprocess.Popen("third_party.exe", stdout=subprocess.PIPE, creationflags=subprocess.CREATE_NEW_CONSOLE)
si = subprocess.STARTUPINFO()
si.dwFlags = subprocess.STARTF_USESTDHANDLES | subprocess.STARTF_USESHOWWINDOW
proc = subprocess.Popen("third_party.exe", stdout=subprocess.PIPE, startupinfo=si)
编辑1: 我实际上并不能在这种情况下使用.communicate()。我启动的应用程序仍在运行很长一段时间(几天到几周)。我实际上可以测试.communicate()的唯一方法就是在启动后不久就杀死该应用程序,我不觉得会给我有效的结果。
即使这个非线程版本失败:
import subprocess, time
from threading import Thread
proc = subprocess.Popen("third_party.exe", stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print "App started, reading output..."
for line in iter(proc.stdout.readline,''):
line = line.rstrip("\r\n")
print "Got: %s" % line
编辑2: 由于JDI,以下的作品没关系:
import tempfile, time, subprocess
w = "test.txt"
f = open("test.txt","a")
p = subprocess.Popen("third_party.exe", shell=True, stdout=f,
stderr=subprocess.STDOUT, bufsize=0)
time.sleep(30)
with open("test.txt", 'r') as r:
for line in r:
print line
f.close()
是否有可能您的第三方程序切换到写入stderr? – jdi
似乎并非如此。如果我拦截stderr,则会发生同样的情况(尽管如此,我确实在控制台上看到了应用程序的输出,但它只是打印,不会通过Python)。 – devicenull
听起来好像应用程序已停止使用标准输出并直接写入控制台。如果是这样,你可以做的不多。你能检查应用程序的供应商吗? –