在运行时获取进程的输出

新手上路,请多包涵

我正在使用 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)

上面的代码工作正常,但它所做的是首先完成该过程并将输出存储在 结果 变量中。之后 for 循环 存储输出并打印它。

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

那么是否有任何其他函数可以动态地(在运行时)给我输出,这意味着一旦过程给出第一行,它就应该被打印出来。

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

阅读 894
2 个回答

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

 for line in result.stdout:
    print(line)

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

.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()

注意:如果子进程在非交互模式下运行时使用块缓冲; you might need pexpect , pty modules or stdbuf , unbuffer , script commands .

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

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

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

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