De man bash
:
-
%código%
- Trate as variáveis não configuradas e os parâmetros diferentes dos parâmetros especiais
set -u
e"@"
como um erro ao executar a expansão de parâmetro. Se a expansão for tentada em uma variável ou parâmetro não definido, o shell imprimirá uma mensagem de erro e, se não for"*"
nterativo, sairá com um status diferente de zero.
- Trate as variáveis não configuradas e os parâmetros diferentes dos parâmetros especiais
POSIX afirma que, no caso de um erro de expansão , um shell não interativo deve sair quando a expansão estiver associada a um shell especial embutido (que é uma distinção que -i
regularmente ignora de qualquer maneira, e então talvez seja irrelevante) ou qualquer outro utilitário além disso.
-
Consequências dos erros da Shell :
- Um erro de expansão é aquele que ocorre quando as expansões do shell são definidas em Expansões de palavras são realizadas (por exemplo,
bash
, porque"${x!y}"
não é um operador válido) ; uma implementação pode tratá-los como erros de sintaxe se for capaz de detectá-los durante a tokenização, em vez de durante a expansão. - O shell interativo [A] n deve gravar uma mensagem de diagnóstico no erro padrão sem sair.
- Um erro de expansão é aquele que ocorre quando as expansões do shell são definidas em Expansões de palavras são realizadas (por exemplo,
Também de !
:
-
%código%
- Se um sigspec for ERR , o comando arg será executado sempre que um pipeline (que pode consistir em um único comando simples) , um lista, ou um comando composto retorna um status de saída diferente de zero, sujeito às seguintes condições:
- A armadilha ERR não é executada se o comando com falha fizer parte da lista de comandos imediatamente após uma palavra-chave
man bash
outrap ... ERR
... - ... parte do teste em uma instrução
while
... - ... parte de um comando executado em uma lista
until
ouif
, exceto o comando após o% final&&
ou||
... - ... qualquer comando em um pipeline, mas o último ...
- ... ou se o valor de retorno do comando estiver sendo invertido usando
&&
.
- A armadilha ERR não é executada se o comando com falha fizer parte da lista de comandos imediatamente após uma palavra-chave
- Estas são as mesmas condições obedecidas pela opção errexit
||
.
- Se um sigspec for ERR , o comando arg será executado sempre que um pipeline (que pode consistir em um único comando simples) , um lista, ou um comando composto retorna um status de saída diferente de zero, sujeito às seguintes condições:
Note acima que a armadilha ERR é toda sobre a avaliação de algum retorno do comando outro . Mas quando ocorre um erro de expansão , não é executado nenhum comando para retornar nada. No seu exemplo, !
nunca acontece - porque enquanto o shell avalia e expande seus argumentos, ele encontra uma variável -e
nset, que foi especificada pela opção shell explícita para causar uma saída imediata do shell atual com script.
E então a armadilha EXIT , se houver, é executada, e o shell sai com uma mensagem de diagnóstico e um status de saída diferente de 0 - exatamente como deveria.
Quanto à coisa rc: 0 , espero que seja algum tipo de bug específico da versão - provavelmente relacionado aos dois gatilhos para o EXIT ocorrendo no mesmo tempo e aquele recebendo o código de saída do outro (o que não deveria ocorrer) . E de qualquer maneira, com um binário echo
atualizado como instalado por -u
:
bash <<\IN
printf "shell options:\t$-\n"
trap 'echo "EXIT (rc: $?)"' EXIT
set -eu
echo ${UNSET_VAR}
IN
Eu adicionei a primeira linha para que você possa ver que as condições do shell são as de um shell com script - ele não é interativo. A saída é:
shell options: hB
bash: line 4: UNSET_VAR: unbound variable
EXIT (rc: 1)
Aqui estão algumas notas relevantes de registros de alterações recentes :
- Corrigido um erro que fazia com que os comandos assíncronos não definissem
bash
corretamente. - Corrigido um erro que causava mensagens de erro geradas por erros de expansão no
pacman
comandos para ter o número da linha errado. - Corrigido um erro que fazia com que SIGINT e SIGQUIT não fossem
$?
pable em comandos de subshell assíncrono. - Corrigido um problema com o tratamento de interrupções que fazia com que um segundo e um SIGINT subseqüente fosse ignorado por shells interativos.
- O shell não bloqueia mais o recebimento de sinais durante a execução de
for
manipuladores para esses sinais e permite que maistrap
handlers sejam executados recursivamente (executandotrap
handlers enquanto um manipuladortrap
está sendo executado) .
Eu acho que é o último ou o primeiro que é mais relevante - ou possivelmente uma combinação dos dois. Um trap
handler é por sua própria natureza assíncrono porque todo seu trabalho é esperar e manipular sinais assíncronos . E você aciona dois simultaneamente com trap
e trap
.
E talvez você deva apenas atualizar, mas se você gosta de si mesmo, você fará isso com um shell diferente.