Zauważyłem, że istnieją dwa alternatywne sposoby budowania pętli w Zsh :
for x (1 2 3); do echo $x; done
for x in 1 2 3; do echo $x; done
Oba drukują:
1
2
3
Moje pytanie brzmi: dlaczego dwie składnie? Czy w każdym z nich występuje $x
iteracja innego typu ?
Czy bash robi podobne rozróżnienie?
Uzupełnienie:
Dlaczego działa następujący:
#!/bin/zsh
a=1
b=2
c=5
d=(a b c)
for x in $d; do print $x;done
ale ten nie ?:
#!/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
zadziała i będzie pasować do pierwszej składni, którą wyliczyłeś na początku pytania.for i ({0..4..2}) for j ({a..c}) echo "($i,$j)"
={0,2,4}x{a,b,c}
. Średniki dotyczą najbardziej zewnętrznej pętli, a przekierowania dotyczą najbardziej wewnętrznej, a jeśli chcesz to zmienić, potrzebujesz tylko nawiasów klamrowych:for i ({0..4..2}) { for j ({a..c}) echo "($i,$j)" } | cat -n
={1,...,9}*({0,2,4}x{a,b,c})
. Oczywiście można łączyć pętle z rozszerzeniem zsh:for i ("("{0..4..2}","{a..c}")") echo $i
Odpowiedzi:
Kilka form złożonych poleceń, takich jak pętle, ma alternatywne formy w zsh. Te formy są w większości inspirowane powłoką C , która była dość powszechna, gdy Zsh był młody, ale teraz zniknął. Te alternatywne formy działają dokładnie tak samo, jak zwykłe formy, to tylko inna składnia. Są nieco krótsze, ale mniej wyraźne.
Standardową formą
for
polecenia jestfor x in 1 2 3; do echo $x; done
, a standardową formąwhile
polecenia jestwhile test …; do somecommand; done
. KSH atakujących i zsh mieć alternatywną postaćfor
:for ((i = 0; i < 42; i++)); do somecommand; done
, który naśladujefor
pętle języków takich jak Pascal i C, w celu wyliczenia całkowitymi. Inne egzotyczne formy, które istnieją w zsh, są specyficzne dla zsh (ale często inspirowane przez csh).źródło
zsh
? Dodałem też jeden przykład na końcu mojego OP, w którym nie mogę wymyślić, jak tłumaczyć między składniami. Jeśli różnica polega tylko na składni, jak powinienem naprawić drugi skrypt w dodatku, aby działał?for x $d
i zsh oczekuje albo,in
albo(
gdzie napisałeś$d
. Znaki interpunkcyjne i słowa zastrzeżone nie mogą pochodzić z rozszerzenia zmiennej, muszą zostać przeanalizowane, zanim powłoka będzie mogła rozpocząć się od rozszerzenia zmiennej.for (( … ))
formularz i zużywa dużo pamięci, jeśli 3 jest duże.do
po));
. Zsh akceptuje także inną składnię, wfor ((…)); COMMAND
którejCOMMAND
jest to jedno polecenie. Dlatego akceptujefor ((i = 1; i<100; i++)); ghi show $i | grep "log"
. Kiedy to zobaczydone
, narzeka, bo nie byłodo
końca. Zobacz „Alternatywne formularze dla złożonych poleceń” w podręczniku .