我已阅读并尝试了8种不同方法,就此问题提出了几个问题。我在python中打开了一个进程,想要读取它的输出,即使进程还没有终止。该过程通常至少持续1分钟或直到发送中断为止。无论我尝试什么,我都无法阅读输出。我知道我通过工作的命令和参数,因为当我将它更改为subprocess.call(cmd,args)时,它会将所有内容打印到屏幕上。我还检查过程是用ps -ax运行的。这是我正在尝试的一个例子(cat / dev / random与我的项目无关):
proc = subprocess.Popen(["cat", "/dev/random"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print("Process started.")
到目前为止,我尝试过的是这个:
for line in iter(p.stdout.readline, ''):
strLine = str(line).rstrip()
print(">>> " + strLine )
sys.stdout.flush()
和
output, error = proc.communicate()
print output
和
while proc.poll() is None:
print("Still waiting.")
print(proc.stdout.readline(1))
我尝试了更多的解决方案,但是没有运气。当使用call函数而不更改stdout时,一切都正确打印到控制台。我做错了什么?
我正在使用Python 2.6。
答案 0 :(得分:2)
我将您的代码复制到一个完整的函数和文件中,添加了一个更改(repr
)以避免打印更改终端标题等的内容,并给出:
import subprocess
import sys
def tst():
proc = subprocess.Popen(["cat", "/dev/random"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print("Process started.")
for line in iter(p.stdout.readline, ''):
strLine = str(line).rstrip()
print(">>> " + repr(strLine))
sys.stdout.flush
tst()
(哎呀,看起来像我的剪切和粘贴掉了sys.stdout.flush上的括号!虽然在这种情况下无害)
立即运行会产生明显的错误:
Process started.
Traceback (most recent call last):
File "foo.py", line 13, in <module>
tst()
File "foo.py", line 8, in tst
for line in iter(p.stdout.readline, ''):
NameError: global name 'p' is not defined
修复(将p
替换为proc
),该示例有效,对于“works”的某些定义:/ dev / random不会停止生成输出,因此它会永远运行。
中间的例子将是一个问题,因为proc.communicate()
将读取进程的整个输出,这是无限的,因此将使你失去内存(最终)。 : - )
第三个例子工作正常。
如果用其他东西替换cat /dev/random
,你可能会发现Unix / Linux管道的一个更有趣且可能令人烦恼的方面:当且仅当它进入“交互式”时,进程的stdout流通常是行缓冲的设备“(如终端窗口)。管道不是“交互式设备”,因此stdout是块缓冲的,除非有问题的命令覆盖了它本身。这可能是我无法在这里重现的问题的根源。
您可以使用伪ttys而不是(或除了)Python的subprocess
模块来解决此问题。