O código a seguir fará com que a instrução 'if' saia antecipadamente e não execute o comando 'echo' no bloco 'if'. Estou me perguntando por que isso acontece apenas no bloco 'if', mas não na parte principal do script. Observação: entendo que alterar ':=' para ':-' resolverá o problema - não estou procurando corrigir o problema, estou procurando entender a diferença entre o ambiente de execução do bloco 'if' que faz com que isso aconteça em primeiro lugar.
#!/bin/bash
if true; then
VAR=${$1:='val'}
echo "This does not run"
fi
VAR=${$1:='val'}
echo "This does run"
A saída é
line 4: ${$1:='val'}: bad substitution
line 7: ${$1:='val'}: bad substitution
This does run
Novamente - não estou interessado em corrigir a mensagem de erro de substituição incorreta, entendo como fazer isso e por que isso acontece. O que eu quero entender é porque a echo "This does not run"
linha não roda quando há uma substituição ruim acima dela em um bloco 'if'.
Reproduzido nas seguintes versões bash:
GNU bash, versão 5.1.16(1)-release (x86_64-pc-linux-gnu)
GNU bash, versão 4.2.46(2)-release (x86_64-redhat-linux-gnu)
Como Kusalananda apontou nos comentários, isso é essencialmente o mesmo descrito na configuração das opções do Bash em um comando composto .
Da referência do Bash :
O bloco na
if
instrução é um comando composto e possui um erro de expansão, ou sejaVAR=${$1:='val'}
, , portanto, todo o bloco falha, a etapa 6 nunca é alcançada e a primeiraecho
nunca é executada.Observe que esse tratamento específico de erros de expansão viola o padrão POSIX, que na seção 2.8.1 diz que um erro de expansão deve sair de um shell não interativo .
No modo POSIX, o Bash opera de maneira compatível:
Para absolver Bash, esta violação é documentada :