Subprocess.communicate将换行打印到标准输出

2 投票
1 回答
2502 浏览
提问于 2025-04-17 09:20

我有一个脚本,它会调用ffprobe,解析它的输出,然后把结果显示在控制台上。

这里是一个简化版的代码,没有解析的部分和命令行选项:

"""Invoke ffprobe to query a video file and parse the output"""

def ffprobe(fname):
    import subprocess as sub
    import re
    p = sub.Popen(['ffprobe', fname], stderr=sub.PIPE)
    stdout, stderr = p.communicate()

def main():
    ffprobe("foo.mp4")
    #print options.formatstr % locals()

if __name__ == '__main__':
    main()

你可以看到我代码里唯一的print语句被注释掉了,所以程序其实不应该输出任何东西。然而,我得到的结果是:

mpenkov@misha-desktop:~/co/youtube$ python ffprobe.py foo.mp4

mpenkov@misha-desktop:~/co/youtube$ python ffprobe.py foo.mp4

mpenkov@misha-desktop:~/co/youtube$ python ffprobe.py foo.mp4

每次调用时,神秘地输出了一行空白。这个空白是从哪里来的,我该怎么处理呢?

似乎有一个类似的问题在StackOverflow上,不过它没有使用communicate这个调用(http://stackoverflow.com/questions/7985334/python-subprocess-proc-stderr-read-introduce-extra-lines)。

1 个回答

5

我无法重现这个问题,所以可能是因为你传给 ffprobe 的文件有问题。

不过,从我看到的情况来看,stdout 没有被捕获,所以问题可能只是 ffprobe 正在向 stdout 输出一个换行符。

为了确认这一点,请把:

p = sub.Popen(['ffprobe', fname], stderr=sub.PIPE)
stdin, stderr = p.communicate()

替换成:

p = sub.Popen(['ffprobe', fname], stdout=sub.PIPE, stderr=sub.PIPE)
stdout, stderr = p.communicate()

在新版本中,stdout 被捕获了,来自 p.communicate 的输出也被正确命名,因为它返回的是 stdout 而不是 stdin

撰写回答