En un script Bash, ¿cómo puedo salir del script completo si ocurre una determinada condición?

Resuelto samoz asked hace 15 años • 9 respuestas

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?

samoz avatar Sep 04 '09 16:09 samoz
Aceptado

Pruebe esta declaración:

exit 1

Reemplace 1con códigos de error apropiados. Consulte también Códigos de salida con significados especiales .

Michael Foukarakis avatar Sep 04 '2009 09:09 Michael Foukarakis

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.

Shizzmo avatar Sep 04 '2009 15:09 Shizzmo

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 para stderr:
    • $0es la ruta al script;
    • $*son todos argumentos.
    • >&2significa >redirigir la salida estándar a & pipe2 . la tubería1 sería stdoutella misma.
  • diehace lo mismo que yell, pero sale con un estado de salida distinto de 0 , lo que significa "fallar".
  • tryusa el ||(booleano OR), que solo evalúa el lado derecho si el izquierdo falló.
    • $@Son todos argumentos nuevamente, pero diferentes .
c.gutierrez avatar Aug 26 '2014 21:08 c.gutierrez

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.

kavadias avatar Sep 12 '2014 14:09 kavadias