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;