¿Qué significa "while:;"?

27

Sé lo que es un whilebucle. Sin embargo, solo lo he visto funcionar con:

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

Donde la declaración posterior whiletiene que ser TRUEo FALSE.

Hay un comando incorporado de shell llamado :. Se describe como un comando ficticio que no hace nada, pero no sé si es lo mismo aquí, incluso si puede ser TRUEo FALSE. Quizás es algo diferente, pero ¿qué?

Sharkant
fuente
44
El comando :no hace nada pero siempre sale con el código de retorno 0. Por lo tanto, es lo mismo while true(suponiendo que su sistema tenga un trueejecutable).
John1024
@ John1024 Devuelve cero a menos que la evaluación de sus argumentos provoque un error, por ejemplo, al asignar un valor a una variable de solo lectura.
Kusalananda
3
@Kusalananda Sí, si el :comando nunca se ejecuta, no devolverá 0. Sin embargo, eso es demasiado pedante en mi opinión.
hvd

Respuestas:

50

La sintaxis es:

while
  first list of commands
do
  second list of commands
done

que ejecuta la segunda lista de comandos en un bucle siempre que la primera lista de comandos (por lo que la última ejecución de esa lista) sea exitosa.

En esa primera lista de comandos , puede usar el [comando para hacer varios tipos de pruebas, o puede usar el :comando nulo que no hace nada y devuelve el éxito, o cualquier otro comando.

while :; do cmd; done

Corre cmduna y otra vez para :siempre como siempre devuelve el éxito. Ese es el ciclo para siempre . En su lugar, podría usar el truecomando para hacerlo más legible:

while true; do cmd; done

La gente solía preferir :como :siempre se construyó mientras que trueno se hizo (hace mucho tiempo; la mayoría de las conchas se han trueconstruido hoy en día) ¹.

Otras variantes que puede ver:

while [ 1 ];  do cmd; done

Arriba, llamamos al [comando para probar si la cadena "1" no está vacía (por lo que siempre es así también)

while ((1)); do cmd; done

Usando la ((...))sintaxis de Korn / bash / zsh para imitar la while(1) { ...; }de C.

O más contorneados aquellos como until false; do cmd; done, until ! true...

Esos a veces tienen alias como:

alias forever='while :; do'

Entonces puedes hacer algo como:

forever cmd; done

Pocas personas se dan cuenta de que la condición es una lista de comandos. Por ejemplo, ves personas escribiendo:

while :; do
  cmd1
  cmd2 || break
  cmd3
done

Cuando podrían haber escrito:

while
  cmd1
  cmd2
do
  cmd3
done

Tiene sentido que sea una lista, ya que a menudo también quieres hacer cosas como while cmd1 && cmd2; do...; donelas listas de comandos.

En cualquier caso, tenga en cuenta que [es un comando como cualquier otro (aunque está integrado en los shells modernos tipo Bourne), no tiene que usarse únicamente en las listas de condiciones if/ while/ until, y esas listas de condiciones no tienen usar ese comando más que cualquier otro comando.


¹ :también es más corto y acepta argumentos (que ignora). Si bien el comportamiento de trueo falseno se especifica si le pasa algún argumento. Entonces uno puede hacer, por ejemplo:

while : you wait; do
  something
done

Pero, el comportamiento de:

until false is true; do
  something
done

no está especificado (aunque funcionaría en la mayoría de las falseimplementaciones / shell ).

Stéphane Chazelas
fuente
12

while :Es un bucle infinito. :simplemente no hace nada (con éxito).

Entonces, si desea que su caparazón se cuelgue para siempre sin hacer nada, puede escribirlo como

while :
do
    :
done

O en una sola línea con en ;lugar de nuevas líneas:while :; do :; done

while :se usa generalmente si desea hacer algo repetidamente sin una condición especial adjunta. Es posible utilizar continue, breakdeclaraciones dentro del bucle de controlarlo o para mover la condición al final del bucle como un do ... whileconstructo.

Frostschutz
fuente
12

sin embargo, la declaración después de while debe ser VERDADERA o FALSA.

No, el comando en la parte de condición puede ser cualquier comando (*) . Todos los comandos de shell tienen algún valor de retorno, y el whilebucle (así como el ifcondicional) toma los valores de retorno de cero como "verdadero", y todos los demás como "falso". (* o una lista de varios comandos, el último cuenta)

En cuanto a :, el manual de Bash dice claramente cuál es el estado de devolución de eso:

: [arguments]
No haga nada más que expandir argumentos y realizar redireccionamientos. El estado de retorno es cero.

La helpconstrucción es aún más clara:

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