Dlaczego nie ma ;
znaku do
w pętli powłoki, gdy jest napisany w jednym wierszu?
Oto co mam na myśli. Gdy zapisana jest w wielu wierszach, for
pętla wygląda następująco:
$ for i in $(jot 2)
> do
> echo $i
> done
I na jednej linii:
$ for i in $(jot 2); do echo $i; done
Wszystkie zapadnięte linie dostać ;
po nich z wyjątkiem dla do
linii, a jeśli należą ;
, to jest błąd. Ktoś pewnie o wiele mądrzejszy ode mnie zdecydował, że to była właściwa rzecz z jakiegoś powodu, ale nie mogę zrozumieć, jaki jest powód. Wydaje mi się to niespójne.
To samo dotyczy while
również pętli.
$ while something
> do
> anotherthing
> done
$ while something; do anotherthing; done
while
/for
albo nie ma średnika .Odpowiedzi:
To jest składnia polecenia. Zobacz Polecenia złożone
Uwaga w szczególności:
do commands
Większość ludzi umieszcza
do
icommands
w osobnym wierszu, aby ułatwić czytelność, ale nie jest to konieczne, możesz napisać:Wiem, że to pytanie dotyczy konkretnie powłoki i podłączyłem się do instrukcji bash. Nie jest tak napisane w podręczniku powłoki, ale jest tak napisane w artykule Stephena Bourne'a dla magazynu byte.
Stephen mówi:
źródło
for i in thing; do; something; done
. Mimo że podział linii jest dozwolony, średnik nie jest dozwolony.something
to przedmiot ido
dotyczy go. Tak jak w angielskiej strukturze zdań.while
składni), więc potrzebujesz czegoś, aby odróżnić polecenia warunku od poleceń treści pętli. Używanie ichdo
do rozdzielania jest prawdopodobnie najbardziej odpowiednie.Nie wiem, jaki jest pierwotny powód tej składni, ale rozważmy fakt, że
while
pętle mogą przyjmować wiele poleceń w sekcji warunków, np.Tutaj
do
słowo kluczowe jest konieczne, aby rozróżnić sekcję warunków i główny korpus pętli.do
Hasło jest niczymwhile
,if
athen
(idone
) i wydaje się być w zgodzie z innymi, które nie wymagają średnik lub nowej linii po nim, ale pojawia się natychmiast przed poleceniem.Alternatywa (uogólniona do
if
iwhile
) wyglądałaby trochę brzydko, musielibyśmy napisać npSkładnia
for
pętli jest po prostu podobna.źródło
Składnia powłoki jest oparta na prefiksie. Ma klauzule wprowadzone przez specjalne słowa kluczowe. Niektóre klauzule muszą iść w parze.
while
Pętla składa się jednego lub więcej testów polecenia:i przez jedno lub więcej poleceń ciała:
Coś musi powiedzieć powłoce, że zaczyna się pętla while. Taki jest cel tego
while
słowa:Ale rzeczy są niejednoznaczne. Które polecenie jest początkiem ciała? Coś musi to wskazywać i właśnie to
do
robi przedrostek:i wreszcie coś musi wskazywać, że widziało ostatnie ciało;
done
robi to specjalne słowo kluczowe .Te słowa kluczowe powłoki nie wymagają separacji średnikami, nawet w tym samym wierszu. Na przykład, jeśli zamkniesz kilka zagnieżdżonych pętli, możesz po prostu mieć
done done done ...
.Średnik jest raczej pomiędzy,
... test ; body ...
jeśli są w tej samej linii. Ten średnik jest rozumiany jako terminator: należy do niegotest
. Dlatego, jeślido
słowo kluczowe zostanie wstawione między nimi, musi przechodzić między średnikiem abody
. Gdyby znajdował się po drugiej stronie średnika, byłby niepoprawnie osadzonytest
w składni polecenia, a nie umieszczony między poleceniami.Składnia powłoki została pierwotnie zaprojektowana przez Stephena Bourne'a i jest inspirowana przez Algola . Bourne tak bardzo kochał Algol, że używał wielu makr C w kodzie źródłowym powłoki, aby C wyglądał jak Algol. Możesz przeglądać źródła powłoki datowane na 1979 rok z wersji 7 Unix . Makra są włączone
mac.h
i są używane wszędzie. Na przykładif
oświadczenia są renderowane jakoIF
...ELSE
...ELIF
...FI
.źródło
Twierdziłbym, że
do
nie jest to tutaj szczególnie wyjątkowe. Wystąpił błąd, ponieważ;
nie można uruchomić listy poleceń. Gdyby tak było, pierwsze polecenie byłoby puste, a gramatyka nie zezwala na puste polecenia (przypisania zmiennych lub przekierowania bez polecenia, tak, ale absolutnie nic, nie). Dzieje się tak w dowolnej liczbie miejsc, wszędzie tam, gdzie oczekiwana jest lista poleceń:Parzysty:
We wszystkich tych miejscach oczekiwana jest lista poleceń, a zatem nie można oczekiwać wprowadzenia
;
.źródło
do
(iif
itp.)?Składnia jest następująca:
Każda z nowych linii, na liście poleceń lub przed „do” lub „zrobione” może być zastąpiona przez „;”.
Nowa linia (ale nie „;”) jest dozwolona po „do” i przed „w”, tylko po to, aby wyglądać ładniej, ale nie ma sensu wymagać nowej linii.
źródło
if
jest podobny do słów kluczowych: jest to dość czytelne, gdy polecenia są krótkie:źródło
\n
podo
nim wszystko miało sens (tak długo, jak nie myśleć o tym nie jest w stanie umieścić w dowolnym\n
między innymi poleceniami i args).do
,then
,else
są nie args - gdyby były, to nie wolno używać średnik przed nimi. Są to słowa kluczowe powłoki (patrztype if then elif else fi
)Krótka odpowiedź, ponieważ jest to określone przez gramatykę powłoki POSIX . Wszystko pomiędzy
do
idone
jest uważane za grupę instrukcji, podczas gdy;
jest sekwencyjnym separatorem:Dodatkowo, jeśli byłoby
;
to konieczne, norma wyraźnie to określa i obejmujesequential_sep
późniejDo
.źródło
Ponieważ do jest słowem kluczowym, a po nim są w zasadzie parametry. Tłumacz Bash wie, że więcej. Jest podobny do tego, jak nie ma ';' po i w poleceniu for. Możesz faktycznie dodać nową linię po i i wpisać resztę w nowej linii, a to będzie działać poprawnie.
źródło