O que significa "while:;"?

27

Eu sei o que é um whileloop. No entanto, eu só vi isso funcionar com:

while [condition]
while ![condition]
while TRUE (infinite loop)

Onde a declaração depois whiledeve ser TRUEou FALSE.

Há um comando interno do shell chamado :. É descrito como um comando fictício sem fazer nada, mas não sei se é o mesmo aqui, mesmo que possa ser TRUEou FALSE. Talvez seja algo diferente, mas o que?

tubarão
fonte
4
O comando :não faz nada, mas sempre sai com o código de retorno 0. Portanto, é o mesmo que era while true(assumindo que seu sistema possui um trueexecutável).
John1024
@ John1024 Retorna zero, a menos que a avaliação de seus argumentos cause um erro ao, por exemplo, atribuir um valor a uma variável somente leitura.
Kusalananda
3
@ Kusalananda Sim, se o :comando nunca for executado, ele não retornará 0. Isso é excessivamente pedante na minha opinião.
hvd 25/05

Respostas:

50

A sintaxe é:

while
  first list of commands
do
  second list of commands
done

que executa a segunda lista de comandos em um loop desde que a primeira lista de comandos (portanto, a última execução nessa lista) seja bem-sucedida.

Na primeira lista de comandos , você pode usar o [comando para fazer vários tipos de testes ou o :comando nulo que não faz nada e retorna sucesso, ou qualquer outro comando.

while :; do cmd; done

Corre cmdrepetidamente para sempre, como :sempre retorna sucesso. Esse é o laço eterno . Você poderia usar o truecomando para torná-lo mais legível:

while true; do cmd; done

As pessoas costumavam preferir o :que :sempre foi construído, enquanto truenão era (há muito tempo; a maioria das conchas já foi trueconstruída hoje em dia) ¹.

Outras variantes que você pode ver:

while [ 1 ];  do cmd; done

Acima, chamamos o [comando para testar se a sequência "1" não está vazia (portanto, sempre também verdadeira)

while ((1)); do cmd; done

Usando a ((...))sintaxe Korn / bash / zsh para imitar o while(1) { ...; }de C.

Ou as mais complicadas gosto until false; do cmd; done, until ! true...

Às vezes, esses são apelidos como:

alias forever='while :; do'

So you can do something like:

forever cmd; done

Poucas pessoas percebem que a condição é uma lista de comandos. Por exemplo, você vê pessoas escrevendo:

while :; do
  cmd1
  cmd2 || break
  cmd3
done

Quando eles poderiam ter escrito:

while
  cmd1
  cmd2
do
  cmd3
done

Faz sentido que seja uma lista, pois muitas vezes você também deseja fazer coisas como while cmd1 && cmd2; do...; donelistas de comandos.

De qualquer forma, observe que [é um comando como outro qualquer (embora esteja embutido em shells modernos do tipo Bourne), ele não precisa ser usado apenas nas listas de condições if/ while/ untile essas listas de condições não têm para usar esse comando mais do que qualquer outro comando.


Also :também é mais curto e aceita argumentos (que são ignorados). Enquanto o comportamento de trueou falsenão for especificado, se você passar algum argumento. Então, pode-se fazer, por exemplo:

while : you wait; do
  something
done

Mas, o comportamento de:

until false is true; do
  something
done

não é especificado (embora funcione na maioria das shell / falseimplementações).

Stéphane Chazelas
fonte
12

while :é um loop infinito. :simplesmente não faz nada (com sucesso).

Portanto, se você deseja que seu shell fique pendurado para sempre sem fazer nada, você pode escrevê-lo como

while :
do
    :
done

Ou em uma única linha com, em ;vez de novas linhas:while :; do :; done

while :é geralmente usado se você deseja fazer algo repetidamente sem uma condição especial anexada. É possível utilizar continue, breakdeclarações dentro do circuito para controlar ou para mover a condição para o fim do laço como uma do ... whileconstruo.

frostschutz
fonte
12

no entanto, a declaração depois de um tempo deve ser VERDADEIRA ou FALSA.

Não, o comando na parte da condição pode ser qualquer comando (*) . Todos os comandos do shell têm algum valor de retorno, e o whileloop (assim como o ifcondicional) assume valores de retorno de zero como "true" e todos os outros como "false". (* ou uma lista de vários comandos, o último conta)

Quanto :, manual do Bash diz claramente que o status de retorno que é:

: [arguments]
Não faça nada além de expandir argumentos e executar redirecionamentos. O status de retorno é zero.

O helpbuiltin é ainda mais claro:

 $ help :
 [...]
 No effect; the command does nothing
 Exit Status:
 Always succeeds.
ilkkachu
fonte
s/any command/any sequence of commands/, como Stéphane deixa claro.
Toby Speight