Python- 从subprocess.communicate()读取流输入
我正在使用Python subprocess.communicate()
从运行约一分钟的进程中读取stdout。
我该如何stdout以流方式打印出该流程的每一行,以便可以看到生成的输出,但仍然阻止该流程终止,然后再继续?
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
中捕获其余部分: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中的预读错误。如果子进程的stdout在非交互模式下使用块缓冲而不是行缓冲(这会导致输出延迟,直到子缓冲区已满或被子进程显式刷新),然后你可以尝试使用以下方式强制使用无缓冲输出
pexpect,pty
模块或unbuffer,stdbuf,script
公用事业,见问:为什么不直接使用管道(popen方法())?这是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的输出进行解码)。