Jak uzyskać kod wyjścia, korzystając z metody komunikacji podprocesów Pythona?


186

Jak odzyskać kod wyjścia, korzystając z subprocessmodułu i communicate()metody Pythona ?

Odpowiedni kod:

import subprocess as sp
data = sp.Popen(openRTSP + opts.split(), stdout=sp.PIPE).communicate()[0]

Czy powinienem to robić w inny sposób?

Odpowiedzi:


266

Popen.communicateustawi returncodeatrybut po zakończeniu (*). Oto odpowiednia sekcja dokumentacji:

Popen.returncode 
  The child return code, set by poll() and wait() (and indirectly by communicate()). 
  A None value indicates that the process hasnt terminated yet.

  A negative value -N indicates that the child was terminated by signal N (Unix only).

Więc możesz to zrobić (nie przetestowałem tego, ale powinno działać):

import subprocess as sp
child = sp.Popen(openRTSP + opts.split(), stdout=sp.PIPE)
streamdata = child.communicate()[0]
rc = child.returncode

(*) Dzieje się tak ze względu na sposób, w jaki jest zaimplementowany: po skonfigurowaniu wątków do odczytu strumieni dziecka, po prostu wywołuje wait.


34
Ten przykład pomógł mi, ale byłoby miło, gdyby przykłady nie wykonywały wzorca „importuj podproces jako sp” importowania czegoś standardowego jako niejasnego skrótu. Chociaż powoduje to obcięcie 8 znaków od następującego po nim kodu, utrudnia również zrozumienie i ponowne użycie.
uglycoyote

16
@uglycoyote Nie ma reguły, która mówi, że musisz skopiować i wkleić. Po prostu przepisz to, jak chcesz, to jak 4 linie.
Jason C

5
@uglycoyote możesz również edytować go tak, aby był czymś podobnym, from subprocess import Popena następnie po prostu użyj Popenzamiast tego, subprocess(or sp).Popenco powiedziałbym, prawdopodobnie zwiększa czytelność i skraca wiersze
Mitch

2
Tak ... trzeba wywołać, process.communicate()a następnie przypisać returncodedo jakiejś zmiennej. Jeśli przypisanie zostało wykonane przed wywołaniem communicate, jest None.
WesternGun

1
Czy można wyświetlić kod powrotu bez przekierowywania potoku? Dzwonię do kodu bash i chciałbym zobaczyć dane wyjściowe w czasie rzeczywistym w terminalu
Nisba 10'18

10

Najpierw upewnij się, że proces został zakończony, a kod powrotu został odczytany przy użyciu tej .waitmetody. To zwróci kod. Jeśli chcesz uzyskać do niego dostęp później, jest on przechowywany jak .returncodew Popenobiekcie.


24
.communicate()już czeka na zakończenie podprocesu.
Ślimak mechaniczny

8

.poll() zaktualizuje kod powrotu.

Próbować

child = sp.Popen(openRTSP + opts.split(), stdout=sp.PIPE)
returnCode = child.poll()

Ponadto, po .poll()nazwie, kod powrotu jest dostępny w obiekcie jako child.returncode.


kiedy to zrobiłem .poll () był pusty. Musiałem uruchomić child.communicate () w linii powyżej child.poll (), aby to zadziałało.
NateW,

1
Myślę, że chciałeś użyć .wait () zamiast .poll (), zgodnie z dokumentacją: docs.python.org/3/library/subprocess.html . Zauważ, że .wait () przyjmuje opcjonalny parametr limitu czasu, który może być wygodny.
gg99


1

To zadziałało dla mnie. Drukuje również dane wyjściowe zwrócone przez proces potomny

child = subprocess.Popen(serial_script_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    retValRunJobsSerialScript = 0
    for line in child.stdout.readlines():
        child.wait()
        print line           
    retValRunJobsSerialScript= child.returncode
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.