Haz todo lo posible por interpretar el código bien previamente a usarlo a tu proyecto si ttienes algo que aportar puedes dejarlo en los comentarios.
Solución:
Esto depende de dónde desee que se almacene el mensaje de error.
Puede hacer lo siguiente:
echo "Error!" > logfile.log
exit 125
O lo siguiente:
echo "Error!" 1>&2
exit 64
Cuando genera una excepción, detiene la ejecución del programa.
También puedes usar algo como exit xxx
dónde xxx
es el código de error que puede querer volver al sistema operativo (de 0 a 255). Aquí 125
y 64
son solo códigos aleatorios con los que puede salir. Cuando necesite indicar al sistema operativo que el programa se detuvo de manera anormal (por ejemplo, se produjo un error), debe pasar un código de salida distinto de cero para exit
.
Como señaló @chepner, puede hacer exit 1
, lo que significará un error no especificado.
Manejo básico de errores
Si su corredor de casos de prueba devuelve un código distinto de cero para las pruebas fallidas, simplemente puede escribir:
test_handler test_case_x; test_result=$?
if ((test_result != 0)); then
printf '%sn' "Test case x failed" >&2 # write error message to stderr
exit 1 # or exit $test_result
fi
O incluso más corto:
if ! test_handler test_case_x; then
printf '%sn' "Test case x failed" >&2
exit 1
fi
O el más corto:
test_handler test_case_x || printf '%sn' "Test case x failed" >&2; exit 1;
Para salir con el código de salida de test_handler:
test_handler test_case_x || ec=$?; printf '%sn' "Test case x failed" >&2; exit $ec;
Manejo avanzado de errores
Si desea adoptar un enfoque más completo, puede tener un controlador de errores:
exit_if_error()
local exit_code=$1
shift
[[ $exit_code ]] && # do nothing if no error code passed
((exit_code != 0)) && # do nothing if error code is 0
printf 'ERROR: %sn' "[email protected]" >&2 # we can use better logging here
exit "$exit_code" # we could also check to make sure
# error code is numeric when passed
luego invocalo después de ejecutar tu caso de prueba:
run_test_case test_case_x
exit_if_error $? "Test case x failed"
o
run_test_case test_case_x || exit_if_error $? "Test case x failed"
Las ventajas de tener un controlador de errores como exit_if_error
están:
- podemos estandarizar toda la lógica de manejo de errores, como el registro, la impresión de un seguimiento de la pila, la notificación, la limpieza, etc., en un solo lugar
- Al hacer que el controlador de errores obtenga el código de error como argumento, podemos evitar que la persona que llama el desorden de
if
bloques que prueban códigos de salida en busca de errores - si tenemos un manejador de señales (usando trampa), podemos invocar el manejador de errores desde allí
Biblioteca de registro y manejo de errores
Aquí hay una implementación completa del manejo y registro de errores:
https://github.com/codeforester/base/blob/master/lib/stdlib.sh
Artículos Relacionados
- Manejo de errores en Bash
- El comando incorporado ‘llamador’ en Bash Hackers Wiki
- ¿Existe algún código de estado de salida estándar en Linux?
- BashFAQ / 105 – ¿Por qué el set -e (o set -o errexit, o trap ERR) no hace lo que esperaba?
- Equivalente de
__FILE__
,__LINE__
en Bash - ¿Hay un comando TRY CATCH en Bash?
- Para agregar un seguimiento de pila al controlador de errores, es posible que desee ver esta publicación: Seguimiento de programas ejecutados llamados por un script Bash
- Ignorar errores específicos en un script de shell
- Captura de códigos de error en una tubería de shell
- ¿Cómo administro la verbosidad del registro dentro de un script de shell?
- ¿Cómo registrar el nombre de la función y el número de línea en Bash?
- Son corchetes dobles [[ ]]preferible a los corchetes simples [ ] en Bash?
Hay un par de formas más de abordar este problema. Suponiendo que uno de sus requisitos es ejecutar un script / función de shell que contenga algunos comandos de shell y verificar si el script se ejecutó correctamente y arrojar errores en caso de fallas.
Los comandos del shell generalmente se basan en los códigos de salida devueltos para informar al shell si tuvo éxito o falló debido a algunos eventos inesperados.
Entonces, lo que quiere hacer recae en estas dos categorías
- salir en caso de error
- salida y limpieza en caso de error
Dependiendo de cuál desee hacer, hay opciones de shell disponibles para usar. Para el primer caso, el caparazón proporciona una opción con set -e
y por el segundo podrías hacer un trap
sobre EXIT
Debo usar exit
en mi script / función?
Utilizando exit
generalmente mejora la legibilidad En ciertas rutinas, una vez que sepa la respuesta, querrá salir a la rutina de llamada inmediatamente. Si la rutina está definida de tal manera que no requiere más limpieza una vez que detecta un error, no salir inmediatamente significa que debe escribir más código.
Por lo tanto, en los casos en que necesite realizar acciones de limpieza en el script para limpiar la terminación del script, se prefiere no usar exit
.
Debo usar set -e
por error al salir?
¡No!
set -e
fue un intento de agregar “detección automática de errores” al shell. Su objetivo era hacer que el shell abortara cada vez que se producía un error, pero conlleva muchos peligros potenciales, por ejemplo,
-
Los comandos que forman parte de una prueba if son inmunes. En el ejemplo, si espera que se rompa en el
test
Verifique el directorio no existente, no lo haría, pasa a la condición elseset -e f() test -d nosuchdir && echo no dir; f echo survived
-
Los comandos de una canalización que no sea la anterior son inmunes. En el siguiente ejemplo, debido a que el código de salida del comando ejecutado más recientemente (más a la derecha) se considera (
cat
) y tuvo éxito. Esto podría evitarse estableciendo elset -o pipefail
opción, pero sigue siendo una advertencia.set -e somecommand that fails | cat - echo survived
Recomendado para su uso – trap
a la salida
El veredicto es si desea poder manejar un error en lugar de salir a ciegas, en lugar de usar set -e
, utilizar una trap
sobre el ERR
pseudo señal.
los ERR
trap no es ejecutar código cuando el propio shell sale con un código de error distinto de cero, sino cuando cualquier comando ejecutado por ese shell que no es parte de una condición (como en if cmd
, o cmd ||
) sale con un estado de salida distinto de cero.
La práctica general es definir un controlador de trampas para proporcionar información de depuración adicional sobre qué línea y qué causa la salida. Recuerde el código de salida del último comando que provocó la ERR
la señal todavía estaría disponible en este punto.
cleanup()
exitcode=$?
printf 'error condition hitn' 1>&2
printf 'exit code returned: %sn' "$exitcode"
printf 'the command executing at the time of the error was: %sn' "$BASH_COMMAND"
printf 'command present on line: %d' "$BASH_LINENO[0]"
# Some more clean up code can be added here before exiting
exit $exitcode
y solo usamos este controlador como se muestra a continuación en la parte superior del script que está fallando
trap cleanup ERR
Poniendo esto junto en un script simple que contenía false
en la línea 15, la información que obtendría como
error condition hit
exit code returned: 1
the command executing at the time of the error was: false
command present on line: 15
los trap
también proporciona opciones independientemente del error para ejecutar la limpieza al finalizar el shell (por ejemplo, el script de shell sale), en la señal EXIT
. También puede atrapar varias señales al mismo tiempo. La lista de señales admitidas para atrapar se puede encontrar en trap.1p – página de manual de Linux
Otra cosa a tener en cuenta sería comprender que ninguno de los métodos proporcionados funciona si se trata de sub-shells involucrados, en cuyo caso, es posible que deba agregar su propio manejo de errores.
-
En un sub-caparazón con
set -e
no funcionaría. losfalse
está restringido al sub-shell y nunca se propaga al shell padre. Para hacer el manejo de errores aquí, agregue su propia lógica para hacer(false) || false
set -e (false) echo survived
-
Lo mismo pasa con
trap
además. La lógica siguiente no funcionaría por las razones mencionadas anteriormente.trap 'echo error' ERR (false)
Si para ti ha sido de ayuda nuestro artículo, agradeceríamos que lo compartas con otros desarrolladores y nos ayudes a dar difusión a nuestro contenido.