在Windows上的Pythonsubprocess输出?

我遇到了一些困难从一个subprocess标准输出pipe道输出。 我正在通过它启动一些第三方代码,以提取日志输出。 直到最近更新的第三方代码,一切正常。 更新之后,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) 

如果我用这个脚本replacethird_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()。 我正在启动的应用程序仍然运行很长一段时间(几天到几周)。 我实际上可以testing.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() 

首先,我会建议你简化这个例子,以确保你可以真正阅读任何东西。 从混合中删除线程的复杂性:

 proc = subprocess.Popen("third_party.exe", stdout=subprocess.PIPE, bufsize=1) print proc.communicate() 

如果这样的话,很好。 那么你可能会遇到问题,如何直接读取标准输出,或者可能在你的线程中。

如果这不起作用,你有没有尝试管道stderr标准输出?

 proc = subprocess.Popen("third_party.exe", stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1) 

更新

既然你说communicate()是死锁,这里是另一种方法,你可以尝试看看它是否与子进程的内部缓冲区的问题…

 import tempfile import subprocess w = tempfile.NamedTemporaryFile() p = subprocess.Popen('third_party.exe', shell=True, stdout=w, stderr=subprocess.STDOUT, bufsize=0) with open(w.name, 'r') as r: for line in r: print line w.close() 
 args = ['svn','log','-v'] def foo(info=''): import logging import subprocess import tempfile try: pipe = subprocess.Popen(args,bufsize = 0,\ stdout = subprocess.PIPE,\ stderr=subprocess.STDOUT) except Exception as e: logging.error(str(e)) return False while 1: s = pipe.stdout.read() if s: print s, if pipe.returncode is None: pipe.poll() else: break if not 0 == pipe.returncode: return False return True print foo() 

这一个应该工作,而不是线程,临时文件魔术。