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 xxxdóndexxxestá el código de error que quizás desee volver al sistema operativo (de 0 a 255). Aquí125y64solo 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>&2hará el trucoexitpor 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_errorson:ifbloques 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 -ey para la segunda se podría hacer untrapsobreEXIT¿Debo usar
exiten mi script / función?El uso
exitgeneralmente 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 -epara error al salir?set -efue 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
testverificació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 pipefailopción, pero sigue siendo una advertencia.Recomendado para su uso:
trapa la salidaEl veredicto es si desea poder manejar un error en lugar de salir a ciegas, en lugar de usar
set -e, use atrapen laERRpseudo señal.La
ERRtrampa 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
ERRseñ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
falseen la línea 15, la información que obtendría comoEl
traptambié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 -eno funcionaría. Elfalseestá 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) || falseLo mismo ocurre con
traptambié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
falseno 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
exitel script:Tenga en cuenta que
exit 1indica 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
%Nes 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.%Na12: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