在这个问题中,hanan-n询问是否有可能有一个向stdout输出的python子进程,同时还将输出保留在字符串中以供以后处理。在这种情况下,解决方案是遍历每条输出线并手动打印它们:
output = [] p = subprocess.Popen(["the", "command"], stdout=subprocess.PIPE) for line in iter(p.stdout.readline, ''): print(line) output.append(line)
但是,此解决方案不能推广到您想要对stdout和stderr都执行此操作的情况,同时满足以下条件:
我浏览了子流程文档,但找不到任何可以实现此目的的东西。我能找到的最接近的方法是添加stderr=subprocess.stdout并使用与上述相同的解决方案,但随后我们就失去了常规输出和错误之间的区别。有任何想法吗?我猜测解决方案- 如果有的话-将涉及对p.stdout和的异步读取p.stderr。
stderr=subprocess.stdout
p.stdout
p.stderr
这是我想做的一个例子:
p = subprocess.Popen(["the", "command"]) p.wait() # while p runs, the command's stdout and stderr should behave as usual p_stdout = p.stdout.read() # unfortunately, this will return '' unless you use subprocess.PIPE p_stderr = p.stderr.read() # ditto [do something with p_stdout and p_stderr]
这个例子似乎对我有用:
# -*- Mode: Python -*- # vi:si:et:sw=4:sts=4:ts=4 import subprocess import sys import select p = subprocess.Popen(["find", "/proc"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout = [] stderr = [] while True: reads = [p.stdout.fileno(), p.stderr.fileno()] ret = select.select(reads, [], []) for fd in ret[0]: if fd == p.stdout.fileno(): read = p.stdout.readline() sys.stdout.write('stdout: ' + read) stdout.append(read) if fd == p.stderr.fileno(): read = p.stderr.readline() sys.stderr.write('stderr: ' + read) stderr.append(read) if p.poll() != None: break print 'program ended' print 'stdout:', "".join(stdout) print 'stderr:', "".join(stderr)
通常,在任何情况下您想同时处理多个文件描述符,却又不知道哪个文件可以读取内容,则应使用select或等效方法(例如Twisted Reactor)。