Considere este trecho:
stop () {
echo "${1}" 1>&2
exit 1
}
func () {
if false; then
echo "foo"
else
stop "something went wrong"
fi
}
Normalmente, quando func
é chamado, o script é finalizado, que é o comportamento pretendido. No entanto, se for executado em um sub-shell, como em
result=`func`
não sairá do script. Isso significa que o código de chamada deve verificar o status de saída da função todas as vezes. Há alguma maneira de evitar isto? É para isso que set -e
serve?
shell
shell-script
exit
subshell
Ernest AC
fonte
fonte
func
.Respostas:
Você pode matar o shell original (
kill $$
) antes de ligarexit
, e isso provavelmente funcionaria. Mas:Em vez disso, você pode usar uma das várias maneiras de devolver um valor nas Perguntas frequentes sobre o Bash . A maioria deles não é tão boa, infelizmente. Você pode apenas ficar parado procurando erros após cada chamada de função (
-e
tem muitos problemas ). Ou isso, ou mude para Perl.fonte
Você pode decidir que o status de saída 77, por exemplo, significa sair de qualquer nível de subcamação e
set -E
em combinação com asERR
armadilhas é um pouco como uma versão aprimorada,set -e
na medida em que permite definir seu próprio tratamento de erros.No zsh, os traps de ERR são herdados automaticamente; portanto, você não precisa
set -E
, também pode definir traps comoTRAPERR()
funções e modificá-los através$functions[TRAPERR]
, comofunctions[TRAPERR]="echo was here; $functions[TRAPERR]"
fonte
kill $$
.echo "$(exit 77)"
; o script continuará como se tivéssemos escrito #echo ""
Como alternativa
kill $$
, você também pode tentarkill 0
, funcionará no caso de subcascas aninhadas (todos os chamadores e processos secundários receberão o sinal) ... mas ainda é brutal e feio.fonte
Tente isso ...
Os resultados que recebo são ...
Notas
if
teste sejatrue
oufalse
(veja as 2 execuções)if
teste é realizadofalse
, nunca alcançamos o subshell.fonte
(Resposta específica do Bash) O Bash não tem conceito de exceções. No entanto, com set -o errexit (ou o equivalente: set -e) no nível mais externo, o comando com falha resultará na saída do subshell com um status de saída diferente de zero. Se este for um conjunto de subshells aninhados sem condicionais em torno da execução desses subshells, ele efetivamente 'acumulará' todo o script e sairá.
Isso pode ser complicado ao tentar incluir bits de vários códigos bash em um script maior. Um pedaço do bash pode funcionar muito bem por si só, mas quando executado sob errexit (ou sem errexit), se comporta de maneiras inesperadas.
fonte
Meu exemplo para sair em um forro:
fonte