我的python脚本使用子进程来调用非常嘈杂的linux实用程序。我想将所有输出存储到日志文件中,并向用户显示其中的一些内容。我以为下面的方法可以工作,但是直到实用程序产生大量输出后,输出才出现在我的应用程序中。
#fake_utility.py, just generates lots of output over time import time i = 0 while True: print hex(i)*512 i += 1 time.sleep(0.5) #filters output import subprocess proc = subprocess.Popen(['python','fake_utility.py'],stdout=subprocess.PIPE) for line in proc.stdout: #the real code does filtering here print "test:", line.rstrip()
我真正想要的行为是过滤器脚本打印从子流程接收到的每一行。Sorta像是做什么tee,但带有python代码。
Sorta
tee
自从我上一次使用Python以来已经很长时间了,但是我认为问题出在语句for line in proc.stdout,该语句在遍历整个输入之前先读取整个输入。解决方案是改为使用readline():
for line in proc.stdout
readline()
#filters output import subprocess proc = subprocess.Popen(['python','fake_utility.py'],stdout=subprocess.PIPE) while True: line = proc.stdout.readline() if not line: break #the real code does filtering here print "test:", line.rstrip()
当然,您仍然必须处理子进程的缓冲。
注意:根据文档,使用迭代器的解决方案应该与使用等效readline(),除了预读缓冲区外,但是(或正因为如此)建议的更改确实为我带来了不同的结果(Windows XP上为Python 2.5)。