string nula como comando em while loop: empty / null-command

5

Eu estou querendo saber como o loop while avalia sua condição de loop. Na página man está escrito:

while list-1; do list-2; done

The while command continuously executes the list list-2 as long as the last command in the list list-1 returns an exit status of zero.

e

Lists

A list is a sequence of one or more pipelines separated by one of the operators ;, &, &&, or ||, and optionally terminated by one of ;, &, or .

e

Pipelines

A pipeline is a sequence of one or more commands separated by one of the control operators | or |&. The format for a pipeline is:

         [time [-p]] [ ! ] command [ [|⎪|&] command2 ... ]

Isso significa:

while <single-command>; do <list>; done;

é uma sintaxe válida. A lista é executada contanto que <single-command> retorne 0 . Se eu executar um loop while, assim, obtenho (obviamente) erros:

$while aaa; do echo "foo"; done;
If 'aaa' is not a typo you can use command-not-found to lookup the package that contains it, like this:
cnf aaa

$while ; do echo "foo"; done;
Absolute path to '' is '/usr/sbin/', so running it may require superuser privileges (eg. root).

$while ""; do echo "foo"; done;
Absolute path to '' is '/usr/sbin/', so running it may require superuser privileges (eg. root).

Para minha surpresa, usando uma variável unitializada bar as <single-command> , eu me deparo com um loop infinito:

$while $bar; do echo "foo"; done;
foo
foo
foo
...

Isso significa que bar é expandido por parâmetro para uma string vazia (?), é executado (?) e sempre retorna 0. Mas por que meu segundo exemplo de erro funciona de maneira equivalente? ? Curiosamente:

$while "$bar"; do echo "foo"; done;
Absolute path to '' is '/usr/sbin/', so running it may require superuser privileges (eg. root).

não funciona. Isso é equivalente ao meu terceiro exemplo de erro. $ bar é expandida para uma string vazia e aspas sem escape permanecem.

Então, minha pergunta é: Como o shell (bash no meu caso) interpreta o

$while $bar; do echo "foo"; done;

comando que resulta em um loop infinito?

Atualizar :

Descobri que o comando null (não faz nada, retorna 0) não é tão difícil de simular. O comando nulo corresponde a : . Portanto, o loop não-finalizante pode ser escrito de forma equivalente como:

while :; do echo "foo"; done;
    
por FloHe 22.01.2017 / 15:41

1 resposta

2

A instrução while é seguida pelo comando do qual avaliar o código de retorno para determinar se deve ou não fazer loop. Ele prossegue se o valor de retorno for 0 .

A referência a uma variável não inicializada é idêntica a tê-la inicializada como ''.

Como a execução de um comando vazio não causa erros, ele retorna o código de retorno correspondente ( 0 ):

$ foo=''
$ $foo
$ echo $?
0

Esse é um comportamento normal, já que o shell teria um erro toda vez que você pressionar enter sem digitar nada.

Observe que isso é diferente de especificar uma string vazia que o shell identifica como um problema:

$ ''
-bash: : command not found
$ echo $?
127
    
por 22.01.2017 / 16:57

Tags