【发布时间】:2011-12-05 11:20:21
【问题描述】:
也许有人在外面可以帮助我解决这个问题。 (我在 SO 上看到了许多与此类似的问题,但没有一个同时处理标准输出和标准错误,或者处理与我的情况非常相似的情况,因此提出了这个新问题。)
我有一个 python 函数,它打开一个子进程,等待它完成,然后输出返回码,以及标准输出和标准错误管道的内容。在进程运行时,我还想在填充两个管道时显示它们的输出。我的第一次尝试结果是这样的:
process = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout = str()
stderr = str()
returnCode = None
while True:
# collect return code and pipe info
stdoutPiece = process.stdout.read()
stdout = stdout + stdoutPiece
stderrPiece = process.stderr.read()
stderr = stderr + stderrPiece
returnCode = process.poll()
# check for the end of pipes and return code
if stdoutPiece == '' and stderrPiece == '' and returnCode != None:
return returnCode, stdout, stderr
if stdoutPiece != '': print(stdoutPiece)
if stderrPiece != '': print(stderrPiece)
这有几个问题。因为read() 一直读取到EOF,所以while 循环的第一行在子进程关闭管道之前不会返回。
我可以将read() 替换为read(int),但打印输出失真,在读取字符的末尾被截断。我可以用readline() 代替,但是当同时出现许多输出和错误时,打印输出会失真。
也许有一个我不知道的read-until-end-of-buffer() 变体?还是可以实现?
也许最好按照answer to another post 中的建议实现sys.stdout 包装器?但是,我只想在此函数中使用包装器。
社区还有其他想法吗?
感谢您的帮助! :)
编辑:解决方案确实应该是跨平台的,但如果您有不跨平台的想法,请将它们分享出去以保持头脑风暴的进行。
对于我的另一个 python 子进程头抓手,请查看我在 accounting for subprocess overhead in timing 上的另一个问题。
【问题讨论】:
-
你可能想看看 pexpect 之类的东西。
-
为什么不直接创建一个StringIO并将同一个实例传递给子进程的stdout和stderr?
-
@NathanErnst:因为那行不通。
stdout和stderr必须是真实的操作系统级文件描述符。 -
@Sven Marnach,我刚刚检查了文档,
stderr可以设置为STDOUT,这将重定向,因此您可以将stdout设置为PIPE,然后从 @987654339 中读取@.
标签: python subprocess