我发现自己最近不得不解决这个问题,而且花了一段时间才得到一些我觉得在大多数情况下都能正常工作的东西,所以就这样!(它还具有通过python记录器处理输出的良好副作用,我注意到这是Stackoverflow中的另一个常见问题)。
代码如下:import sys
import logging
import subprocess
from threading import Thread
logging.basicConfig(stream=sys.stdout,level=logging.INFO)
logging.addLevelName(logging.INFO+2,'STDERR')
logging.addLevelName(logging.INFO+1,'STDOUT')
logger = logging.getLogger('root')
pobj = subprocess.Popen(['python','-c','print 42;bargle'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
def logstream(stream,loggercb):
while True:
out = stream.readline()
if out:
loggercb(out.rstrip())
else:
break
stdout_thread = Thread(target=logstream,
args=(pobj.stdout,lambda s: logger.log(logging.INFO+1,s)))
stderr_thread = Thread(target=logstream,
args=(pobj.stderr,lambda s: logger.log(logging.INFO+2,s)))
stdout_thread.start()
stderr_thread.start()
while stdout_thread.isAlive() and stderr_thread.isAlive():
pass
输出如下:STDOUT:root:42
STDERR:root:Traceback (most recent call last):
STDERR:root: File "", line 1, in
STDERR:root:NameError: name 'bargle' is not defined
您可以替换子进程调用来执行任何您想要的操作,我只是选择了使用一个命令来运行python,我知道该命令将同时打印到stdout和stderr。关键位是在一个单独的线程中读取stderr和stdout。否则,当另一个数据准备好读取时,可能会阻塞一个数据的读取。