Kiedy uruchamiam te dwa polecenia, otrzymuję
$ type cd
cd is a shell builtin
$ type if
if is a shell keyword
Jest wyraźnie pokazane, że cd
jest wbudowaną powłoką i if
jest słowem kluczowym powłoki. Jaka jest różnica między wbudowaną powłoką a słowem kluczowym?
command-line
Avinash Raj
źródło
źródło
Odpowiedzi:
Istnieje duża różnica między wbudowanym a słowem kluczowym w sposobie, w jaki Bash analizuje kod. Zanim porozmawiamy o różnicy, wypiszmy wszystkie słowa kluczowe i wbudowane:
Wbudowane:
Słowa kluczowe:
Zauważ, że na przykład
[
jest wbudowany i to[[
jest słowo kluczowe. Użyję tych dwóch, aby zilustrować różnicę poniżej, ponieważ są one dobrze znanymi operatorami: wszyscy je znają i używają ich regularnie (lub powinni).Słowo kluczowe jest skanowane i rozumiane przez Bash na bardzo wczesnym etapie jego analizy. Umożliwia to na przykład:
To działa dobrze, a Bash z przyjemnością wyświetli
Pamiętaj, że nie cytowałem
$string_with_spaces
. Mając na uwadze, że:pokazuje, że Bash nie jest szczęśliwy:
Dlaczego działa ze słowami kluczowymi, a nie z wbudowanymi? ponieważ kiedy Bash analizuje kod, widzi,
[[
które jest słowem kluczowym i bardzo wcześnie rozumie, że jest wyjątkowy. Będzie więc szukał zamknięcia]]
i potraktuje wnętrze w specjalny sposób. Wbudowane (lub polecenie) jest traktowane jako rzeczywiste polecenie, które będzie wywoływane z argumentami. W tym ostatnim przykładzie bash rozumie, że powinien uruchomić polecenie[
z argumentami (pokazane po jednym w wierszu):ponieważ następuje rozwijanie zmiennych, usuwanie cytatów, rozwijanie nazw ścieżek i dzielenie słów. Komenda
[
okazuje się być wbudowana w powłokę, więc wykonuje ją z tymi argumentami, co powoduje błąd, stąd skarga.W praktyce widać, że to rozróżnienie pozwala na wyrafinowane zachowanie, które nie byłoby możliwe w przypadku wbudowanych poleceń (lub poleceń).
W praktyce, jak możesz odróżnić wbudowane narzędzie od słowa kluczowego? to zabawny eksperyment do wykonania:
Kiedy Bash analizuje linię
$a -d . ]
, nie widzi nic specjalnego (tj. Żadnych aliasów, żadnych przekierowań, żadnych słów kluczowych), więc po prostu wykonuje zmienną interpretację. Po zmiennych rozszerzeniach widzi:tak wykonuje polecenia (wbudowane)
[
z argumentami-d
,.
i]
, co oczywiście jest prawdą (to tylko testy czy.
jest katalogiem).Nowy wygląd:
O. Dzieje się tak, ponieważ gdy Bash widzi tę linię, nie widzi nic specjalnego, a zatem rozwija wszystkie zmienne i ostatecznie widzi:
W tej chwili rozszerzenia aliasów i skanowanie słów kluczowych były już od dawna wykonywane i nie będą już wykonywane, więc Bash próbuje znaleźć polecenie o nazwie
[[
, nie znajduje go i narzeka.Wzdłuż tych samych linii:
i
Rozszerzenie aliasu jest również czymś wyjątkowym. Wszyscy przynajmniej raz wykonaliście następujące czynności:
Rozumowanie jest takie samo: rozwinięcie aliasu następuje na długo przed rozwinięciem zmiennej i usunięciem cytatu.
Słowo kluczowe a Alias
Jak myślisz, co się stanie, jeśli zdefiniujemy alias jako słowo kluczowe?
Och, to działa! więc aliasy mogą być używane do aliasu słów kluczowych! dobrze wiedzieć.
Wniosek: wbudowane naprawdę zachowują się jak polecenia: odpowiadają one wykonywanej akcji z argumentami, które podlegają bezpośredniemu rozszerzaniu zmiennych oraz dzieleniu i dzieleniu słów. To naprawdę tak, jakby mieć gdzieś zewnętrzną komendę
/bin
lub/usr/bin
jest ona wywoływana z argumentami podanymi po rozwinięciu zmiennej itp. Zauważ, że kiedy mówię, to tak naprawdę, jak z zewnętrzną komendą, mam na myśli tylko w odniesieniu do argumentów, dzielenia słów, globowania, zmienna ekspansja itp. Wbudowany może modyfikować wewnętrzny stan powłoki!Z drugiej strony słowa kluczowe są skanowane i rozumiane bardzo wcześnie i umożliwiają wyrafinowane zachowanie powłoki: powłoka będzie mogła zabronić dzielenia słów lub rozwijania nazw ścieżek itp.
Teraz spójrz na listę wbudowanych i słów kluczowych i spróbuj dowiedzieć się, dlaczego niektóre muszą być słowami kluczowymi.
!
jest słowem kluczowym. Wydaje się, że można by naśladować jego zachowanie za pomocą funkcji:ale to zabraniałoby konstrukcji takich jak:
lub
To samo dla
time
: bardziej wydajne jest użycie słowa kluczowego, aby mógł on mierzyć złożone polecenia złożone i potoki z przekierowaniami:Gdyby
time
zwykłe polecenie (nawet wbudowane), widziałoby tylko argumentygrep
,^#
a/home/gniourf/.bashrc
tym razem, a następnie jego dane wyjściowe przechodziłyby przez pozostałe części potoku. Ale dzięki słowu kluczowemu Bash poradzi sobie ze wszystkim! możetime
kompletny potok, w tym przekierowania! Gdyby totime
było zwykłe polecenie, nie moglibyśmy zrobić:Spróbuj:
Spróbuj naprawić (?) To:
Beznadziejny.
Słowo kluczowe a alias?
Jak myślisz, co się dzieje?
Naprawdę, wbudowane jest jak polecenie, tyle że jest wbudowane w powłokę, podczas gdy słowo kluczowe pozwala na wyrafinowane zachowanie! możemy powiedzieć, że jest to część gramatyki powłoki.
źródło
=\
"za pomocąman
,apropos
, ihelp
, a ja nie miałem szczęścia. Masz pomysł, gdzie mógłbym znaleźć te informacje? Przede wszystkim dlatego, że w przyszłości mogę zobaczyć, co jeszcze tam jest, ponieważ myślę, że brakuje mi źródła odniesienia.\ll
,"ll"
albo'll'
.[[
wydajność\[[
, nie jest ona analizowana jako alias. Jak dotąd? Kiedy zgubiłem się, nie zdawałem sobie sprawy, że odwrotny ukośnik był cytatem w Bash, i spróbowałem to sprawdzić pod aliasami i słowami kluczowymi i całkowicie się zgubiłem ... Wszystko dobrze. W sekcji Cytowanie:> Niecytowany ukośnik odwrotny () to znak zmiany znaczenia.\[[
jest to pojedynczy token typu LiteralQuoteToken, w przeciwieństwie do[[
OpenTestKeywordToken, który wymaga zamykającego]]
CloseTestKeywordToken do kompilacji oroper / poprawnej składni. Później w (4) LiteralQuoteToken zostanie oceniony[[
jako nazwa bulitin / polecenia do wykonania, aw (6) Bash zbankrutuje, ponieważ nie ma[[
wbudowanego polecenia ani polecenia. Miły. Z czasem mogę zapomnieć o dokładnych szczegółach, ale w tej chwili sposób, w jaki Bash prowadzi rzeczy, jest dla mnie o wiele bardziej wyraźny; Dziękuję Ci.man bash
dzwoni do nichSHELL BUILTIN COMMANDS
. Tak więc „wbudowana powłoka” jest jak zwykłe polecenie, jakgrep
itp., Ale zamiast być zawarta w osobnym pliku, jest wbudowana w samą bash . Dzięki temu działają one wydajniej niż polecenia zewnętrzne.Słowo kluczowe jest również „zakodowane na stałe w Bash, ale w przeciwieństwie do wbudowanego słowa kluczowego nie jest samo w sobie poleceniem, ale podjednostką konstrukcji polecenia”. Interpretuję to w ten sposób, że słowa kluczowe nie pełnią żadnej funkcji, ale wymagają poleceń do wykonania dowolnej czynności. (Z linku, inne przykłady
for
,while
,do
, i!
, i są bardziej w mojej odpowiedzi na inne pytanie.)źródło
[[ is a shell keyword
ale[ is a shell builtin
. Nie mam pojęcia dlaczego.[
istniał jako osobne polecenie w przeszłości.[[
nie jest określony przez standard, więc programiści mogą zdecydować się na uwzględnienie go jako słowa kluczowego lub jako wbudowanego.Podręcznik wiersza poleceń dostarczany z Ubuntu nie zawiera definicji słów kluczowych, jednak podręcznik online (patrz sidenote) i standardowe specyfikacje POSIX Shell Command Language określają je jako „słowa zastrzeżone” i oba zawierają ich listę. Ze standardu POSIX:
Kluczem tutaj jest to, że słowa kluczowe / słowa zastrzeżone mają specjalne znaczenie, ponieważ ułatwiają składnię powłoki, służą do sygnalizowania pewnych bloków kodu, takich jak pętle, polecenia złożone, instrukcje rozgałęziające (if / case) itp. Pozwalają one tworzyć instrukcje, ale sami - nie rób nic, aw rzeczywistości po wpisaniu słów kluczowych, takich jak
for
,until
,case
- powłoka będzie oczekiwać kompletne oświadczenie, w przeciwnym razie - błąd składni:Na poziomie kodu źródłowego słowa zastrzeżone dla bash są zdefiniowane w parese.y , podczas gdy wbudowane mają dedykowany im cały katalog .
Dygresja
Indeks GNU pokazuje się
[
jako słowo zastrzeżone, jednak w rzeczywistości jest to wbudowane polecenie.[[
natomiast jest słowem zastrzeżonym.Zobacz także: Różnice między słowem kluczowym, słowem zastrzeżonym i wbudowanym?
źródło