[英]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.