Come ottenere il codice di uscita quando si utilizza il metodo di comunicazione del sottoprocesso di Python?


186

Come posso recuperare il codice di uscita quando utilizzo il subprocessmodulo e il communicate()metodo di Python ?

Codice pertinente:

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

Dovrei farlo in un altro modo?

Risposte:


266

Popen.communicateimposterà l' returncodeattributo al termine (*). Ecco la sezione relativa alla documentazione:

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).

Quindi puoi semplicemente farlo (non l'ho provato ma dovrebbe funzionare):

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

(*) Questo accade a causa del modo in cui è implementato: dopo aver impostato i thread per leggere i flussi del bambino, chiama semplicemente wait.


34
Questo esempio mi ha aiutato, ma sarebbe bello se gli esempi non facessero il modello "import subprocess as sp" di importare qualcosa di standard come un'abbreviazione oscura. Mentre questo elimina 8 caratteri dal codice che lo segue, rende anche difficile la comprensione e il riutilizzo.
uglycoyote,

16
@uglycoyote Non esiste una regola che dice che devi copiare e incollare. Basta riscriverlo come vuoi, è come 4 linee simili.
Jason C

5
@uglycoyote potresti anche modificarlo per essere qualcosa di simile from subprocess import Popene poi semplicemente usare Popeninvece del subprocess(or sp).Popenquale direi che probabilmente aumenta la leggibilità e accorcia le righe
Mitch

2
Sì ... deve chiamare process.communicate()e quindi assegnare returncodea qualche variabile. Se l'assegnazione viene eseguita prima di chiamare communicate, lo è None.
WesternGun

1
È possibile mostrare il codice di ritorno senza reindirizzare la pipe? Sto chiamando un codice bash e vorrei vedere l'output in tempo reale nel terminale
Nisba

10

È innanzitutto necessario assicurarsi che il processo sia stato completato e che il codice di ritorno sia stato letto utilizzando il .waitmetodo Questo restituirà il codice. Se si desidera accedere in un secondo momento, è memorizzato come .returncodein Popenoggetto.


24
.communicate()attende già che il sottoprocesso venga chiuso.
Lumaca meccanica

8

.poll() aggiornerà il codice di ritorno.

Provare

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

Inoltre, dopo .poll()viene chiamato il codice di ritorno è disponibile nell'oggetto come child.returncode.


quando ho fatto questo .poll () era vuoto. Ho dovuto eseguire child.communicate () nella riga sopra child.poll () per farlo funzionare.
NateW,

1
Penso che intendevi usare .wait () invece di .poll (), come da documentazione: docs.python.org/3/library/subprocess.html . Si noti che .wait () accetta un parametro di timeout opzionale che può essere utile.
gg99,


1

Questo ha funzionato per me. Stampa anche l'output restituito dal processo figlio

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.