在运行时获取进程的输出

时间:2013-05-15 06:01:55

标签: python python-3.x subprocess

我使用python脚本使用subprocess.Popen运行进程,同时将输出存储在文本文件中,并在控制台上打印。这是我的代码:

result = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
for line in result.stdout.readlines(): #read and store result in log file
    openfile.write("%s\n" %line)
    print("%s" %line)

上面的代码工作正常,但它的作用是首先完成整个过程并将输出存储在 result 变量中。之后 for循环存储输出并打印出来。

但是我想在运行时输出(因为我的过程可能需要数小时才能完成,所以这些时间都没有得到任何输出。)

还有其他任何动态(在运行时)给我输出的函数,意味着只要进程给出第一行,就应该打印出来。

3 个答案:

答案 0 :(得分:5)

这里的问题是.readlines()在返回之前获取整个输出,因为它构造了一个完整的列表。直接迭代:

for line in result.stdout:
    print line

答案 1 :(得分:3)

.readlines()返回所有列表,进程将在打开时返回,即直到所有从子进程输出后才会返回任何内容收到了。要在“实时”中逐行阅读:

import sys
from subprocess import Popen, PIPE

proc = Popen(cmd, shell=True, bufsize=1, stdout=PIPE)
for line in proc.stdout:
    openfile.write(line)
    sys.stdout.buffer.write(line)
    sys.stdout.buffer.flush()
proc.stdout.close()
proc.wait()

注意:如果子进程在非交互模式下运行时使用块缓冲;您可能需要pexpect, pty modulesstdbuf, unbuffer, script commands

注意:在Python 2上,您可能还需要使用iter()来获得“实时”输出:

for line in iter(proc.stdout.readline, ""):
    openfile.write(line)
    print line,

答案 2 :(得分:1)

您可以使用管道上的readline逐个遍历这些行:

while True: 
    line = result.stdout.readline()
    print line.strip()
    if not line:
        break

这些行包含一个尾部\n,我将其剥离以进行打印。 当进程终止时,readline返回一个空字符串,因此您知道何时停止。