在进程运行时不断打印子进程输出

新手上路,请多包涵

要从我的 Python 脚本启动程序,我使用以下方法:

 def execute(command):
    process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    output = process.communicate()[0]
    exitCode = process.returncode

    if (exitCode == 0):
        return output
    else:
        raise ProcessException(command, exitCode, output)

因此,当我启动像 Process.execute("mvn clean install") 这样的进程时,我的程序会一直等到进程完成,然后才能获得程序的完整输出。如果我正在运行一个需要一段时间才能完成的进程,这很烦人。

我可以让我的程序通过在循环完成之前轮询进程输出来逐行编写进程输出吗?

我发现 这篇 文章可能是相关的。

原文由 Wolkenarchitekt 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.5k
2 个回答

一旦命令输出它们,您就可以使用 iter 来处理它们: lines = iter(fd.readline, "") 。这是一个显示典型用例的完整示例(感谢@jfs 的帮助):

 from __future__ import print_function # Only Python 2.x
import subprocess

def execute(cmd):
    popen = subprocess.Popen(cmd, stdout=subprocess.PIPE, universal_newlines=True)
    for stdout_line in iter(popen.stdout.readline, ""):
        yield stdout_line
    popen.stdout.close()
    return_code = popen.wait()
    if return_code:
        raise subprocess.CalledProcessError(return_code, cmd)

# Example
for path in execute(["locate", "a"]):
    print(path, end="")

原文由 tokland 发布,翻译遵循 CC BY-SA 4.0 许可协议

要在 Python 3 中刷新其标准输出缓冲区后立即逐行打印子进程的输出:

 from subprocess import Popen, PIPE, CalledProcessError

with Popen(cmd, stdout=PIPE, bufsize=1, universal_newlines=True) as p:
    for line in p.stdout:
        print(line, end='') # process line here

if p.returncode != 0:
    raise CalledProcessError(p.returncode, p.args)

注意:您不需要 p.poll() 达到 eof 时循环结束。而且您不需要 iter(p.stdout.readline, '') 读错误已在 Python 3 中修复。

另请参阅 Python:从 subprocess.communicate() 读取流式输入

原文由 jfs 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题