我遇到了一些困難,從子流程標準輸出管道獲取輸出。我正在通過它啓動一些第三方代碼,以提取日誌輸出。直到最近更新的第三方代碼,一切正常。更新之後,python已經無限期地開始阻塞,並且沒有實際顯示任何輸出。我可以手動啓動第三方應用程序並查看輸出。窗口上的Python子流程輸出?
我正在使用的代碼的基本版本:
import subprocess, time
from threading import Thread
def enqueue_output(out):
print "Hello from enqueue_output"
for line in iter(out.readline,''):
line = line.rstrip("\r\n")
print "Got %s" % line
out.close()
proc = subprocess.Popen("third_party.exe", stdout=subprocess.PIPE, bufsize=1)
thread = Thread(target=enqueue_output, args=(proc.stdout,))
thread.daemon = True
thread.start()
time.sleep(30)
這工作完全,如果我代替third_party.exe這個腳本:
import time, sys
while True:
print "Test"
sys.stdout.flush()
time.sleep(1)
所以我不清楚魔需要完成這項工作才能使用原始命令。
這些都是我沒有成功嘗試subprocess.Popen線的所有變體:
proc = subprocess.Popen("third_party.exe", stdout=subprocess.PIPE, bufsize=0)
proc = subprocess.Popen("third_party.exe", stdout=subprocess.PIPE, shell=True)
proc = subprocess.Popen("third_party.exe", stdout=subprocess.PIPE, creationflags=subprocess.CREATE_NEW_CONSOLE)
si = subprocess.STARTUPINFO()
si.dwFlags = subprocess.STARTF_USESTDHANDLES | subprocess.STARTF_USESHOWWINDOW
proc = subprocess.Popen("third_party.exe", stdout=subprocess.PIPE, startupinfo=si)
編輯1: 我實際上並不能在這種情況下使用.communicate()。我啓動的應用程序仍在運行很長一段時間(幾天到幾周)。我實際上可以測試.communicate()的唯一方法就是在啓動後不久就殺死該應用程序,我不覺得會給我有效的結果。
即使這個非線程版本失敗:
import subprocess, time
from threading import Thread
proc = subprocess.Popen("third_party.exe", stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print "App started, reading output..."
for line in iter(proc.stdout.readline,''):
line = line.rstrip("\r\n")
print "Got: %s" % line
編輯2: 由於JDI,以下的作品沒關係:
import tempfile, time, subprocess
w = "test.txt"
f = open("test.txt","a")
p = subprocess.Popen("third_party.exe", shell=True, stdout=f,
stderr=subprocess.STDOUT, bufsize=0)
time.sleep(30)
with open("test.txt", 'r') as r:
for line in r:
print line
f.close()
是否有可能您的第三方程序切換到寫入stderr? – jdi
似乎並非如此。如果我攔截stderr,則會發生同樣的情況(儘管如此,我確實在控制檯上看到了應用程序的輸出,但它只是打印,不會通過Python)。 – devicenull
聽起來好像應用程序已停止使用標準輸出並直接寫入控制檯。如果是這樣,你可以做的不多。你能檢查應用程序的供應商嗎? –