Que veut dire «while:;»?

27

Je sais ce qu'est une whileboucle. Cependant, je ne l'ai vu que fonctionner avec:

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

Où la déclaration suivante whiledoit être soit TRUEou FALSE.

Il existe une commande intégrée au shell nommée :. Il est décrit comme une commande factice ne faisant rien, mais je ne sais pas si c'est la même chose ici, même si cela peut être TRUEou FALSE. C'est peut-être quelque chose de différent, mais quoi?

sharkant
la source
4
La commande :ne fait rien mais quitte toujours avec le code retour 0. Donc, c'est la même chose while true(en supposant que votre système a un trueexécutable).
John1024
@ John1024 Il renvoie zéro sauf si l'évaluation de ses arguments provoque une erreur, par exemple en affectant une valeur à une variable en lecture seule.
Kusalananda
3
@Kusalananda Oui, si la :commande n'est jamais exécutée, elle ne retournera pas 0. C'est trop pédant à mon avis cependant.
hvd

Réponses:

50

La syntaxe est:

while
  first list of commands
do
  second list of commands
done

qui exécute la deuxième liste de commandes dans une boucle tant que la première liste de commandes (donc la dernière exécution de cette liste) réussit.

Dans cette première liste de commandes , vous pouvez utiliser la [commande pour effectuer différents types de tests, ou vous pouvez utiliser la :commande null qui ne fait rien et renvoie le succès, ou toute autre commande.

while :; do cmd; done

S'exécute cmdencore et encore pour :toujours comme toujours le succès. C'est la boucle pour toujours . Vous pouvez utiliser la truecommande à la place pour la rendre plus lisible:

while true; do cmd; done

Les gens préféraient ce :qui :était toujours intégré alors que ce truen'était pas le cas (il y a longtemps; la plupart des obus sont trueintégrés de nos jours) ¹.

D'autres variantes que vous pourriez voir:

while [ 1 ];  do cmd; done

Ci-dessus, nous appelons la [commande pour tester si la chaîne "1" n'est pas vide (donc toujours aussi vraie)

while ((1)); do cmd; done

Utilisation de la ((...))syntaxe Korn / bash / zsh pour imiter le while(1) { ...; }C.

Ou des plus alambiqués comme until false; do cmd; done, until ! true...

Ceux-ci sont parfois aliasés comme:

alias forever='while :; do'

Vous pouvez donc faire quelque chose comme:

forever cmd; done

Peu de gens réalisent que la condition est une liste de commandes. Par exemple, vous voyez des gens écrire:

while :; do
  cmd1
  cmd2 || break
  cmd3
done

Quand ils auraient pu écrire:

while
  cmd1
  cmd2
do
  cmd3
done

Il est logique que ce soit une liste car vous voulez souvent faire des choses comme des while cmd1 && cmd2; do...; donelistes de commandes.

Dans tous les cas, notez qu'il [s'agit d'une commande comme les autres (bien qu'elle soit intégrée dans des shells modernes de type Bourne), elle ne doit pas être utilisée uniquement dans les listes de conditions if/ while/ until, et ces listes de conditions n'ont pas d'utiliser cette commande plus que toute autre commande.


¹ :est également plus court et accepte les arguments (qu'il ignore). Alors que le comportement de trueou falsen'est pas spécifié si vous lui passez un argument. On peut donc faire par exemple:

while : you wait; do
  something
done

Mais, le comportement de:

until false is true; do
  something
done

n'est pas spécifié (bien qu'il fonctionnerait dans la plupart des shell / falseimplémentations).

Stéphane Chazelas
la source
12

while :est une boucle infinie. :ne fait rien (avec succès).

Donc, si vous voulez que votre shell se bloque pour toujours sans rien faire, vous pouvez l'écrire comme

while :
do
    :
done

Ou en une seule ligne avec ;au lieu de nouvelles lignes:while :; do :; done

while :est généralement utilisé si vous voulez faire quelque chose à plusieurs reprises sans condition spéciale attachée. Vous pourriez utilisercontinue , breakinstructions dans la boucle pour contrôler ou pour déplacer la condition à la fin de la boucle comme une do ... whileconstruction.

frostschutz
la source
12

cependant, l'instruction après while doit être TRUE ou FALSE.

Non, la commande dans la partie condition peut être n'importe quelle commande (*) . Toutes les commandes shell ont une valeur de retour et la whileboucle (ainsi que laif conditionnel) prend les valeurs de retour de zéro comme "vrai" et toutes les autres comme "fausses". (* ou une liste de plusieurs commandes, la dernière compte)

Quant à :, le manuel de Bash indique clairement quel est le statut de retour de celui-ci:

: [arguments]
Ne faites rien d'autre que d'étendre les arguments et d'effectuer des redirections. Le statut de retour est zéro.

L' helpintégration est encore plus claire:

 $ help :
 [...]
 No effect; the command does nothing
 Exit Status:
 Always succeeds.
ilkkachu
la source
s/any command/any sequence of commands/, comme le précise Stéphane.
Toby Speight