2010-12-15 12 views
6

En python (en un sistema Linux), estoy iniciando un comando usando os.system() y recuperando el código de retorno. Si ese código de retorno es diferente de 0, me gustaría hacer que el programa salga con el mismo código de retorno. Así que escribí:Cómo eludir el límite del rango 0-255 para sys.exit() en python?

ret = os.system(cmd) 
if ret != 0: 
    print "exit with status %s" % ret 
    sys.exit(ret) 

Cuando el código de retorno es inferior a 256, que funciona bien, pero cuando es superior a 255, el código de salida utilizado es 0. ¿Cómo puedo hacer sys.exit() acepto códigos mayor que 255?

Editar: el límite es en realidad 255

De hecho, la variable ret recibe 256, pero sys.exit() no hace uso de ella, por lo que el programa devuelve 0 en su lugar. Cuando inicio cmd manualmente, veo que devuelve 1, no 256.

Respuesta

0

funciona para mí (CentOS 5.5, Python 2.6.5):

$ python 
>>> import sys 
>>> sys.exit(245) 
$ echo $? 
245 
+0

Esto no es correcto, no prueba lo mismo. – unwind

+0

Lo siento, mi mal, el límite es 255, no 127. –

+2

El límite de 255 se aplica por el shell: http://tldp.org/LDP/abs/html/exit-status.html y http: // tldp. org/LDP/abs/html/exitcodes.html –

2

Usted no puede no debe, porque el sistema reserva códigos de salida superiores a 128 para sí mismo. Si el código de retorno es de 0 a 127, significa que el programa salió solo. Si el código de retorno es mayor que 128, significa que el programa fue terminado por una señal del sistema (por ejemplo, SIGKILL o SIGTERM). El número de señal es el código de resultado menos 128.

Deberás detectarlo y hacer algún otro tipo de indicación de salida, creo. Quizás imprima el código de retorno en STDOUT y luego regrese con 0 (salida normal, salida normal) o 1 (cmd tenía un valor de retorno distinto de cero, la salida significa algo).

edición: Al parecer (de this comment), Python es más inteligente que un script de shell ... Para ponerlo de nuevo en un código de salida regular de Linux, intente esto:

subprocess_exit_code = (ret >> 8) & 0x7f 
subprocess_signal_number = ret & 0xff 

if subpprocess_signal_number == 0: 
    exit_code = subprocess_exit_code 
else: 
    exit_code = 128 + subprocess_signal_number 

Aunque esto ignora el núcleo- información de volcado.

5

En realidad, el documentation indica que

salida de indicación de estado: un número de 16 bits, cuyo byte bajo es el número de señales que mató el proceso, y cuyo byte es el estado de salida (si la señal el número es cero); el bit alto del byte bajo se establece si se produjo un archivo core.

por eso es necesario para procesar el número devuelto por sys.exit() con el fin de recuperar el estado de salida de bienes, así:

ret = os.system(cmd) 
# Ignore the first byte, use the second one only 
ret = ret >> 8 
if ret != 0: 
    print "exit with status %s" % ret 
    sys.exit(ret) 

Y ahora funciona: ret contiene 1 en lugar de 256

+0

Oh. Empecé a preguntarme por qué devuelve 0x8b00 en la terminación segfaulty. – ulidtko

+0

Creo que si se vuelca núcleo que le dará un código de salida diferente a lo que habría conseguido si lo ejecuta desde la línea de comandos. –

+1

puede usar 'subprocess.call' en lugar de' os.system': compare 'python -c 'import os; print [os.system (["./ exit-with ", str (i)]) para i en [127,128,255,256,257]] '' y' python -c 'importar el subproceso imprimir [subprocess.call (["./ exit-with", str (i)]) para i en [127,128,255,256,257]] '' donde 'exit-with' es http://ideone.com/zFelC – jfs

Cuestiones relacionadas