我正在使用Python subprocess.communicate()从运行约一分钟的进程中读取stdout。
Python subprocess.communicate()
我该如何stdout以流方式打印出该流程的每一行,以便可以看到生成的输出,但仍然阻止该流程终止,然后再继续?
subprocess.communicate() 似乎一次给出所有输出。
subprocess.communicate()
这是一个简单的示例(不检查错误):
import subprocess proc = subprocess.Popen('ls', shell=True, stdout=subprocess.PIPE, ) while proc.poll() is None: output = proc.stdout.readline() print output,
如果ls结束太快,则while循环可能会在你读取所有数据之前结束。
你可以通过以下方式在stdout中捕获其余部分:
stdout
output = proc.communicate()[0] print output,
要在子进程刷新其stdout缓冲区后逐行获取子进程的输出:
#!/usr/bin/env python2 from subprocess import Popen, PIPE p = Popen(["cmd", "arg1"], stdout=PIPE, bufsize=1) with p.stdout: for line in iter(p.stdout.readline, b''): print line, p.wait() # wait for the subprocess to exit
iter()用于在编写行后立即读取行,以解决Python 2中的预读错误。
iter()
如果子进程的stdout在非交互模式下使用块缓冲而不是行缓冲(这会导致输出延迟,直到子缓冲区已满或被子进程显式刷新),然后你可以尝试使用以下方式强制使用无缓冲输出 pexpect,pty模块或unbuffer,stdbuf,script公用事业,见问:为什么不直接使用管道(popen方法())?
pexpect,pty
unbuffer,stdbuf,script
这是Python 3代码:
#!/usr/bin/env python3 from subprocess import Popen, PIPE with Popen(["cmd", "arg1"], stdout=PIPE, bufsize=1, universal_newlines=True) as p: for line in p.stdout: print(line, end='')
注意:与Python 2不同,Python 2照原样输出子进程的字节串。Python 3使用文本模式(使用locale.getpreferredencoding(False)编码对cmd的输出进行解码)。
locale.getpreferredencoding(False)