[英]Unable to read stdout and stderr for a long running process in paramiko with channels and exec_command
[英]Unable to read stdout from a running process
我已经阅读并尝试了8种不同的方法来回答有关此问题的几个问题。 我在python中打开了一个进程,并希望读取其输出,即使该进程尚未终止。 该过程通常至少要等一分钟或发送中断后才能完成。 不管我尝试什么,都无法读取输出。 我知道我传递的命令和参数,因为当我将其更改为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))
我尝试了更多解决方案,这些都是这些的变体,但是没有运气。 在不更改stdout的情况下使用call函数时,所有内容都会正确打印到控制台。 我究竟做错了什么?
我正在使用Python 2.6。
我将您的代码复制到一个完整的函数和文件中,添加了一个更改( 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
为解决此问题(用proc
替换p
),该示例适用于“ works”的某些定义:/ dev / random不会停止产生输出,因此它将永远运行。
中间的示例将是一个问题,因为proc.communicate()
将读取进程的整个输出,该输出是无限的,因此最终将耗尽内存。 :-)
第三个示例工作正常。
如果将cat /dev/random
替换为其他内容,则可能会发现Unix / Linux管道的一个更有趣甚至令人讨厌的方面:进程的stdout流通常在且仅当它进入“交互设备”时才被行缓冲(例如终端窗口)。 管道不是“交互设备”,因此stdout是块缓冲的,除非相关命令本身覆盖了该命令。 这可能是我在这里无法重现的问题的根源。
您可以通过使用伪ttys代替(或除此之外)Python的subprocess
模块来解决此问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.