Estou aprendendo a usar com eficiência diferentes set
opções em meu script e encontrei set -u
que parece ser perfeito para sair do meu script se uma variável não for configurada corretamente (por exemplo, excluir usuários). De acordo com a página man , set -u
e set -e
faz o seguinte …
-e Exit immediately if a command exits with a non-zero status. -u Treat unset variables as an error when substituting.
Criei um script de teste para testar esta funcionalidade, mas não parece estar funcionando como esperado . Talvez alguém pudesse explicar melhor meu problema para mim e onde estou interpretando mal? O script de teste está abaixo. Obrigado.
set -e set -u testing="This works" echo $? echo ${testing} testing2= echo $? echo ${testing2} testing3="This should not appear" echo $? echo ${testing3}
Espero que o script exiba 0 e “Isso funciona” e falha porque ${testing2}
é não definido.
Em vez disso, sou exibido 0 e “Isso funciona” , seguido por 0 e então 0 Isso não deve aparecer
Alguém pode fornecer algum conhecimento? Obrigado.
Comentários
- Então, continuação … há alguma maneira de tornar ilegal a configuração de uma variável como string nula / gerar um erro? Eu ' suponho que não.
Resposta
De ” man Bash “:
Um parâmetro é definido se tiver sido atribuído um valor. A string nula é um valor válido. Depois que uma variável é definida, ela pode ser removida apenas usando o comando interno unset.
Quando você faz testing2=
você está definindo a variável como string nula.
Altere para unset testing2
e tente novamente.
O set -e
não ajuda neste caso, pois uma atribuição nunca tem um código de saída 1. Tente isso para ver se o último comando executado (a atribuição) tem um código de saída 0, ou leia esta pergunta :
$ false; a=""; echo $? 0
E também acredito que o uso de set -e é mais um problema do que uma solução.
O que pode gerar um erro com o uso de variáveis não definidas é set -u
:
#!/bin/bash set -u testing="This works" echo ${testing} unset testing2 echo ${testing2} testing3="This should not appear" echo ${testing3}
Irá gerar:
$ ./script.sh This works ./script.sh: line 9: testing2: unbound variable
Resposta
testing2=
define a variável testing2
como uma string vazia; a variável realmente está definida .
No entanto, se você executasse echo $testing99
em um shell Bash interativo (sem definir errexit
, ou seja, set -e
), você obteria um erro:
bash: testing99: unbound variable
À parte
Ao testar scripts agora, descobri que um shell interativo nem sempre sai ao tentar expandir uma variável que não foi definida enquanto um shell não interativo (executando um script de shell) sempre sai de . De acordo com a página do manual POSIX para set
:
-u O shell deve escrever uma mensagem de erro padrão quando tenta expandir uma variável que não está configurada e sai imediatamente. Um shell interativo não deve sair.
Um shell Bash interativo não sairá a menos que errexit
tenha também foi definido. Por outro lado, um shell de traço interativo não sairá – mesmo se set -e
tiver sido executado anteriormente.
Comentários
- Se o traço não sair com set -e; set -u; não definido aa; echo $ aa, então o traço está errado.
- @schily Quando percebi isso pela primeira vez, percebi que os autores do traço sabiam melhor do que eu e que pode ter havido alguma ambiguidade nas especificações POSIX, mas tendo verificado pubs.opengroup.org/onlinepubs/9699919799/utilities/… , concordo que parece um bug, certo.
- Há uma regra simples: quando o Korn Shell e o Bourne Shell concordam e outra implementação do shell tem um desvio, o outro shell se comporta incorretamente.