Я заметил, что есть два альтернативных способа построения циклов в zsh :
for x (1 2 3); do echo $x; done
for x in 1 2 3; do echo $x; done
Они оба печатают:
1
2
3
У меня вопрос, почему два синтаксиса? Является ли $x
итерация через другой тип объекта в каждой из них?
Делает ли Bash подобное различие?
Приложение:
Почему работает следующее:
#!/bin/zsh
a=1
b=2
c=5
d=(a b c)
for x in $d; do print $x;done
а этот нет?
#!/bin/zsh
a=1
b=2
c=5
d=(a b c)
# It complains with "parse error near `$d'"
for x $d; do print $x;done
for x ($d); do print $x; done
будет работать, и он будет соответствовать первому синтаксису, который вы перечислили в начале вашего вопроса.for i ({0..4..2}) for j ({a..c}) echo "($i,$j)"
={0,2,4}x{a,b,c}
. Точки с запятой применяются к самому внешнему циклу, а перенаправления применяются к самому внутреннему циклу, и если вам нужно это изменить, вам нужны только фигурные скобки:for i ({0..4..2}) { for j ({a..c}) echo "($i,$j)" } | cat -n
={1,...,9}*({0,2,4}x{a,b,c})
. Конечно, вы можете комбинировать циклы с расширением zsh:for i ("("{0..4..2}","{a..c}")") echo $i
Ответы:
Несколько форм сложных команд, таких как циклы, имеют альтернативные формы в zsh. Эти формы в основном вдохновлены оболочкой C , которая была довольно распространена, когда zsh был молодым, но теперь исчез. Эти альтернативные формы действуют точно так же, как нормальные формы, это просто другой синтаксис. Они немного короче, но менее четкие.
Стандартная форма для
for
командыfor x in 1 2 3; do echo $x; done
, и стандартная форма дляwhile
командыwhile test …; do somecommand; done
. Ksh, bash и zsh имеют альтернативную формуfor
:,for ((i = 0; i < 42; i++)); do somecommand; done
которая имитируетfor
циклы языков, таких как Pascal или C, для перечисления целых чисел. Другие экзотические формы, которые существуют в zsh, специфичны для zsh (но часто вдохновлены csh).источник
zsh
? Кроме того, я добавил один пример в конце моего OP, где я не могу понять, как переводить между синтаксисами. Если разница только в синтаксисе, как мне исправить второй скрипт в приложении, чтобы он работал?for x $d
и zsh ожидает, чтоin
или(
где вы написали$d
. Знаки пунктуации и зарезервированные слова не могут быть получены из раскрытия переменных, их необходимо проанализировать, прежде чем оболочка сможет начать развертывание переменных.for (( … ))
форма, и использует много памяти, если 3 большой.do
после));
. Zsh также принимает другой синтаксис,for ((…)); COMMAND
гдеCOMMAND
есть одна команда. Вот почему он принимаетfor ((i = 1; i<100; i++)); ghi show $i | grep "log"
. Когда он видитdone
после этого, он жалуется, потому что неdo
было конца. См. «Альтернативные формы для сложных команд» в руководстве .