在子进程执行时读取其标准错误输出
我想在一个子进程执行的时候,读取它写入到标准错误输出(stderr)里的内容。
不过,当我用我写的这个脚本时,stderr似乎在子进程结束之前没有任何内容可以让我读取。
#!/usr/bin/env python2
import sys
from subprocess import Popen, PIPE, STDOUT
if len(sys.argv) < 2:
print "Please provide a command"
sys.exit(1)
sub = Popen(sys.argv[1:], stdout=PIPE, stderr=STDOUT)
for i, line in enumerate(sub.stdout):
sys.stdout.write("%d: %s" % (i, line))
更新:
好的,我现在更接近解决方案了。如果我指定要读取的字节数,就能解决缓冲的问题。
#!/usr/bin/env python2
import sys
from subprocess import Popen, PIPE, STDOUT
if len(sys.argv) < 2:
print "Please provide a command"
sys.exit(1)
sub = Popen(sys.argv[1:], stdout=PIPE, stderr=STDOUT)
i = 0
while sub.poll() is None:
line = sub.stdout.read(64)
line.strip("\b")
sys.stdout.write("%d: %s\n" % (i, line))
i += 1
输出片段:
58: 86 q=21.0 size= 4541841kB time=00:00:22.08 bitrate=1685014.2kbi
frame= 567 fps= 86 q=22.0 size= 4543667kB time=00:00:2
frame= 621 fps= 87 q=20.0 sizs/s
frame= 4545352kB time=00:00:26.11 bitrate=1425939.2kbits/s
62: = 686 fps= 90 q=12.0 size= 4546970kB time=00:00:28.89 bitrate=1
frame= 758 fps= 93 q=25.0 size= 4548534kB t
frame= 794 fps= 92 bitrate=1168185.5kbits/s
65: q=27.0 size= 4550901kB time=00:00:33.40 bitrate=1115897.0kbits/
frame= 827 fps= 91 q=27.0 size= 4552324kB time=00:00:34.7
frame= 857 fps= 89 q=26.0 size=
frame= 254kB time=00:00:36.12 bitrate=1032874.9kbits/s
69: 892 fps= 88 q=25.0 size= 4556598kB time=00:00:37.36 bitrate=9988
frame= 948 fps= 89 q=19.0 size= 4558565kB time=
frame= 1006 fps= 90 q=19937320.4kbits/s
72: .0 size= 4560139kB time=00:00:42.16 bitrate=885880.0kbits/s
73: frame= 1060 fps= 91 q=19.0 size= 4561958kB time=00:00:44.49 bitr
frame= 1122 fps= 93 q=18.0 size= 4563460
frame= 1173 fps=0:47.08 bitrate=793898.4kbits/s
现在看起来我的问题是ffmpeg在使用退格字符或者类似的东西来干扰标准输出(stdout)。我不太确定这里发生了什么。
3 个回答
1
如果这个子进程没有使用块缓冲,那么你可以试试:
for i, line in enumerate(iter(sub.stdout.readline, b"")):
print i, line,
1
你应该对两个都使用管道(PIPE),另外,你还需要调用 communicate()
方法:
sub = Popen(sys.argv[1:], stdout=PIPE, stderr=PIPE)
output, error_output = sub.communicate()
print 'OUTPUT:'
print output
print 'ERROR:'
print error_output
4
我建议你使用sh这个模块。它是个很不错的软件,可以在Python中处理子进程,并且提供了一个非常好用的界面,你一定会喜欢的。你可以看看文档。
如果你真的不想用sh
模块,可以使用Popen的communicate
方法。