首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用子进程获取实时输出

使用子进程获取实时输出
EN

Stack Overflow用户
提问于 2009-04-30 00:45:48
回答 19查看 135.4K关注 0票数 153

我正在尝试为一个命令行程序(svnadmin I)编写一个包装器脚本,它将显示一个很好的操作进度指示器。这要求我能够在包装的程序输出后立即看到它的每一行输出。

我想我只需要使用subprocess.Popen执行程序,使用stdout=PIPE,然后读取传入的每一行,并对其执行相应的操作。然而,当我运行下面的代码时,输出似乎被缓冲在某处,导致它出现在两个块中,第1到332行,然后是333到439 (输出的最后一行)。

代码语言:javascript
复制
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', '')

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

在这一点上,我开始抓取吸管,所以我编写了以下输出循环:

代码语言:javascript
复制
while True:
    try:
        print p.stdout.next().replace('\n', '')
    except StopIteration:
        break

但得到的结果是一样的。

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

EN

回答 19

Stack Overflow用户

回答已采纳

发布于 2009-04-29 17:26:54

我试过了,出于某种原因,当代码

代码语言:javascript
复制
for line in p.stdout:
  ...

积极地缓冲,变种

代码语言:javascript
复制
while True:
  line = p.stdout.readline()
  if not line: break
  ...

不会。显然这是一个已知的bug:http://bugs.python.org/issue3907 (这个问题现在已经在2018年8月29日“关闭”了)

票数 87
EN

Stack Overflow用户

发布于 2011-06-21 00:13:51

通过将缓冲区大小设置为1,您实际上强制该进程不缓冲输出。

代码语言:javascript
复制
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, bufsize=1)
for line in iter(p.stdout.readline, b''):
    print line,
p.stdout.close()
p.wait()
票数 39
EN

Stack Overflow用户

发布于 2018-02-21 16:17:06

您可以将子流程输出直接定向到流中。简化示例:

代码语言:javascript
复制
subprocess.run(['ls'], stderr=sys.stderr, stdout=sys.stdout)
票数 35
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/803265

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档