2010-12-07 12 views
76

Estoy construyendo un script de shell que tiene una función if como éste:salida un error de secuencia de comandos en

if jarsigner -verbose -keystore $keyst -keystore $pass $jar_file $kalias 
then 
    echo $jar_file signed sucessfully 
else 
    echo ERROR: Failed to sign $jar_file. Please recheck the variables 
fi 

... 

Quiero la ejecución de la secuencia de comandos para terminar después de mostrar el mensaje de error. ¿Como puedo hacer esto?

Respuesta

67

¿Está buscando exit?

Esta es la mejor guía de bash. http://tldp.org/LDP/abs/html/

En contexto:

if jarsigner -verbose -keystore $keyst -keystore $pass $jar_file $kalias 
then 
    echo $jar_file signed sucessfully 
else 
    echo ERROR: Failed to sign $jar_file. Please recheck the variables 1>&2 
    exit 1 # terminate and indicate error 
fi 

... 
+2

Si te gusta el ABS, te encantará la [BashGuide] (http://mywiki.wooledge.org/BashGuide), [BashFAQ] (http://mywiki.wooledge.org/BashFAQ) y [BashPitfalls] (http://mywiki.wooledge.org/BashPitfalls). –

-5

exit 1 es todo lo que necesita. El 1 es un código de retorno, por lo que puede cambiarlo si quiere, por ejemplo, 1 para significar una ejecución exitosa y -1 para indicar un error o algo así.

+12

En Unix, el éxito siempre es 0. Esto puede ayudar al usar 'test' o' && 'o' || '. – mouviciel

+4

Para ampliar el comentario de mouviciel: en scripts de shell, 0 siempre significa éxito, y 1 a 255 significa falla. -1 está fuera de rango (y a menudo tendrá el mismo efecto que 255, por lo que una falla como 1). – Gilles

+0

@mouviciel, @Gilles: Gracias por la información adicional. Ha pasado un tiempo desde que lidié con bash. – DGH

252

Si coloca set -e en una secuencia de comandos, la secuencia de comandos finalizará tan pronto como un comando dentro de ella falle (es decir, tan pronto como un comando devuelva un estado distinto de cero). Esto no le permite escribir su propio mensaje, pero a menudo los propios mensajes del comando que falla son suficientes.

La ventaja de este enfoque es que es automático: no se corre el riesgo de olvidarse de ocuparse de un caso de error.

Comandos cuyo estado se prueba por un condicional (como if, && o ||) no terminar la secuencia de comandos (de lo contrario el condicional sería inútil). Un modismo para el comando ocasional cuya falla no importa es command-that-may-fail || true. También puede desactivar set -e para una parte de la secuencia de comandos con set +e.

+2

De acuerdo con http://mywiki.wooledge.org/BashFAQ/105, esta función tiene un historial de ser oscuro y complejo en su determinación de qué códigos de error de los comandos provocan una salida automática.Además, "las reglas cambian de una versión Bash a otra, ya que Bash intenta rastrear la extremadamente deslizante definición POSIX de esta 'característica'". Estoy de acuerdo con @Dennis Williamson y con la respuesta aceptada de http://stackoverflow.com/questions/19622198/what-does-set-e-mean-in-a-bash-script - use trap 'error_handler' ERR. ¡Incluso si es una trampa! – NargothBond

+0

a menudo usando la bandera '-x' con la bandera' -e' es suficiente de un rastro de dónde está el programa al salir. Eso implica que el usuario del script también es el desarrollador. – Alex

33

Si desea poder gestionar un error en lugar de salir a ciegas, en lugar de utilizar set -e, utilice un trap en la pseudo señal ERR.

#!/bin/bash 
f() { 
    errcode=$? # save the exit code as the first thing done in the trap function 
    echo "error $errorcode" 
    echo "the command executing at the time of the error was" 
    echo "$BASH_COMMAND" 
    echo "on line ${BASH_LINENO[0]}" 
    # do some error handling, cleanup, logging, notification 
    # $BASH_COMMAND contains the command that was being executed at the time of the trap 
    # ${BASH_LINENO[0]} contains the line number in the script of that command 
    # exit the script or return to try again, etc. 
    exit $errcode # or use some other value or do return instead 
} 
trap f ERR 
# do some stuff 
false # returns 1 so it triggers the trap 
# maybe do some other stuff 

Otras trampas se pueden configurar para manejar otras señales, incluyendo las señales de Unix usuales y las otras señales seudo Bash RETURN y DEBUG.

5

Aquí es la manera de hacerlo:

#!/bin/sh 

abort() 
{ 
    echo >&2 ' 
*************** 
*** ABORTED *** 
*************** 
' 
    echo "An error occurred. Exiting..." >&2 
    exit 1 
} 

trap 'abort' 0 

set -e 

# Add your script below.... 
# If an error occurs, the abort() function will be called. 
#---------------------------------------------------------- 
# ===> Your script goes here 
# Done! 
trap : 0 

echo >&2 ' 
************ 
*** DONE *** 
************ 
' 
+0

¿Por qué el mensaje HECHO a stderr? – MattBianco

+0

Esta es una práctica común, por lo que puede canalizar la salida del script a stdout para que otro proceso pueda obtenerla sin tener los mensajes de información en el medio. – supercobra

+0

Probablemente sea una práctica igualmente común tratar cualquier cosa en stderr como una indicación de problemas. – MattBianco

Cuestiones relacionadas