2011-03-15 16 views
31

Hay muchos puntos de salida en mi código de bash. Necesito hacer algún trabajo de limpieza a la salida, por lo que utiliza la trampa para agregar una llamada de retorno para la salida como esta:Cómo atrapar el código de salida en el script Bash

trap "mycleanup" EXIT 

El problema es que somos diferentes códigos de salida, lo que necesito hacer trabajos de limpieza correspondientes. ¿Puedo obtener el código de salida en mycleanup?

+0

trampa 'foo' EXIT o trampa 'foo' CHLD? –

Respuesta

31

Creo que puede usar $? para obtener el código de salida.

+1

sí, es correcto. ¡Gracias! – Dagang

+2

@Todd: Las variables '$ BASH_COMMAND' y' $ BASH_LINENO' también son útiles a veces. –

+4

@Todd, @bmk: no olvide que el comando * any * ejecutado cambia el valor de $ ?; por ejemplo, myCmdIWantToTest; echo $? ; myRC = $? ; ... ahora myRC es la 'verdad' del eco $? cmd siendo invocado. Si myCmdIWantToTest salió de 'false', ese valor se pierde. Lo mejor es ahorrar $? a una var designada por separado que es única. Usando exitCode = $? universalmente, puede terminar fácilmente heredando el código de salida de otros cmd (o más probablemente desde un subconjunto (script)). Además, no olvide que está bien el código de salida de prueba como parte de un if; entonces ; ... fi. Me gusta si myCmdIWantToTest; luego echo funcionó; else echo falló; fi – shellter

25

La respuesta aceptada es básicamente correcta, solo quiero aclarar las cosas.

El siguiente ejemplo funciona bien:

#!/bin/bash 

cleanup() { 
    rv=$? 
    rm -rf "$tmpdir" 
    exit $rv 
} 

tmpdir="$(mktemp)" 
trap "cleanup" INT TERM EXIT 
# Do things... 

Pero hay que tener más cuidado si al hacerlo en línea de limpieza, sin función. Por ejemplo, esto no funcionará:

trap "rv=$?; rm -rf $tmpdir; exit $rv" INT TERM EXIT 

En su lugar, tienen que escapar de las $rv y $? variables:

trap "rv=\$?; rm -rf $tmpdir; exit \$rv" INT TERM EXIT 

Usted también puede escapar $tmpdir, ya que se evalúan cuando la línea de trampas se ejecuta y si el valor tmpdir cambia más tarde que no le dará el comportamiento esperado.

Editar: Use shellcheck para verificar sus scripts bash y tenga en cuenta problemas como este.

2

que he encontrado que es mejor para atrapar salida independiente de la trampa para otras señales

Ejemplo trampa test script ...

umask 77 
tmpfile=`tmpfile.$$` 
trap 'rm -f "$tmpfile"' EXIT 
trap 'exit 2' HUP INT QUIT TERM 

touch $tmpfile 
read -r input 

exit 10 

El archivo temporal se borra. ¡Se conserva el valor de salida de archivo de 10! Las interrupciones dan como resultado un valor de salida de 2

Básicamente, siempre que no utilice "exit" en una trampa EXIT, saldrá con el valor de salida original preservado.

ASIDE: Observe las citas en la trampa EXIT. Eso me permite cambiar qué archivo debe limpiarse durante la vida útil de los scripts. A menudo también incluyo una prueba para la existencia de los archivos vaciables de $ tmpfile, por lo que ni siquiera necesito configurarlo al comienzo del script.

Cuestiones relacionadas