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

use*_*629 7 python 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,
Run Code Online (Sandbox Code Playgroud)

这样工作正常......除非执行的命令是python例如`args = ['python','foo.py'],在这种情况下输出不会被刷新,而是仅在命令完成时打印.

有解决方案吗?

jfo*_*cht 2

查看如何刷新 Python 打印的输出?

\n\n

您需要使用 -u 选项运行 python 子进程:

\n\n
\n

-u 强制 stdin、stdout 和 stderr 完全无缓冲。在重要的 sys\xe2\x80\x90\n 项目上,也将 stdin、stdout 和 stderr 置于二进制\n 模式。请注意,xreadlines()、readlines() 和文件对象迭代器(“for line in sys.stdin”)中有内部缓冲,不受此选项的影响。要解决此问题,您需要在“while 1:”循环中使用“sys.stdin.readline()”。

\n
\n\n

或者,如果您可以控制 python 子进程脚本,则可以使用 sys.stdout.flush() 在每次打印时刷新输出。

\n\n
import sys\nsys.stdout.flush()\n
Run Code Online (Sandbox Code Playgroud)\n