2011-02-16 21 views
6

Estoy utilizando Python 2.7.1 en un cuadro de Windows Server 2008 R2 x64.Python: obtener salida de una línea de comando que sale con código de salida distinto de cero

Estoy tratando de obtener el resultado de un proceso de línea de comando que da un estado de salida distinto de cero después de generar la información que necesito.

Al principio estaba usando subprocess.check_output, y capturando el CalledProcessError que se produce con un estado de salida distinto de cero, pero mientras el código de retorno se almacenaba en el error, ningún resultado de salida lo reveló.

Ejecutando esto en casos que dan salida pero tienen un estado de salida de 0 funciona correctamente y puedo obtener la salida usando subprocess.check_output.

Mi suposición era que la salida se escribía en STDOUT pero la excepción saca su 'salida' de STDERR. Intenté volver a implementar la funcionalidad de check_output, pero todavía no recibo nada en la salida cuando creo que debería estar viendo salida en STDOUT y STDERR. Mi código actual está por debajo (donde 'comando' es el texto completo, incluyendo los parámetros, de mando Me postulo:

process = subprocess.Popen(command, stdout=subprocess.PIPE, 
stderr=subprocess.STDOUT, universal_newlines=True) 
output = process.communicate() 
retcode = process.poll() 
if retcode: 
    raise subprocess.CalledProcessError(retcode, image_check, output=output) 
    return output 

Esto me da lo siguiente en la salida variable:

es mi código subprocess.Popen correcto?

+0

después de '.communicate()', puede usar 'process.returncode' directamente en lugar de' process.poll() '. – jfs

+0

Cómo obtener resultados desde la línea de comandos con Python: http://stackoverflow.com/a/20456745/445131 –

Respuesta

8

código funciona bien. Resulta que el proceso que está llamando probablemente esté produciendo a CON. Vea el ejemplo siguiente

import subprocess 

def check_output(command): 
    process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True) 
    output = process.communicate() 
    retcode = process.poll() 
    if retcode: 
      raise subprocess.CalledProcessError(retcode, command, output=output[0]) 
    return output 

command = "echo this>CON" 

print "subprocess -> " + subprocess.check_output(command, shell=True) 
print "native -> " + str(check_output(command)) 

try: 
    subprocess.check_output("python output.py", shell=True) 
except subprocess.CalledProcessError, e: 
    print "subproces CalledProcessError.output = " + e.output 

try: 
    check_output("python output.py") 
except subprocess.CalledProcessError, e: 
    print "native CalledProcessError.output = " + e.output 

salida

subprocess -> 
native -> ('', None) 
stderr subproces CalledProcessError.output = stdout 
native CalledProcessError.output = stderr stdout 

Lamentablemente, no sé cómo resolver el problema. Observe que los resultados subprocess.check_output contienen solo la salida de stdout. El reemplazo check_output generaría stderr y stdout.

Después de inspeccionar subprocess.check_output, de hecho genera un CalledProcessError con la salida que contiene solamente stdout.

+1

Estoy bastante seguro de que esto es lo que está sucediendo.Pude ponerme en contacto con el proveedor y descubrí abotu algunos parámetros adicionales no documentados que hacen que no se produzcan los estados de salida distintos de cero, por lo que mi scripting está funcionando ahora, aunque me gustaría saber cómo capturar los resultados de CON. – bplattenburg

1

¿Ha intentado stderr=subprocess.STDOUT como se ha mencionado en la página pitón doc:

Para capturar también el error estándar en el resultado, utilice stderr = subprocess.STDOUT:

Aquí hay un código de prueba :

import subprocess 

try: 
    subprocess.check_output('>&2 echo "errrrr"; exit 1', shell=True) 
except subprocess.CalledProcessError as e: 
    print 'e.output: ', e.output 


try: 
    subprocess.check_output('>&2 echo "errrrr"; exit 1', shell=True, stderr=subprocess.STDOUT) 
except subprocess.CalledProcessError as e: 
    print 'e.output: ', e.output 

de salida:

errrrr 
e.output: 
e.output: errrrr 
Cuestiones relacionadas