Respostas:
Colchetes simples no shell é sinônimo de test
(comando separado ou interno do shell), portanto [ 0 ]
significa a mesma coisa que test 0
. test
é para fazer comparações e testar os atributos dos arquivos, como você pode ler em sua página de manual. Quando não recebe uma expressão que se parece com uma comparação, teste de arquivo ou uma das outras operações que pode ser executada, ela testará se o argumento está presente e uma sequência não vazia. Nem 0
ou 1
são entradas realmente apropriados para o teste, e como strings não vazias teste simplesmente sucede e seu loop while loop para sempre.
Você pode tentar
while false; do
echo "hello"
done
possivelmente substituindo false
por true
. Ou talvez o que você queira seja usar (( ))
:
while (( 0 )); do
echo "hello"
done
Que se comportará como a maioria dos idiomas, onde 0 significa falha / falso e 1 significa sucesso / verdadeiro.
0
e 1
não forem strings vazias. Novos programadores shell muitas vezes escrever if [ 1=2 ]
em vez de if [ 1 = 2 ]
e admira por isso que o primeiro é sempre verdadeiro. É verdade porque é um argumento único e não é uma string vazia.
O valor 0 aqui não está atuando como uma constante numérica, mas como uma sequência de caracteres. Esses testes são todos equivalentes no efeito de produzir um status de finalização bem-sucedido:
[ A ]
[ "XYZ" ]
[ 0 ]
estes produzem um status de terminação com falha:
[ ]
[ "" ]
existe um argumento não em branco, que avalia como verdadeiro lógico. Isso permite que você faça coisas como:
if [ $UNDER_NUCLEAR_ATTACK ] ; then
launch-missiles -a $DRY_RUN # $DRY_RUN set to "-n" during testing
fi
A variável UNDER_NUCLEAR_ATTACK
é configurada para qualquer valor que não esteja em branco para indicar true ou está desabilitada ou vazia para indicar false.
Podemos aplicar o !
operador para reverter a lógica:
[ ! a ] # fails: a is nonblank so true; and not true is false.
[ ! ] # succeeds: blank is false, not blank is true.
Para avaliar uma condição numérica, você deve usar operadores de teste numérico:
while [ $A -gt $B ] ; do ...
Se A
e B
contiverem seqüências de caracteres que pareçam números inteiros decimais, elas serão comparadas como números e, se A
for maior que B
, o loop será executado. Portanto, suponha que UNDER_NUCLEAR_ATTACK
não seja um booleano do tipo string que esteja em branco ou não em branco, mas na verdade um booleano numérico que seja 0
(false) ou algum outro valor (true). Nesse caso, escreveríamos o teste assim:
if [ $UNDER_NUCLEAR_ATTACK -ne 0 ] ; then ...
Uma construção if / then testa se o status de saída de uma lista de comandos é 0 (já que 0 significa "sucesso" pela convenção UNIX) e, nesse caso, executa um ou mais comandos.
Em resumo, você está retornando um resultado de teste igual a zero.
[
obtiver apenas um argumento (excluindo o ]
, é claro), ele sairá com status zero se o argumento não estiver vazio, diferente de zero se estiver. Então, por exemplo, [ 1 ]
também retornará um código de saída de 0
.
O valor 0 é considerado como verdadeiro para o loop while, portanto, a condição para o loop while é verdadeira e, portanto, continua a mostrar o loop infinito. O é verdadeiro se substituirmos 0 por 1, pois qualquer número inteiro que escrevermos entre a condição retornará verdadeiro
[ ]
(sem argumento) e[ "" ]
(com um único argumento vazio) não obtêm êxito.