Quel est le but du mot clé "do" dans Bash for Loops?

76

Quel est le but du domot clé dans la forsyntaxe de la boucle Bash ? Pour moi, cela me semble superflu.

for i in `seq 1 2`; do echo "hi"; done

Pourquoi la syntaxe n'est-elle pas comme ça?

for i in `seq 1 2`; echo "hi"; done

Je suis sûr qu'il ne remplir un but. Je veux juste apprendre.

Fredrik Johansson
la source

Réponses:

118

Notez que cette syntaxe est héritée du shell Bourne.

Après le nom de la variable, vous pouvez soit inavoir explicitement la liste des éléments, soit doparcourir les paramètres de position.

for i in 1 2 3
do
  echo "$i"
done

Ou

set 1 2 3
for i do
  echo "$i"
done

Avoir le dodans les deux cas (même si ce n'est pas strictement nécessaire dans le premier) rend la syntaxe plus cohérente. C'est également compatible avec les while/ untilboucles où le doest nécessaire.

while
  cmd1
  cmd2
do
  cmd3
  cmd4
done

Vous avez besoin de dopour savoir où se termine la liste des commandes de condition .

Notez que le shell Bourne ne prend pas en charge for i; do. Cette syntaxe n'était pas non plus POSIX jusqu'à l'édition 2016 de la norme (elle for i doa toujours été POSIX; voir le bogue lié au groupe Austin ).

zsh a quelques formes abrégées comme:

for i in 1 2 3; echo $i
for i (1 2 3) echo $i
for ((i=1;i<=3;i++)) echo $i

Ou prendre en charge plusieurs variables:

for i j (1 a 2 b) echo $i $j

(bien que vous ne puissiez pas utiliser inou docomme nom de variable à la place de jci - dessus).

Même s'ils sont rarement documentés, la plupart des coquilles de type Bourne (Bourne, ksh, bash, zsh, not ashni yash) prennent également en charge:

for i in 1 2 3; { echo "$i";}

Le shell Bourne, kshet zsh(mais pas bash) prend également en charge:

for i { echo "$i"; }

Alors que bash( kshet zshpas le shell Bourne), le support:

for i; { echo "$i"; }

Tous (Bourne, bash, ksh, zsh) soutien:

for i
{ echo "$i";}

ksh93, bash, zshSoutien:

for ((i=1;i<=3;i++)) { echo "$i"; }
Stéphane Chazelas
la source
2
Comme toujours, réponse complète et parfaite (avec une référence à zsh) ...
Kiwy
2
Ce n'est pas "strictement nécessaire" dans les deux cas for; la commande peut être terminée par une nouvelle ligne ou un point-virgule. Cela fait un peu plus sens pour if/ while(le premier avec thenplutôt que do), mais en principe, ceux-ci auraient pu l'omettre et nécessiter un sous-shell ou des accolades pour l'utilisation (rare) de plusieurs commandes. Je soupçonne que la véritable raison pour laquelle Bourne Shell le fait est qu’ALGOL le fait, et nous devrions nous réjouir de ne donepas l’épeler od.
Random832
4
@ Random832: C'est parce qu'il oda déjà été utilisé comme nom du programme Octal Dump.
user1024
8
Il y a tellement de choses que je ne savais pas. Je vous remercie!
Courses de légèreté avec Monica
1
@mirabilos, for i doest Bourne et POSIX, mais ne fonctionnera pas dans certaines anciennes versions de shells IIRC à base de cendres. for i in "$@"ne fonctionnera pas dans le shell Bourne si $IFSne contient pas le caractère espace. for i<newline>doest en effet le plus portable si vous devez prendre en compte de très vieux systèmes BSD. Voir in-ulm.de/~mascheck/various/bourne_args pour plus de détails
Stéphane Chazelas