
Estoy usando una trampa ERR para detectar cualquier error en mi script bash y mostrar lo que sucedió en el registro. (similar a esta pregunta:Trampa, ERR y eco de la línea de error) Funciona como se esperaba. El único problema es que en algún momento de mi script se espera que aparezca un código de salida! = 0. ¿Cómo puedo hacer que la trampa no se active en esta situación?
Aquí hay un código:
err_report() {
echo "errexit on line $(caller)" | tee -a $LOGFILE 1>&2
}
trap err_report ERR
Luego, más adelante en el guión:
<some command which occasionally will return a non-zero exit code>
if [ $? -eq 0 ]; then
<handle stuff>
fi
Cada vez que el comando devuelve un valor distinto de cero, se activa mi trampa. ¿Puedo evitar esto sólo para esta parte del código?
Revisé esta pregunta:Comportamiento correcto de las trampas EXIT y ERR al usar `set -eu` pero realmente no entiendo cómo aplicarlo a mi caso, si es que es aplicable.
Respuesta1
Un ERR
trap
no se activará si se "capta" inmediatamente un código de error, lo que significa que ustedpoderuse if
declaraciones y todo eso sin tener que activar y desactivar la captura de errores todo el tiempo. Sin embargo, tuno puedouse la verificación $?
para el control de flujo, porque cuando llegue a esa verificación, ya (puede) tener el error no detectado.
Si tienes un comando esperas que falle, ynoSi desea que esas fallas activen el trap
, simplemente tiene que detectar la falla. Envolverlos en una if
declaración es complicado y detallado, pero esta taquigrafía funciona muy bien:
/bin/false || : # will not trigger an ERR trap
Sin embargo, si desea hacer cosas cuando falla un comando, if
estará bien aquí:
if ! /bin/false; then
echo "this was not caught by the trap!"
fi
O alternativamente, else
también detectará el estado de error:
if /bin/false; then
: # dead code
else
echo "this was not caught by the trap!"
fi
En resumen, set -e
y trap "command" ERR
solo se activa si hay una condición de error que no se tiene en cuenta inmediata e intrínsecamente.
Respuesta2
Puede habilitar/deshabilitar la ERR
captura durante partes de su código según sea necesario.
#!/bin/bash
err_report() {
echo "errexit on line $(caller)"
}
trap err_report ERR
trap - ERR # disable ERR trap
false
if [ $? -eq 0 ]; then
printf "OK\n"
else
printf "FAIL\n" # prints FAIL
fi
trap err_report ERR # enable ERR trap
false # prints errexit on line 14
Respuesta3
A menudo encuentro que quiero evitar la trampa ERR pero tampoco quiero descartar el código de retorno de mi función. Entonces el patrón que uso es este:
RC=0
some_function || RC=$?
Luego hago lo que sea necesario con RC.
Respuesta4
La ERR
trampa obedece las mismas reglas que set -e
, es decir, no tiene efecto sobre los comandos que se utilizan como condiciones. Entonces,
trap "echo error" ERR
false # this should trigger the trap
if ! false; then # this shouldn't
echo handle stuff
fi
Recuerde que el comando en elif
condición puede sercualquiercomando, no tiene por qué serlo [ .. ]
. Por lo tanto, si solo desea una evaluación verdadero/falso del estado de salida de un comando, utilícela directamente en la if
condición.
Si necesita guardar el código de salidayEvita la ERR
trampa, tendrás que hacer algo como
somecmd && :; ret=$?
Aquí, &&
aplastará la ERR
trampa, pero como solo se ejecuta si el código de salida es cero, sabremos que el código de salida es el mismo después :
.
Quizás quieras comprobarBashFAQ 105: ¿Por qué set -e (o set -o errexit, o trap ERR) no hace lo que esperaba?