【问题标题】:Getting output of a process at runtime在运行时获取进程的输出
【发布时间】:2013-05-09 14:28:59
【问题描述】:

我正在使用 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 循环 存储输出并打印它。

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

那么有没有其他函数可以动态地(在运行时)给我输出,这意味着只要进程给出第一行,它就应该被打印出来。

【问题讨论】:

  • 我从未真正尝试过,但我认为您应该将自己的 Python file 对象发送到 stdout(或 stdin,或 stderr)参数。然后你必须轮询那个文件。 Subprocess 的发明是为了让你免于痛苦,但看起来你别无选择。祝你好运。
  • “它首先完成该过程并将输出存储在结果中” - 这不是真的。
  • “它首先完成该过程并将输出存储在结果中” - 这不是真的。好吧,当我运行 Popen 命令时,它会一直运行直到进程完成,然后它会执行进一步的编码。如果它以其他方式起作用,我很想知道。
  • @AdrianRatnapala 听起来太复杂了,“别无选择”的说法是错误的。
  • 您可以考虑使用 fcntl 将result.stdout 设置为非阻塞,这样可以实时读取,如果还没有数据,则会引发IOError

标签: python python-3.x subprocess


【解决方案1】:

您可以在管道上使用readline 逐行迭代:

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

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

【讨论】:

  • 很抱歉,您没有收到我的问题。您建议我已经使用 for 循环完成它,我想要的是在进程仍处于运行状态时逐行输出。
  • 你试过了吗?您正在使用readlines,它返回所有行。这只有在终止后才有可能。使用readline,您只会获得下一个
  • result.stdout 对我来说工作得很好,但是你的 line.strip() 函数很有帮助,因为我之前得到了太多的“b'\r\n'”,谢谢
【解决方案2】:

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

for line in result.stdout:
    print line

【讨论】:

【解决方案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,

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-25
    • 1970-01-01
    • 2023-01-10
    • 1970-01-01
    • 1970-01-01
    • 2018-12-06
    • 2015-10-07
    • 1970-01-01
    相关资源
    最近更新 更多