subprocess.PIPE的增量输出

时间:2011-06-06 20:42:21

标签: python subprocess stdout

我正在使用subprocess模块运行来自其他应用的命令我知道您可以执行以下操作

import subprocess

app = subprocess(args, stdout=subprocess.PIPE)
out, err = app.communicate()
print out

我希望输出显示为最终发生的一个大blob。想法?

2 个答案:

答案 0 :(得分:5)

问题可能是您在子进程中运行的命令缓冲其输出:在这种情况下,在Blender的答案中,process.stdout.read(1)将不会返回,直到子进程的输出缓冲区填满,导致它被刷新,因此被父进程看到。

有关缓冲如何影响事物的详细信息,请参阅this answerthis one

这里有一些脚本要说明:

# spew.py
import sys
import time

for i in range(10):
    print 'Message no. %d' % i
    #sys.stdout.flush()
    time.sleep(1)

# runspew.py
import subprocess
import time

start = time.time()
p = subprocess.Popen(['python', 'spew.py'], stdout=subprocess.PIPE)
data = p.stdout.read(1)
print 'Elapsed time to first byte read: %.2f' % (time.time() - start)
data = p.stdout.read()
print 'Elapsed time to last byte read: %.2f' % (time.time() - start)
p.wait()

现在,将两个脚本放在同一目录中并运行python runspew.py。你会看到这样的事情:

Elapsed time to first byte read: 10.05
Elapsed time to last byte read: 10.05

现在,移除sys.stdout.flush()spew.py的评论,然后再次python runspew.py。你现在可以看到这样的东西:

Elapsed time to first byte read: 0.02
Elapsed time to last byte read: 10.04

请注意runspew.py没有改变:只有作为子进程运行的程序才会改变。如果您正在运行的程序无法运行无缓冲(或经常刷新),那么您必须使用我链接到的其他答案中所述的expect / unbuffer。< / p>

答案 1 :(得分:2)

我做了一次Python shell实现,所以这是我用来运行命令的代码。它运行wgetnano很好,所以我认为代码符合您的需求:

  process = subprocess.Popen(shlex.split(command), stdout = subprocess.PIPE, stderr = subprocess.STDOUT)

  while True:
    output = process.stdout.read(1)

    if output == '' and process.poll() != None:
      break

    if output != '':
      sys.stdout.write(output)
      sys.stdout.flush()

基本上,您必须直接写入stdout