在Python中使用subprocess进行无缓冲读取进程

25 投票
3 回答
9713 浏览
提问于 2025-04-15 13:09

我正在尝试从一个会产生很长输出的程序中读取信息。不过,我希望能在它输出的时候就能获取到这些信息,而不是等到全部输出完再一起拿到。但是像下面这样的写法似乎会把输出内容先存起来,导致我最后只能一次性拿到所有的输出行:

p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, bufsize=0)
    for line in p.stdout:
        print line

我是在MacOS 10.5上进行这个尝试的。

3 个回答

3

其实这是一个在Python 2.6中修复的错误:http://bugs.python.org/issue3907

6

通常,每个程序在处理输入和输出时,都会比你想象的要多做一些缓冲。这种情况发生在程序认为它的输入输出通道实际上是一个终端的时候!

为了达到这种“善意的欺骗”目的,你可以使用 pexpect —— 它在Mac上运行得很好(在Windows上就比较麻烦,不过也有一些解决办法可以帮助你,幸运的是我们不需要讨论这些,因为你用的是Mac)。

30

文件迭代器在内部会自己进行一些缓存处理,具体可以参考这个链接。你可以试试下面的代码:

line = p.stdout.readline()
while line:
    print line
    line = p.stdout.readline()

另外,你还需要确保你运行的程序能够经常清空它的输出缓存。

撰写回答