Яка мета ключового слова "робити" в Bash для циклів?


76

Яке призначення doключового слова в forсинтаксисі циклу Баша ? Мені це здається зайвим.

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

Чому синтаксис не такий?

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

Я впевнений, що це справді заповнює мету. Я просто хочу вчитися.

Відповіді:


118

Зауважте, що цей синтаксис успадкований від оболонки Борна.

Після імені змінної, ви можете мати або inявно вказаний список елементів, або do, щоб перейти через позиційні параметри.

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

Або

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

Наявність doв обох випадках (навіть якщо це не є строго необхідним у першому) означає більш послідовний синтаксис. Він також відповідає while/ untilпетлям, де doце необхідно.

while
  cmd1
  cmd2
do
  cmd3
  cmd4
done

Вам потрібно doсказати, де закінчується список команд умови .

Зауважте, що оболонка Борна не підтримувала for i; do. Цей синтаксис також не був POSIX до випуску стандарту 2016 року ( for i doзавжди був POSIX; див . Відповідну помилку групи Austin ).

zsh має кілька скорочених форм, таких як:

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

Або підтримка декількох змінних:

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

(хоча замість вищесказаного ви не можете використовувати inабо doяк ім’я змінної j).

Навіть якщо це документально рідко задокументовано, більшість оболонок Борна (Bourne, ksh, bash, zsh, не ashні yash) також підтримують:

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

Оболонка Bourne kshта zsh(але не bash) також підтримують:

for i { echo "$i"; }

Хоча bash, kshі zsh(але не Bourne оболонки) підтримка:

for i; { echo "$i"; }

Всі (Bourne, bash, ksh, zsh) підтримка:

for i
{ echo "$i";}

ksh93, bash, zshПідтримка:

for ((i=1;i<=3;i++)) { echo "$i"; }

2
Як завжди, повна і досконала відповідь (із посиланням на zsh) ...
Kiwy

2
У будь-якому випадку це не "суворо необхідно" for; команда може бути закінчена новим рядком або крапкою з комою. Це має трохи більше сенсу для if/ while(колишній з, thenа не do), але в принципі ті, хто міг його опустити, вимагали підзарядки або дужок для (рідкісного) використання декількох команд. Я підозрюю справжню причину, що оболонка Борна робить це тому, що це робить ALGOL, і ми повинні бути раді, що doneце не написано od.
Випадково832

4
@ Random832: Це тому, що odвже використовувалося як назва програми Octal Dump.
користувач1024

8
Тут так багато я не знав. Дякую!
Гонки легкості по орбіті

1
@mirabilos, for i doє Bourne та POSIX, але не працюватиме в деяких старих версіях оболонок на основі золи IIRC. for i in "$@"не працюватиме в оболонці Bourne, якщо $IFSне містить символу пробілу. for i<newline>doдійсно є найбільш портативним, якщо вам потрібно врахувати дуже старі системи BSD. Див in-ulm.de/~mascheck/various/bourne_args подробиці
Stephane Chazelas
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.