用Python读取另一个程序的控制台输出

时间:2015-10-14 17:27:07

标签: python python-2.7 subprocess stdout

有两个程序 - parent.py和myscript.py,如下所示。 parent.py在控制台中保持打印消息。并且myscript.py需要访问parent.py打印的内容。

parent.py:

import time

while 1:
     time.sleep(1)
     print "test"

myscript.py:

import subprocess
p = None

p = subprocess.Popen(['python', 'parent.py'],
                 stdout=subprocess.PIPE,
                 stderr=subprocess.STDOUT,
                 )
for line in p.stdout:
       print line

我希望myscript.py动态捕获parent.py的输出。可以看出,parent.py有一个无限循环 - 脚本永远不会停止,但每当它输出单词' test'时,myscript.py也应输出相同的内容。但myscript.py并没有给出任何输出。

我尝试用

替换parent.py中的代码
print "Hello"

由于程序执行完毕,myscript.py还打印了#34; Hello"。所以我想除非parent.py的执行完成,否则myscript.py不会读它。那是什么发生的?

我还尝试用这个片段替换myscript.py中的循环:

for line in iter(p.stdout.readline, ''):
    print line

仍然没有输出。

我的问题是:即使parent.py永远不会完成执行,我如何让myscript.py动态读取parent.py正在打印的所有内容。

(我发现了类似的问题,但他们要么没有工作,要么根本没有答案。)

1 个答案:

答案 0 :(得分:6)

这是block buffering issue:当stdout被重定向到管道parent.py时,它的输出会在内部缓冲区(~4K-8K)中累积,即你不会看到周围的任何东西小时,直到缓冲区溢出。

要禁用缓冲,请传递-u命令行选项:

#!/usr/bin/env python
import os
import sys
from subprocess import Popen, PIPE, STDOUT

script_path = os.path.join(get_script_dir(), 'parent.py')
p = Popen([sys.executable, '-u', script_path],
          stdout=PIPE, stderr=STDOUT, bufsize=1)
with p.stdout:
    for line in iter(p.stdout.readline, b''):
        print line,
p.wait()

请参阅:

注意:如果您不需要对输出执行任何操作,只需删除stdout=PIPE,即可在控制台中查看输出:

subprocess.check_call([sys.executable, script_path])