如何利用子进程获得实时输出?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (28)

我试图为命令行程序(svnadmin验证)编写一个包装脚本,它将显示操作的良好进度指示符。这要求我能够看到包装程序的每一行输出。

我想我应该用subprocess.Popen,使用stdout=PIPE,然后读每一行,当它进来,并采取相应的行动。但是,当我运行下面的代码时,输出似乎被缓冲在某个地方,导致它出现在两个块中,第1行到332行,然后是333行到439行(最后一行输出)。

from subprocess import Popen, PIPE, STDOUT

p = Popen('svnadmin verify /var/svn/repos/config', stdout = PIPE, 
        stderr = STDOUT, shell = True)
for line in p.stdout:
    print line.replace('\n', '')

在查看了一些关于子进程的文档之后,我发现bufsize参数Popen因此,我尝试将bufsize设置为1(每行缓冲)和0(没有缓冲区),但这两个值似乎都没有改变行的传递方式。

所以我编写了以下输出循环:

while True:
    try:
        print p.stdout.next().replace('\n', '')
    except StopIteration:
        break

但结果是一样的。

是否可能获得使用子进程执行的程序的“实时”程序输出?在Python中是否有其他与前向兼容的选项(不是exec*)?

提问于
用户回答回答于

我试过这个,由于某种原因,代码

for line in p.stdout:
  ...

缓冲区,变体

while True:
  line = p.stdout.readline()
  if not line: break
  ...

用户回答回答于
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, bufsize=1)
for line in iter(p.stdout.readline, b''):
    print line,
p.stdout.close()
p.wait()

扫码关注云+社区