使用python的子进程同时捕获和输出stderr

Catching and outputting stderr at the same time with python's subprocess

(目前使用python 3.2)

我需要能够:

  • 使用子进程运行命令
  • 该命令的stdout / stderr都需要实时打印到终端(如果它们都出现在stdout或stderr或其他任何地方都无关紧要
  • 与此同时,我需要一种方法来了解命令是否向stderr打印了任何内容(最好是打印出来的内容)。

我已经玩过子进程管道以及在bash中进行奇怪的管道重定向,以及使用tee,但到目前为止还没有找到任何可行的方法。 这是可能的吗?


我的解决方案

1
2
3
4
5
6
7
8
9
10
11
import subprocess

process = subprocess.Popen("my command", shell=True,
                           stdout=None, # print to terminal
                           stderr=subprocess.PIPE)
duplicator = subprocess.Popen("tee /dev/stderr", shell=True, # duplicate input stream
                              stdin=process.stderr,
                              stdout=subprocess.PIPE, # catch error stream of first process
                              stderr=None) # print to terminal
error_stream = duplicator.stdout
print('error_stream.read() = ' + error_stream.read())

尝试这样的事情:

1
2
3
4
5
6
7
8
9
import os

cmd = 'for i in 1 2 3 4 5; do sleep 5; echo $i; done'
p = os.popen(cmd)

while True:
    output = p.readline()
    print(output)
    if not output: break

在python2中,您可以使用popen3这样轻松捕获stderr:

1
i, o, err = os.popen3(cmd)

但在python3中似乎没有这样的功能。 如果您没有找到解决方法,请尝试直接使用subprocess.Popen,如下所述:http://www.saltycrane.com/blog/2009/10/how-capture-stdout-in-real-time-python/