Występują pewne trudności z uzyskaniem wyniku z potoku podprocesowego podprocesowego. Uruchamiam za jego pośrednictwem jakiś kod strony trzeciej, aby wyodrębnić dane wyjściowe dziennika. Aż do ostatniej aktualizacji kodu strony trzeciej wszystko działało dobrze. Po aktualizacji python zaczął blokować w nieskończoność i nie wyświetlał żadnych danych wyjściowych. Mogę ręcznie uruchomić aplikację firmową w porządku i zobaczyć dane wyjściowe.Wyjście podprocesu Python w systemie Windows?
Podstawowa wersja kodu używam:
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)
Działa to doskonale, jeśli zastąpić third_party.exe dla tego skryptu:
import time, sys
while True:
print "Test"
sys.stdout.flush()
time.sleep(1)
więc jestem jasne, magii należy zrobić, aby działało to z oryginalnym poleceniem.
Są to wszystkie warianty linii subprocess.Popen próbowałem bez powodzenia:
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)
Edit 1: nie mogę faktycznie korzysta .communicate() w tym przypadku. Uruchomiona przeze mnie aplikacja działa przez długie okresy czasu (dni lub tygodnie). Jedynym sposobem, w jaki mogłem przetestować .communicate() byłoby zabicie aplikacji wkrótce po jej uruchomieniu, co nie wydaje mi się, że dałoby to prawidłowe wyniki.
Nawet niegwintowane wersja to się nie powiedzie:
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
Edycja 2: Dzięki JDI następujące prace okay:
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()
Czy jest możliwe, że Twój program zewnętrzny został przełączony na zapisywanie na stderr? – jdi
Nie wydaje się, że tak jest. Jeśli zamiast tego przechwycę stderr, stanie się to samo (chociaż widzę wyjście aplikacji na konsoli, ale to tylko drukowanie, nie przechodzi Python). – devicenull
Wygląda na to, że aplikacja przestała używać standardowego wyjścia i pisze bezpośrednio na konsoli. Jeśli tak, niewiele można z tym zrobić. Czy możesz sprawdzić u sprzedawcy aplikacji? –