在Python中实时拦截另一个进程的stdout
我想在一个系统进程中运行,实时捕捉输出,并逐行修改它,这个过程是在一个Python脚本中进行的。
我目前的尝试是,等这个进程完成后再打印输出,代码如下:
#!/usr/bin/env python
import subprocess
cmd = "waitsome.py"
proc = subprocess.Popen(cmd, shell=True, bufsize=256, stdout=subprocess.PIPE)
for line in proc.stdout:
print ">>> " + line.rstrip()
这个脚本 waitsome.py
每半秒打印一行:
#!/usr/bin/env python
import time
from sys import stdout
print "Starting"
for i in range(0,20):
time.sleep(0.5)
print "Hello, iteration", i
stdout.flush()
有没有简单的方法可以让 subprocess
实时读取输出?我需要使用线程吗?
以前我用Perl写脚本,这个操作简单得多:
open(CMD, "waitsome.py |");
while (<CMD>) {
print ">>> $_";
}
close(CMD);
2 个回答
0
这一切可以用一个迭代器来封装,像这样:
def subprocess_readlines(out):
while True:
line = out.readline()
if not line:
return
yield line
然后可以这样调用:
for line in subprocess_readlines(proc.stdout):
print ">>>", line.rstrip()
16
在处理文件时,循环读取文件内容会不可避免地将数据分成比较大的块来缓存,这在所有的Python 2.*版本中都是一个已知的问题。在Python 3.1中,这个问题得到了改善,最后的循环写法稍有不同:
for line in proc.stdout:
print(">>> " + str(line.rstrip()))
如果升级到Python 3.1不太现实(我知道这通常是这样的!),那就采用传统的写法来实现循环——下面这个版本的循环在Python 2.*中可以正常工作:
while True:
line = proc.stdout.readline()
if not line:
break
print ">>> " + line.rstrip()