2011-11-10 19 views
14

Mam problem z wykorzystaniem podprocesu.Popen lub subprocess.call, gdy używam ich do wykonywania wierszy polecenia, które generują dużo danych wyjściowych, skrypty Pythona zawiesza się, ale co to jest dziwne, że po odczekaniu przez chwilę, gdy skrypt jest w stanie zawieszenia, stwierdzam, że zadanie zlecone przez linię cmd zostało wykonane i tylko skrypt jest zawieszony.Python: subprocess.Popen i subprocess.call zawiesza się

subprocess.call(cmd, shell = True) 
#OR 
subprocess.Popen(cmd, stdout = subprocess.PIPE, stdin = subprocess.PIPE, shell = True) 
# HANGS HERE 
print "show something after subprocess" 

Należy zauważyć, że ostatni wydruk nigdy nie jest wykonywany, ale faktycznie wykonano polecenie cmd.

Zauważ także, że cmd jest związane z portem szeregowym, więc gdy podłączę kabel szeregowy, wszystko stanie się w porządku, a ostatnie oznaczenie wydruku zostanie wykonane. Ale kiedy używam terminala wszystko jest w porządku, nawet jeśli serial jest podłączony, pojawia się tylko w przypadku skryptu Pythona.

Thanks a lot

Odpowiedz

12

Zgodnie z dokumentacją Python, subprocess.call uruchamia polecenie i czeka na jej zakończenie, więc jest to odpowiednik subprocess.Popen następnie Popen.wait.

Jednak dokumentacja metody Popen.wait wyraźnie ostrzega o problemie przepełnienia bufora i zaleca zamiast tego użycie Popen.communicate. Stąd rozwiązanie szukasz powinno być coś takiego:

import subprocess 
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, shell=True) 
stdout, stderr = process.communicate() 
print "show something after subprocess" 
+1

Nie ma problemu, używając 'subprocess.call', jeśli nie używasz' subprocess.PIPE', którego OP nie jest. – interjay

+1

Nie wyjaśnia, dlaczego dane wyjściowe instrukcji 'print' nie są wyświetlane w obiekcie nadrzędnym. 'Popen()' nie czeka na dziecko, nawet jeśli proces potomny jest zablokowany, próbując zapisać do potoku z pełnym buforem. – jfs

2

ja nie rozumiem, dlaczego Twoja pierwsza linia nie działa - jak nie ma stdin/stdout/stderr przekierowania, nie ma potrzeby do blokowania.

Drugi ma blokować jeśli proces

  1. oczekuje danych za pośrednictwem stdin lub
  2. wysyła więcej danych na standardowe wyjście niż rura może posiadać wothout odczytania.

Ale ponieważ twój podproces kończy się poprawnie, nie widzę również powodu do blokowania. Jesteś pewien, że to naprawdę się kończy?

Powiązane problemy