Wozu dient das Schlüsselwort "do" in Bash for loops?

76

Wozu dient das doSchlüsselwort in der Bash- forLoop-Syntax? Für mich fühlt es sich überflüssig an.

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

Warum ist die Syntax nicht so?

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

Ich bin sicher, dass es einen Zweck erfüllt . Ich will nur lernen.

Fredrik Johansson
quelle

Antworten:

118

Beachten Sie, dass diese Syntax von der Bourne-Shell geerbt wird.

Nach dem Variablennamen müssen Sie entweder indie Liste der Elemente explizit angeben lassen oder dodie Positionsparameter durchlaufen.

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

Oder

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

Das Haben doin beiden Fällen (auch wenn es in dem ersten nicht unbedingt notwendig ist) sorgt für eine konsistente Syntax. Es stimmt auch mit den while/ untilSchleifen überein, in denen das donotwendig ist.

while
  cmd1
  cmd2
do
  cmd3
  cmd4
done

Sie müssen doangeben, wo die Liste der Bedingungsbefehle endet.

Beachten Sie, dass die Bourne-Shell nicht unterstützt for i; do. Diese Syntax war auch erst in der Ausgabe 2016 des Standards for i doPOSIX (war schon immer POSIX; siehe den entsprechenden Fehler in der Austin-Gruppe ).

zsh hat ein paar Kurzformen wie:

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

Oder Unterstützung für mehr als eine Variable:

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

(obwohl Sie inoder nicht doals Variablennamen anstelle von joben verwenden können).

Obwohl selten dokumentiert, unterstützen die meisten Bourne-ähnlichen Shells (Bourne, ksh, bash, zsh, weder ashnoch yash) auch:

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

Die Bourne-Shell kshund zsh(aber nicht bash) auch:

for i { echo "$i"; }

Während bash, kshund zsh(aber nicht die Bourne - Shell) Unterstützung:

for i; { echo "$i"; }

All (Bourne, bash, ksh, zsh) Unterstützung:

for i
{ echo "$i";}

ksh93, bash, zshUnterstützung:

for ((i=1;i<=3;i++)) { echo "$i"; }
Stéphane Chazelas
quelle
2
Wie immer vollständige und perfekte Antwort (mit einem Verweis auf zsh) ...
Kiwy
2
Es ist in beiden Fällen nicht "unbedingt erforderlich" für for; Der Befehl kann durch eine neue Zeile oder ein Semikolon beendet werden. Es ist ein bisschen sinnvoller für if/ while(erstere theneher mit als do), aber im Prinzip hätten diese es weglassen und eine Unterschale oder geschweifte Klammern für die (seltene) Verwendung mehrerer Befehle benötigen können. Ich vermute, der wahre Grund, warum die Bourne-Shell dies tut, ist, dass ALGOL dies tut, und wir sollten froh sein, dass donedas nicht geschrieben ist od.
Random832
4
@ Random832: Das liegt daran, dass odbereits der Name des Octal Dump-Programms verwendet wurde.
user1024
8
Es gibt so viel hier, was ich nicht wusste. Danke!
Leichtigkeitsrennen im Orbit
1
@mirabilos for i doist Bourne und POSIX, funktioniert aber in einigen alten Versionen von aschebasierten IIRC-Shells nicht. for i in "$@"funktioniert in der Bourne-Shell nicht, wenn $IFSdas Leerzeichen nicht enthalten ist. for i<newline>doist in der Tat am portabelsten, wenn Sie sehr alte BSD-Systeme berücksichtigen müssen. Siehe in-ulm.de/~mascheck/various/bourne_args für Details
Stéphane Chazelas