子进程输出到 PIPE 并直接输出到 stdout

问题描述 投票:0回答:2

我发现了一些看起来像我的问题,但没有产生我可以使用的解决方案(最接近的是:子进程输出到stdout和PIPE

问题:我想使用子进程启动一个进程,这需要很长时间。运行命令后,我需要解析标准输出输出和标准错误输出。

目前我这样做:

p = subprocess.Popen( command_list, stdout=subprocess.PIPE, 
    stderr=subprocess.PIPE )
out, error_msg = p.communicate()
print out + "\n\n" + error_msg

#next comes code in which I check out and error_msg

但是这种方法的缺点是用户在进程运行时看不到进程的输出。仅在最后打印输出。

有没有一种方法可以在命令运行时打印输出(就好像我在没有 stdout/stderr=subprocess.PIPE 的情况下给出命令一样)并且最终仍然通过 p.communicate 获得输出?

注意:我目前正在 python 2.5 上进行开发(使用此 python 版本的旧软件版本)。

python subprocess
2个回答
8
投票

这个片段曾经在类似的情况下帮助过我:

process = subprocess.Popen(cmd, bufsize=1, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in iter(process.stdout.readline, ''):
    print line,
    sys.stdout.flush() # please see comments regarding the necessity of this line 
process.wait()
errcode = process.returncode

0
投票

这是一个 python 函数,用于监视命令 stdout + stderr,如果成功完成则返回输出,否则引发异常:

import subprocess
def execute_command(cmd):
    """
    Execute and watch shell command, and return its output
    """
    output = ''
    with subprocess.Popen(
            cmd,
            shell=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            universal_newlines=True,
            encoding='utf-8',
            errors='replace'
        ) as p:
            while True:
                line = p.stdout.readline()
                if line != '':
                    output += (line + "\n")
                    print(line)
                elif p.poll() != None:
                    break
            sys.stdout.flush()
            if (p.returncode == 0):
                return output
            else:
                raise Exception(cmd, p.returncode, output)
© www.soinside.com 2019 - 2024. All rights reserved.