Quiero generar un error en un script Bash con el mensaje "¡¡¡Casos de prueba fallaron !!!". ¿Cómo hacer esto en Bash?
Por ejemplo:
if [ condition ]; then
raise error "Test cases failed !!!"
fi
linux
bash
shell
error-handling
Naveen Kumar
fuente
fuente
echo you screwed up at ... | mail -s BUG $bugtrackeremailaddress
?Respuestas:
Esto depende de dónde desee que se almacene el mensaje de error.
Puede hacer lo siguiente:
O lo siguiente:
Cuando genera una excepción, detiene la ejecución del programa.
También puede usar algo como
exit xxx
dóndexxx
está el código de error que quizás desee volver al sistema operativo (de 0 a 255). Aquí125
y64
solo hay 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 aexit
.Como señaló @chepner , puede hacerlo
exit 1
, lo que significará un error no especificado .fuente
1>&2
hará el trucoexit
por sí mismo usa el estado de salida del comando completado más recientemente, que puede ser 0.exit 1
, que por convención significa 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:
O incluso más corto:
O el más corto:
Para salir con el código de salida de test_handler:
Manejo avanzado de errores
Si desea adoptar un enfoque más completo, puede tener un controlador de errores:
luego invocalo después de ejecutar tu caso de prueba:
o
Las ventajas de tener un controlador de errores como
exit_if_error
son:if
bloques que prueban los códigos de salida en busca de erroresBiblioteca 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
__FILE__
,__LINE__
en Bashfuente
Hay un par de formas más con las que puede 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
Dependiendo de cuál desee hacer, hay opciones de shell disponibles para usar. Para el primer caso, la carcasa ofrece una opción con
set -e
y para la segunda se podría hacer untrap
sobreEXIT
¿Debo usar
exit
en mi script / función?El uso
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 se define de tal manera que no requiere ninguna limpieza adicional 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
para error al salir?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 ocurriera 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 la
test
verificación en el directorio no existente, no lo haría, pasa a la condición elseLos comandos de una canalización que no sea la anterior son inmunes. En el siguiente ejemplo, porque el código de salida del comando ejecutado más recientemente (más a la derecha) se considera (
cat
) y fue exitoso. Esto podría evitarse estableciendo laset -o pipefail
opción, pero sigue siendo una advertencia.Recomendado para su uso:
trap
a la salidaEl veredicto es si desea poder manejar un error en lugar de salir a ciegas, en lugar de usar
set -e
, use atrap
en laERR
pseudo señal.La
ERR
trampa 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 sicmd
, ocmd ||
) sale con un estado de salida distinto de cero. .La práctica general es que definimos un controlador de trampas para proporcionar información de depuración adicional sobre qué línea y qué causa la salida. Recuerde que el código de salida del último comando que causó la
ERR
señal aún estaría disponible en este punto.y usamos este controlador como se muestra a continuación en la parte superior del script que está fallando
Poniendo esto junto en un script simple que contenía
false
en la línea 15, la información que obtendría comoEl
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ñalEXIT
. También puede atrapar varias señales al mismo tiempo. La lista de señales admitidas para capturar se puede encontrar en trap.1p - página de manual de LinuxOtra 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-shell con
set -e
no funcionaría. Elfalse
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
Lo mismo ocurre con
trap
también. La lógica siguiente no funcionaría por las razones mencionadas anteriormente.fuente
Aquí hay una trampa simple que imprime el último argumento de lo que falló en STDERR, informa la línea en la que falló y sale del script con el número de línea como código de salida. Tenga en cuenta que estas no siempre son buenas ideas, pero esto demuestra alguna aplicación creativa sobre la que podría desarrollar.
Lo puse en un script con un bucle para probarlo. Solo busco un acierto en algunos números aleatorios; puede utilizar pruebas reales. Si necesito fianza, llamo a false (que desencadena la trampa) con el mensaje que quiero lanzar.
Para una funcionalidad elaborada, haga que la trampa llame a una función de procesamiento. Siempre puede usar una declaración de caso en su arg ($ _) si necesita hacer más limpieza, etc. Asigne a una var para un poco de azúcar sintáctico -
Salida de muestra:
Obviamente, podrías
Mucho espacio para mejorar el diseño.
Los inconvenientes incluyen el hecho de que
false
no es bonito (por lo tanto, el azúcar), y otras cosas que disparan la trampa pueden parecer un poco estúpidas. Aún así, me gusta este método.fuente
Tiene 2 opciones: Redirigir la salida del script a un archivo, Introducir un archivo de registro en el script y
Aquí asume que el script genera toda la información necesaria, incluidos los mensajes de advertencia y error. A continuación, puede redirigir la salida a un archivo de su elección.
El comando anterior redirige tanto la salida estándar como la salida de error a su archivo de registro.
Con este enfoque, no es necesario introducir un archivo de registro en el script, por lo que la lógica es un poco más sencilla.
En su secuencia de comandos, agregue un archivo de registro codificándolo:
o pasándolo por un parámetro:
Es una buena idea agregar la marca de tiempo en el momento de la ejecución al archivo de registro en la parte superior del script:
Luego puede redirigir sus mensajes de error al archivo de registro
Esto agregará el error al archivo de registro y continuará la ejecución. Si desea detener la ejecución cuando ocurren errores críticos, puede
exit
el script:Tenga en cuenta que
exit 1
indica que el programa detiene la ejecución debido a un error no especificado. Puede personalizar esto si lo desea.Con este enfoque, puede personalizar sus registros y tener un archivo de registro diferente para cada componente de su secuencia de comandos.
Si tiene un script relativamente pequeño o desea ejecutar el script de otra persona sin modificarlo, el primer método es más adecuado.
Si siempre desea que el archivo de registro esté en la misma ubicación, esta es la mejor opción de la 2. Además, si ha creado una secuencia de comandos grande con varios componentes, es posible que desee registrar cada parte de manera diferente y el segundo enfoque es su único opción.
fuente
A menudo encuentro útil escribir una función para manejar mensajes de error para que el código sea más limpio en general.
Esto toma el código de error del comando anterior y lo usa como el código de error predeterminado al salir de todo el script. También toma nota del tiempo, con microsegundos donde se admite (la fecha de GNU
%N
es nanosegundos, que truncamos a microsegundos más tarde).Si la primera opción es cero o un entero positivo, se convierte en el código de salida y lo eliminamos de la lista de opciones. Luego informamos el mensaje a error estándar, con el nombre del script, la palabra "ERROR" y el tiempo (usamos la expansión de parámetros para truncar nanosegundos a microsegundos, o para tiempos no GNU, truncar, por ejemplo,
12:34:56.%N
a12:34:56
). Se agregan dos puntos y un espacio después de la palabra ERROR, pero solo cuando se proporciona un mensaje de error. Finalmente, salimos del script usando el código de salida previamente determinado, activando las trampas de forma normal.Algunos ejemplos (suponga que el código reside en
script.sh
):fuente