Considere este fragmento:
stop () {
echo "${1}" 1>&2
exit 1
}
func () {
if false; then
echo "foo"
else
stop "something went wrong"
fi
}
Normalmente cuando func
se llama provocará que el script finalice, que es el comportamiento previsto. Sin embargo, si se ejecuta en un sub-shell, como en
result=`func`
no saldrá del script. Esto significa que el código de llamada tiene que verificar el estado de salida de la función cada vez. Hay alguna manera de evitar esto? ¿Para esto es esto set -e
?
shell
shell-script
exit
subshell
Ernest AC
fuente
fuente
func
.Respuestas:
Usted podría matar el intérprete original, (
kill $$
) antes de llamarexit
, y que probablemente había trabajo. Pero:En su lugar, puede utilizar una de las varias formas de devolver un valor en las Preguntas frecuentes de Bash . La mayoría de ellos no son tan buenos, desafortunadamente. Es posible que se quede atascado buscando errores después de cada llamada a la función (
-e
tiene muchos problemas ). O eso, o cambia a Perl.fuente
Podría decidir que el estado de salida 77, por ejemplo, significa salir de cualquier nivel de subshell y hacer
set -E
en combinación conERR
trampas es un poco como una versión mejorada deset -e
que le permite definir su propio manejo de errores.En zsh, las trampas ERR se heredan automáticamente, por lo que no es necesario
set -E
, también puede definir trampas comoTRAPERR()
funciones y modificarlas$functions[TRAPERR]
, comofunctions[TRAPERR]="echo was here; $functions[TRAPERR]"
fuente
kill $$
.echo "$(exit 77)"
; el guión continuará como si hubiéramos escritoecho ""
Como alternativa
kill $$
, también puede intentarlokill 0
, funcionará en el caso de subcapas anidadas (todas las personas que llaman y el proceso secundario recibirán la señal) ... pero sigue siendo brutal y feo.fuente
Prueba esto ...
Los resultados que obtengo son ...
Notas
if
prueba seatrue
ofalse
(ver las 2 carreras)if
prueba esfalse
, nunca llegamos a la subshell.fuente
(Respuesta específica de Bash) Bash no tiene el concepto de excepciones. Sin embargo, con set -o errexit (o el equivalente: set -e) en el nivel más externo, el comando fallido hará que la subshell salga con un estado de salida distinto de cero. Si se trata de un conjunto de subcapas anidadas sin condicionales en torno a la ejecución de esas subcapas, efectivamente 'enrollará' todo el script y saldrá.
Esto puede ser complicado cuando se trata de incluir bits de varios códigos bash en un script más grande. Una parte de bash puede funcionar bien por sí sola, pero cuando se ejecuta bajo errexit (o sin errexit), se comporta de manera inesperada.
fuente
Mi ejemplo para salir en un trazador de líneas:
fuente