¿Cómo obtener el código de salida cuando se usa el método de comunicación del subproceso Python?

186

¿Cómo recupero el código de salida cuando uso el subprocessmódulo y el communicate()método de Python ?

Código relevante:

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

¿Debería estar haciendo esto de otra manera?

CarpeNoctem
fuente

Respuestas:

266

Popen.communicateestablecerá el returncodeatributo cuando esté hecho (*). Aquí está la sección de documentación relevante:

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

Entonces puedes hacerlo (no lo probé pero debería funcionar):

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

(*) Esto sucede debido a la forma en que se implementa: después de configurar subprocesos para leer las transmisiones del niño, simplemente llama wait.

Eli Bendersky
fuente
34
Este ejemplo me ayudó, pero sería bueno si los ejemplos no hicieran el patrón "importar subproceso como sp" de importar algo estándar como una abreviatura oscura. Si bien esto recorta 8 caracteres del código que lo sigue, también hace que sea difícil de entender y reutilizar.
uglycoyote
16
@uglycoyote No hay una regla que diga que tienes que copiar y pegar. Simplemente vuelva a escribirlo como desee, es como 4 líneas similares.
Jason C
55
@uglycoyote también podría editarlo para que sea algo así from subprocess import Popeny luego usarlo en Popenlugar de subprocess(or sp).Popenlo que diría que probablemente aumenta la legibilidad y acorta las líneas
Mitch
2
Sí ... debe llamar process.communicate()y luego asignar returncodea alguna variable. Si la asignación se realiza antes de llamar communicate, es None.
WesternGun
1
¿Es posible mostrar el código de retorno sin redirigir la tubería? Estoy llamando a un código bash y me gustaría ver la salida en tiempo real en la terminal
Nisba
10

Primero debe asegurarse de que el proceso se haya completado y que el código de retorno se haya leído utilizando el .waitmétodo. Esto devolverá el código. Si desea acceder a él más tarde, se almacena como .returncodeen el Popenobjeto.

Noufal Ibrahim
fuente
24
.communicate()ya espera a que finalice el subproceso.
Caracol mecánico el
8

.poll() actualizará el código de retorno.

Tratar

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

Además, después de que .poll()se llama, el código de retorno está disponible en el objeto como child.returncode.

Matthew Vernon
fuente
cuando hice esto .poll () estaba vacío. Tuve que ejecutar child.communicate () en la línea sobre child.poll () para que esto funcione.
NateW
1
Creo que querías usar .wait () en lugar de .poll (), según la documentación: docs.python.org/3/library/subprocess.html . Tenga en cuenta que .wait () toma un parámetro de tiempo de espera opcional que puede ser conveniente.
gg99
7

exitcode = data.wait(). El proceso secundario se bloqueará si escribe en la salida / error estándar, y / o lee desde la entrada estándar, y no hay pares.

Khachik
fuente
1

Esto funcionó para mí. También imprime el resultado devuelto por el proceso secundario

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
Chinni Mahesh
fuente