Por que o while [0] entra em loop infinito?

23

Eu vejo o mesmo comportamento abaixo do loop que o loop com while [ 1 ] . Por que isso acontece?

while [ 0 ]; do
    echo "hello"
done
    
por user13107 22.10.2013 / 03:35

4 respostas

33

Colchetes simples no shell é sinônimo de test (o comando separado ou o shell interno), portanto, [ 0 ] significa a mesma coisa que test 0 . test é para fazer comparações e testar os atributos dos arquivos, como você pode ler na manpage. Quando não é dada uma expressão que parece uma comparação, teste de arquivo ou uma das outras operações que ele pode fazer, ele irá testar se o argumento está presente e uma string não vazia. Nem 0 ou 1 são entradas realmente apropriadas para teste, e como o teste de cadeias não vazias simplesmente é bem-sucedido e o loop while executa loops para sempre.

Você pode tentar em vez disso

while false; do
  echo "hello"
done

possivelmente substituindo false por true . Ou talvez o que você queira é usar (( )) :

while (( 0 )); do
  echo "hello"
done

O que se comportará como a maioria dos idiomas, em que 0 significa falha / falsa e 1 significa sucesso / verdade.

    
por 22.10.2013 / 03:44
10

O valor 0 aqui não está atuando como uma constante numérica, mas como uma cadeia de caracteres. Esses testes são todos equivalentes em seu efeito de produzir um status de rescisão bem-sucedido:

[ A ]
[ "XYZ" ]
[ 0 ]

estes produzem um status de rescisão falho:

[ ]
[ "" ]

existe um argumento não em branco, que avalia como lógico verdadeiro. 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 não em branco para indicar true ou não está definida ou vazia para indicar false.

Podemos aplicar o operador ! para inverter 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ê precisa usar operadores de teste numérico:

 while [ $A -gt $B ] ; do ...

Se A e B contiverem cadeias com 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 seja vazio, mas na verdade um valor numérico booleano que seja 0 (false) ou algum outro valor (true). Nesse caso, nós escreveríamos o teste assim:

 if [ $UNDER_NUCLEAR_ATTACK -ne 0 ] ; then ...
    
por 22.10.2013 / 08:58
-1

An if/then construct tests whether the exit status of a list of commands is 0 (since 0 means "success" by UNIX convention), and if so, executes one or more commands.

Em suma, você está retornando um resultado de teste de zero.

link

    
por 22.10.2013 / 03:43
-1

O valor 0 é considerado como verdadeiro para o loop while, portanto, a condição para loop while é verdadeira e, portanto, contínua para mostrar o loop infinito. Isto é verdade se substituirmos 0 por 1, como qualquer inteiro que escrevermos entre a condição que retornará true

    
por 22.10.2013 / 06:05

Tags