简体   繁体   English

python,迭代subprocess.Popen()stdout / stderr

[英]python, iterate on subprocess.Popen() stdout/stderr

There are a lot of similar posts, but I didn't find answer. 有很多类似的帖子,但我没有找到答案。

On Gnu/Linux, with Python and subprocess module, I use the following code to iterate over the stdout/sdterr of a command launched with subprocess: 在Gnu / Linux上,使用Pythonsubprocess进程模块,我使用以下代码迭代使用子进程启动的命令的stdout / sdterr:

class Shell:
    """ 
    run a command and iterate over the stdout/stderr lines
    """

    def __init__(self):

        pass

    def __call__(self,args,cwd='./'):

        p = subprocess.Popen(args,
                cwd=cwd, 
                stdout = subprocess.PIPE,
                stderr = subprocess.STDOUT,
                )

        while True:

            line = p.stdout.readline()
            self.code = p.poll()

            if line == '':
                if self.code != None:
                    break
                else:
                    continue

            yield line

#example of use
args = ["./foo"]
shell = Shell()
for line in shell(args):
     #do something with line
     print line,

This works fine... except if the command executed is python , for example `args = ['python','foo.py'], in which case the output is not flushed but printed only when the command is finished. 这样工作正常......除非执行的命令是python ,例如`args = ['python','foo.py'],在这种情况下输出不会刷新,而是仅在命令完成时打印。

Is there a solution? 有解决方案吗?

Check out How to flush output of Python print? 查看如何刷新Python打印输出? .

You need to run the python subprocess with the -u option: 您需要使用-u选项运行python子进程:

-u Force stdin, stdout and stderr to be totally unbuffered. -u强制stdin,stdout和stderr完全无缓冲。 On sys‐ tems where it matters, also put stdin, stdout and stderr in binary mode. 在重要的系统上,还将stdin,stdout和stderr置于二进制模式。 Note that there is internal buffering in xreadlines(), readlines() and file-object iterators ("for line in sys.stdin") which is not influenced by this option. 请注意,xreadlines(),readlines()和file-object迭代器(“for sys.stdin中的行”)中存在内部缓冲,不受此选项的影响。 To work around this, you will want to use "sys.stdin.readline()" inside a "while 1:" loop. 要解决此问题,您需要在“while 1:”循环中使用“sys.stdin.readline()”。

Or, if you have control over the python sub-process script you can use sys.stdout.flush() to flush the output every time you print. 或者,如果您可以控制python子流程脚本,则可以使用sys.stdout.flush()在每次打印时刷新输出。

import sys
sys.stdout.flush()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM