サブプロセスの stdout パイプから出力を取得する際に問題が発生しています。ログ出力を抽出するために、それを介してサードパーティのコードを起動しています。サードパーティのコードが最近更新されるまでは、すべて正常に機能していました。更新後、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()