Eu tenho um script de shell com loops aninhados e descobri que "exit" realmente não sai do script, mas apenas o loop atual. Existe outra maneira de sair completamente do script em uma determinada condição de erro?
Eu não quero usar "set -e", porque há erros aceitáveis e isso exigiria muita reescrita.
No momento, estou usando o kill para matar manualmente o processo, mas parece que deve haver uma maneira melhor de fazer isso.
bash -c 'for x in y z; do exit; done; echo "This never gets printed"'
.Respostas:
Seu problema não é loops aninhados, por si só. É que um ou mais dos seus loops internos estão sendo executados em um subshell .
Isso funciona:
resultado:
Isso apresenta o problema que você descreveu:
resultado:
Aqui está a solução; você precisa testar o valor de retorno dos loops internos que são executados em subshells:
Observe o teste:
[[ $? != 0 ]] && exit $?
resultado:
Editar: para verificar em que subshell você está, modifique o script "answer" para informar qual é o ID do processo do seu shell atual. NOTA: Isso funciona apenas no bash 4:
resultado:
As variáveis "i" e "j" trazidas a você são cortesia da Fortran. Tenha um bom dia. :-)
fonte
bash --version
na linha de comando.Uma resposta anterior sugere o uso
[[ $? != 0 ]] && exit $?
no entanto isso não vai muito trabalho como esperado, porque o[[ $? != 0 ]]
teste irá repor$?
a zero, o que significa que, embora o script early-saída como esperado, vai sempre sair com o código 0 (como não se espera) . Além disso, seria melhor usar o-ne
teste de comparação numérica, em vez do!=
teste de comparação de cadeias. Portanto, IMHO, uma solução melhor é usar:pois isso garantirá que o código de saída real esteja definido corretamente.
fonte
Você pode usar
break
.De
help break
:Portanto, para sair de três loops anexos, ou seja, se você tiver dois loops aninhados dentro do principal, use isso para sair de todos eles:
fonte
for((i=0;i<3;i++));do echo A;for((j=0;j<2;j++));do echo B;break 2;done;done
exit
finaliza o shell inteiro ou o sub shell atual:fonte