Python: subprocess.popen() 使用
我有一个关于 subprocess.popen()
的问题:
假设执行的命令是在一个循环里运行的,有没有办法让 subprocess.popen()
检测到这一点,并在打印出第一次输出后就退出呢?
或者有没有其他方法可以做到这一点并打印结果呢?
你可以看到,下面这个程序在一个Linux机器上执行时会一直运行:
>>> import os
>>> import subprocess as sp
>>> p = sp.Popen("yes", stdout=sp.PIPE)
>>> result = p.communicate()[0]
1 个回答
4
这个 communicate 方法只有在被调用的程序很快就会结束,并且输出不多的情况下才有用。在你的例子中,“yes” 程序是不会结束的,所以 communicate 永远不会完成。为了处理那些会一直运行并可能产生大量输出的子进程,你需要加一个循环,反复调用 p.poll(),直到 p.poll() 返回一个不是 None 的值,这表示这个进程已经结束。在这个循环中,你还应该从 p.stdout 和 p.stderr 中读取输出,以消耗程序的任何输出。如果你不处理这些输出,缓冲区可能会满,导致程序阻塞,无法继续写入更多的输出。
import subprocess
import time
p = subprocess.Popen("yes", stdout=subprocess.PIPE)
result = ""
start_time = time.time()
while (p.poll() is None):
result += p.stdout.read(8192)
time.sleep(1)
if (time.time() - start_time) > 5:
print "Timeout"
break
print result
需要注意的是,上面的例子会一直运行,直到你手动终止正在读取输入的 “yes” 子进程。如果你想检测这个进程是否不会结束,可以在 while 循环中加一个时间检查,过了一段时间后就跳出循环。
如果你确定你的子进程会自己结束,那么你可以直接调用 communicate() 来获取输出,但在你的例子中,这种方法不适用,原因我在上面已经解释过了。