En un script Bash, ¿cómo puedo salir del script completo si ocurre una determinada condición?
Estoy escribiendo un script en Bash para probar algún código. Sin embargo, parece una tontería ejecutar las pruebas si la compilación del código falla en primer lugar, en cuyo caso simplemente abortaré las pruebas.
¿Hay alguna manera de hacer esto sin envolver todo el script dentro de un bucle while y usar pausas? ¿Algo así como un dun dun dun goto?
Pruebe esta declaración:
exit 1
Reemplace 1
con códigos de error apropiados. Consulte también Códigos de salida con significados especiales .
Utilice conjunto -e
#!/bin/bash
set -e
/bin/command-that-fails
/bin/command-that-fails2
El script finalizará después de la primera línea que falla (devuelve un código de salida distinto de cero). En este caso, comando-that-fails2 no se ejecutará.
Si verificaras el estado de retorno de cada comando, tu script se vería así:
#!/bin/bash
# I'm assuming you're using make
cd /project-dir
make
if [[ $? -ne 0 ]] ; then
exit 1
fi
cd /project-dir2
make
if [[ $? -ne 0 ]] ; then
exit 1
fi
Con set -e quedaría así:
#!/bin/bash
set -e
cd /project-dir
make
cd /project-dir2
make
Cualquier comando que falle hará que todo el script falle y devolverá un estado de salida que puede verificar con $? . Si su script es muy largo o está creando muchas cosas, se pondrá bastante feo si agrega verificaciones de estado de devolución en todas partes.
Un chico de SysOps me enseñó una vez la técnica de la garra de tres dedos:
yell() { echo "$0: $*" >&2; }
die() { yell "$*"; exit 111; }
try() { "$@" || die "cannot $*"; }
Estas funciones son *NIX OS y shell robustas. Colóquelos al comienzo de su script (bash o de otro tipo), try()
su declaración y código.
Explicación
(basado en el comentario de la oveja voladora ).
yell
: imprime el nombre del script y todos los argumentos parastderr
:$0
es la ruta al script;$*
son todos argumentos.>&2
significa>
redirigir la salida estándar a & pipe2
. la tubería1
seríastdout
ella misma.
die
hace lo mismo queyell
, pero sale con un estado de salida distinto de 0 , lo que significa "fallar".try
usa el||
(booleanoOR
), que solo evalúa el lado derecho si el izquierdo falló.$@
Son todos argumentos nuevamente, pero diferentes .
Si invocará el script con source
, puede usar return <x>
dónde <x>
estará el estado de salida del script (use un valor distinto de cero para error o falso). Pero si invoca un script ejecutable (es decir, directamente con su nombre de archivo), la declaración return resultará en una queja (mensaje de error "return: sólo puede `regresar' desde una función o script fuente").
Si exit <x>
se usa en su lugar, cuando se invoca el script con source
, se saldrá del shell que inició el script, pero un script ejecutable simplemente terminará, como se esperaba.
Para manejar cualquiera de los casos en el mismo script, puede usar
return <x> 2> /dev/null || exit <x>
Esto manejará cualquier invocación que pueda ser adecuada. Eso supone que utilizará esta declaración en el nivel superior del script. Yo desaconsejaría salir directamente del script desde una función.
Nota: <x>
se supone que es solo un número.