Jaki jest cel słowa kluczowego „do” w Bash dla pętli?

76

Jaki jest cel tego dosłowa kluczowego w forskładni pętli Bash ? Dla mnie jest to zbędne.

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

Dlaczego taka składnia nie jest taka?

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

Jestem pewien, że spełnia swój cel. Chcę się tylko uczyć.

Fredrik Johansson
źródło

Odpowiedzi:

118

Zauważ, że ta składnia jest dziedziczona z powłoki Bourne'a.

Po nazwie zmiennej możesz mieć albo injawnie podaną listę elementów, albo dozapętlić parametry pozycyjne.

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

Lub

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

Posiadanie dow obu przypadkach (nawet jeśli nie jest to absolutnie konieczne w pierwszym), zapewnia bardziej spójną składnię. Jest również zgodny z pętlami while/, w untilktórych dojest to konieczne.

while
  cmd1
  cmd2
do
  cmd3
  cmd4
done

Musisz dopowiedzieć, gdzie kończy się lista poleceń warunkowych .

Pamiętaj, że powłoka Bourne'a nie była obsługiwana for i; do. Ta składnia nie była również POSIX do czasu wydania standardu 2016 ( for i dozawsze był POSIX; patrz powiązany błąd grupy Austin ).

zsh ma kilka krótszych form, takich jak:

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

Lub wsparcie dla więcej niż jednej zmiennej:

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

(chociaż nie można użyć inlub dojako nazwy zmiennej zamiast jpowyższego).

Nawet jeśli jest to rzadko udokumentowane, większość powłok podobnych do Bourne'a (Bourne, ksh, bash, zsh, not ashnor yash) również obsługuje:

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

Powłoka Bourne'a ( kshi zshnie bash) obsługuje również:

for i { echo "$i"; }

Chociaż bash, kshi zsh(ale nie Bourne shell) support:

for i; { echo "$i"; }

Wszystkie (Bourne, bash, ksh, zsh) wsparcie:

for i
{ echo "$i";}

ksh93, bash, zshSupport:

for ((i=1;i<=3;i++)) { echo "$i"; }
Stéphane Chazelas
źródło
2
Jak zawsze, kompletna i idealna odpowiedź (w odniesieniu do zsh) ...
Kiwy
2
W obu przypadkach nie jest to „absolutnie konieczne” for; polecenie może zostać zakończone znakiem nowej linii lub średnikiem. Ma to nieco więcej sensu dla if/ while(poprzedni z thenraczej niż do), ale w zasadzie mogliby go pominąć i potrzebować podpowłoki lub nawiasów klamrowych do (rzadkiego) używania wielu poleceń. Podejrzewam, że prawdziwym powodem, dla którego robi to powłoka Bourne'a, jest to, że robi to ALGOL, i powinniśmy się cieszyć, że donenie jest to napisane od.
Random832,
4
@ Random832: To dlatego, że odbył już używany jako nazwa programu Octal Dump.
user1024,
8
Jest tyle rzeczy, których nie wiedziałem. Dziękuję Ci!
Wyścigi lekkości na orbicie
1
@mirabilos, for i dojest Bourne i POSIX, ale nie będzie działać w niektórych starych wersjach powłok opartych na popiele IIRC. for i in "$@"nie będzie działać w powłoce Bourne'a, jeśli $IFSnie zawiera znaku spacji. for i<newline>dojest rzeczywiście najbardziej przenośny, jeśli chcesz wziąć pod uwagę bardzo stare systemy BSD. Szczegółowe informacje można znaleźć na stronie inulm.de/~mascheck/various/bourne_args
Stéphane Chazelas,