要从我的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)

所以当我启动一个进程,比如进程。执行("mvn clean install")时,我的程序会一直等待,直到进程完成,只有到那时我才能得到程序的完整输出。这是恼人的,如果我正在运行一个进程,需要一段时间才能完成。

我能让我的程序一行一行地写进程输出吗,在循环结束之前轮询进程输出什么的?

我找到了这篇文章,可能与此有关。


当前回答

如果您想在进程运行时从stdout打印,请使用-u Python选项和subprocess.Popen()。(shell=True是必要的,尽管有风险…)

其他回答

对于试图回答这个问题并从Python脚本中获取标准输出的人来说,请注意Python会缓冲它的标准输出,因此可能需要一段时间才能看到标准输出。

这可以通过在目标脚本中的每个标准输出写入后添加以下内容来纠正:

sys.stdout.flush()

可以在命令输出后立即使用iter对行进行处理。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="")

简单比复杂好。

操作系统库内置模块系统。您应该执行代码并看到输出。

import os
os.system("python --version")
# Output
"""
Python 3.8.6
0
"""

在版本之后,它也打印返回值为0。

在Python 3中,只要子进程的stdout缓冲区被刷新,就逐行打印子进程的输出:

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.s dout。readline, ")——在Python 3中修复了预读错误。

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

在Python中>= 3.5使用subprocess.run为我工作:

import subprocess

cmd = 'echo foo; sleep 1; echo foo; sleep 2; echo foo'
subprocess.run(cmd, shell=True)

(在没有shell=True的情况下,在执行过程中获得输出也可以工作) https://docs.python.org/3/library/subprocess.html#subprocess.run