Soy un novato en scripting de shell. Quiero imprimir un mensaje y salir de mi script si falla un comando. He intentado:
my_command && (echo 'my_command failed; exit)
Pero no funciona. Sigue ejecutando las instrucciones siguiendo esta línea en el script. Estoy usando Ubuntu y bash.
linux
bash
exit
exitstatus
usuario459246
fuente
fuente
Respuestas:
Tratar:
Cuatro cambios:
&&
a||
{ }
en lugar de( )
;
despuésexit
y{
y antes}
Como desea imprimir el mensaje y salir solo cuando el comando falla (sale con un valor distinto de cero), no necesita
||
un&&
.se ejecutará
cmd2
cuandocmd1
tenga éxito (valor de salida0
). Donde comose ejecutará
cmd2
cuandocmd1
falle (valor de salida distinto de cero).El uso
( )
hace que el comando dentro de ellos se ejecute en un sub-shell y llamar aexit
desde allí hace que salga del sub-shell y no de su shell original, por lo tanto, la ejecución continúa en su shell original.Para superar este uso
{ }
Los dos últimos cambios son requeridos por bash.
fuente
{ (>&2 echo 'my_command failed') ; exit 1; }
Las otras respuestas han cubierto bien la pregunta directa, pero también puede interesarle usar
set -e
. Con eso, cualquier comando que falle (fuera de contextos específicos como lasif
pruebas) hará que el script se cancele. Para ciertos scripts, es muy útil.fuente
set -e
tiene un conjunto de reglas largo y arcano sobre cuándo funciona y cuándo no. (Si alguien correif yourfunction; then ...
,set -e
nunca disparará adentroyourfunction
o cualquier cosa que llame, porque ese código se considera "marcado"). Consulte la sección de ejercicios de BashFAQ # 105 , donde se analizan esta y otras dificultades (algunas de las cuales solo se aplican a versiones de shell específicas, por lo que debe asegurarse de probar cada versión que pueda usarse para ejecutar su script).Tenga en cuenta también que el estado de salida de cada comando se almacena en la variable de shell $ ?, que puede verificar inmediatamente después de ejecutar el comando. Un estado distinto de cero indica falla:
fuente
echo "Just finished step A"
, sin saber que esoecho
sobrescribió el$?
que iba a verificarse más tarde.Si desea ese comportamiento para todos los comandos en su script, simplemente agregue
Al comienzo del guión. Este par de opciones le dice al intérprete bash que salga cuando un comando regrese con un código de salida distinto de cero.
Sin embargo, esto no le permite imprimir un mensaje de salida.
fuente
trap
comando incorporado bash.set -o pipefail
podría no ser el comportamiento deseado. Aún así, gracias por señalarlo!set -e
no es del todo confiable, consistente o predecible! Para convencerse de eso, revise la sección de ejercicios de BashFAQ # 105 , o la tabla que compara los comportamientos de diferentes shells en in-ulm.de/~mascheck/various/set-eHe pirateado el siguiente idioma:
Preceda cada comando con un eco informativo y siga cada comando con esa misma
if [ $? -ne 0 ];...
línea. (Por supuesto, puede editar ese mensaje de error si lo desea).fuente
if ! javac *.java; then ...
- ¿Por qué molestarse$?
en absoluto?Siempre que
my_command
esté diseñado canónicamente, es decir , devuelve 0 cuando tiene éxito, entonces&&
es exactamente lo contrario de lo que desea. Que desea||
.También tenga en cuenta que
(
no me parece correcto en bash, pero no puedo intentar desde donde estoy. Dime.fuente
También puede usar, si desea conservar el estado de error de salida, y tener un archivo legible con un comando por línea:
Esto, sin embargo, no imprimirá ningún mensaje de error adicional. Pero en algunos casos, el error será impreso por el comando fallido de todos modos.
fuente
exit $?
; solo seexit
usa$?
como su valor predeterminado.El
trap
shell incorporado permite la captura de señales y otras condiciones útiles, incluida la ejecución fallida de comandos (es decir, un estado de retorno distinto de cero). Entonces, si no desea probar explícitamente el estado de retorno de cada comando, puede decirtrap "your shell code" ERR
y el código de shell se ejecutará cada vez que un comando devuelva un estado que no sea cero. Por ejemplo:trap "echo script failed; exit 1" ERR
Tenga en cuenta que, al igual que con otros casos de captura de comandos fallidos, las tuberías necesitan un tratamiento especial; lo anterior no atrapará
false | true
.fuente