gpt4 book ai didi

python - subprocess.Popen 处理 stdout 和 stderr

转载 作者:太空宇宙 更新时间:2023-11-03 12:11:06 27 4
gpt4 key购买 nike

我正在尝试从 subprocess.Popen 调用中处理 stdoutstderr,该调用通过 subprocess.PIPE 捕获两者 但希望在输出出现时对其进行处理(例如在终端上打印它们)。

我见过的所有当前解决方案都会等待 Popen 调用完成,以确保所有 stdoutstderr 被捕获,以便随后进行处理。

这是一个带有混合输出的示例 Python 脚本,在实时(或尽可能实时)处理它时我似乎无法复制订单:

$ cat mix_out.py

import sys

sys.stdout.write('this is an stdout line\n')
sys.stdout.write('this is an stdout line\n')
sys.stderr.write('this is an stderr line\n')
sys.stderr.write('this is an stderr line\n')
sys.stderr.write('this is an stderr line\n')
sys.stdout.write('this is an stdout line\n')
sys.stderr.write('this is an stderr line\n')
sys.stdout.write('this is an stdout line\n')

似乎可行的一种方法是使用线程,因为这样读取将是异步的,并且可以在 subprocess 产生输出时进行处理。

当前的实现只是先处理 stdout,最后处理 stderr,如果输出最初在两者之间交替,这可能是骗人的:

cmd = ['python', 'mix_out.py']

process = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
close_fds=True,
**kw
)

if process.stdout:
while True:
out = process.stdout.readline()
if out == '' and process.poll() is not None:
break
if out != '':
print 'stdout: %s' % out
sys.stdout.flush()

if process.stderr:
while True:
err = process.stderr.readline()
if err == '' and process.poll() is not None:
break
if err != '':
print 'stderr: %s' % err
sys.stderr.flush()

如果我运行上面的代码(保存为 out.py)来处理上面的 mix_out.py 示例脚本,流将(如预期的那样)按顺序处理:

$ python out.py
stdout: this is an stdout line
stdout: this is an stdout line
stdout: this is an stdout line
stdout: this is an stdout line
stderr: this is an stderr line
stderr: this is an stderr line
stderr: this is an stderr line
stderr: this is an stderr line

我知道某些系统调用可能会缓冲,对此我没有意见,我要解决的一件事是尊重流发生时的顺序。

有没有一种方法能够同时处理 stdoutstderr 因为它来自 subprocess without必须使用线程? (代码在无法使用线程的受限远程系统中执行)。

必须区分 stdout 和 stderr(如示例输出所示)

理想情况下,最好不要使用额外的库(例如,我知道 pexpect 可以解决这个问题)

很多例子都提到了 select 的使用,但我没有想出可以保留输出顺序的方法。

最佳答案

如果您正在寻找一种将 subprocess.Popen 实时输出到 stdout/stderr 的方法,您应该能够通过以下方式实现:

import sys, subprocess
p = subprocess.Popen(cmdline,
stdout=sys.stdout,
stderr=sys.stderr)

也许使用 stderr=subprocess.STDOUT 可以简化您的过滤,IMO。

关于python - subprocess.Popen 处理 stdout 和 stderr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26369829/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com