set -u uso não funciona como esperado

7

Estou aprendendo a usar de forma eficiente diferentes opções set no meu script e me deparei com set -u que parece perfeito para sair do meu script se uma variável não for definida corretamente (por exemplo, excluindo usuários). De acordo com a página man , set -u e set -e fazem o seguinte ...

-e  Exit immediately if a command exits with a non-zero status.
-u  Treat unset variables as an error when substituting.

Eu criei um script de teste para testar essa funcionalidade, mas parece que não está funcionando como esperado. Talvez alguém possa explicar melhor o 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, em seguida, falhe porque ${testing2} não está definido.

Em vez disso, são exibidos 0 e "Isso funciona" , seguido por 0 e, em seguida, 0 Isso não deve aparecer

Alguém pode fornecer algum conhecimento? Obrigado.

    
por bluerojo 08.03.2016 / 20:23

2 respostas

6

De "man Bash":

A parameter is set if it has been assigned a value. The null string is a valid value. Once a variable is set, it may be unset only by using the unset builtin command.

Quando você executa testing2= , está definindo a variável como a string nula.

Altere isso para unset testing2 e tente novamente.

O set -e não ajuda nesse caso, já que uma atribuição nunca possui um código de saída 1. Tente isso para ver que o último comando executado (a atribuição) tem um código de saída 0 ou levou esta questão :

$ false; a=""; echo $?
0

E eu também acredito que o uso do set -e é mais um problema 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}

A saída será:

$  ./script.sh
This works
./script.sh: line 9: testing2: unbound variable
    
por 08.03.2016 / 20:34
3

testing2= define a variável testing2 como uma string vazia; a variável na verdade é definida .

No entanto, se você executasse echo $testing99 em um shell Bash interativo (sem definir errexit , ou seja, set -e ), você receberia um erro:

bash: testing99: unbound variable

Aparte

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 acordo com a página man do POSIX para set :

-u The shell shall write a message to standard error when it tries to expand a variable that is not set and immediately exit. An interactive shell shall not exit.

Um shell Bash interativo não sairá, a menos que errexit tenha também sido definido. Por outro lado, um painel de controle interativo não sairá, mesmo que set -e tenha sido executado anteriormente.

    
por 08.03.2016 / 20:32