Dlaczego echo jest wbudowanym poleceniem powłoki?


34
$ which echo
echo: shell built-in command.
$ which ls
/bin/ls
$ which cat
/bin/cat

Dlaczego echo nie jest niezależnym Narzędzie jak ls, ps, catitp? Dlaczego jest on specyficzny dla powłoki? Jakieś dobre powody?


5
Pamiętaj, że jest to specyficzne dla powłoki. ZSH go wbudowuje, BASH nie.
tsvallender,

21
@tsv: z echopewnością jest wbudowany w Bash. W rzeczywistości jest wbudowany w każdą większą nowoczesną powłokę.
Wstrzymano do odwołania.

Odpowiedzi:


71

Istnieją dwie klasy wbudowanych:

  1. Niektóre polecenia muszą być wbudowane w sam program powłoki, ponieważ nie mogą działać, jeśli są zewnętrzne.

    cdjest jednym z nich, ponieważ gdyby był zewnętrzny, mógłby jedynie zmienić własny katalog; nie może wpłynąć na bieżący katalog roboczy powłoki. (Zobacz także: Dlaczego cdnie jest programem? )

  2. Druga klasa poleceń jest wbudowana w powłokę wyłącznie w celu zwiększenia wydajności.

    Strona człowiek posiada sekcję na builtins który wspomina , i jako przykłady poleceń w tej klasie.dash printfechotest

Systemy uniksowe zawsze zawierały osobne pliki wykonywalne dla poleceń w tej drugiej klasie. Te osobne pliki wykonywalne są nadal dostępne w każdym systemie Unixy, z którego korzystałem, nawet jeśli są wbudowane w każdą powłokę, której prawdopodobnie będziesz używać. ( POSIX faktycznie wymaga obecności tych plików wykonywalnych).

Myślę, że echozostał wbudowany w powłokę w AT&T Unix System V Release 3.1. Opieram to na porównaniu dwóch różnych wydań instrukcji obsługi systemów uniksowych serii AT i Ts 3B1 . Ktoś uprzejmie zeskanował wydania tych podręczników z 1986 r. I umieścił je w Internecie ; odpowiadają one pierwotnemu wydaniu SVR3. Widać, że echonie ma go na liście na stronie 523 UNIX System V Podręcznik użytkownika, tom II , gdzie można się spodziewać, gdyby polecenie zostało wbudowane w powłokę. W mojej lokalnej wersji papierowej instrukcji SVR3.1 z 1987 r. Wymieniony echo jest w tej części instrukcji.

Jestem prawie pewien, że nie jest to innowacja Berkeley CSRG, którą AT&T wróciło do domu. 4.3BSD wyszedł w tym samym roku, co SVR3, 1986, ale jeśli spojrzysz na stronę podręcznika sh.1 4.3BSD , zobaczysz, że echonie ma go na liście wbudowanych poleceń sekcji „Polecenia specjalne”. Jeśli CSRG to zrobi, pozostanie nam udokumentowane źródło, które to udowodni.

W tym momencie możesz się zastanawiać, czy echozostał on wbudowany w powłokę wcześniej niż SVR3.1 i czy do tego czasu ten fakt nie został po prostu udokumentowany . Najnowszy dostępny dla mnie kod źródłowy AT&T Unix sprzed SVR3 znajduje się w tarballu PDP-11 System III , w którym znajdziesz kod źródłowy powłoki Bourne'a. Nie znajdziesz echowbudowanej tabeli poleceń /usr/src/cmd/sh/msg.c. Na podstawie sygnatur czasowych w tym pliku dowodzi, że z echopewnością nie było go w powłoce w 1980 roku.


Drobnostki

Ten sam katalog zawiera również plik o nazwie, builtin.cktóry nie zawiera żadnych informacji na temat tego pytania, ale znajdujemy ten interesujący komentarz:

/*      
    builtin commands are those that Bourne did not intend
    to be part of his shell.
    Redirection of i/o, or rather the lack of it, is still a
    problem..
*/      

Na stronie 385 SysV UM, tom II, o której wspomniałeś, jest wbudowane printpolecenie dla ksh, o którym mówi się, że zachowuje się jak echo. To polecenie jest także obecne w coś takiego jak AT&T Unix SVR4 2.1 i386 z ISC. print "\012"daje taki sam wynik jak echo. Zastanawiasz się, dlaczego ksh ma wbudowane drukowanie, a nie echo? W każdym razie naprawdę interesujące.

Ile takich klejnotów sprzed kilku lat zostało wymkniętych i czeka na odkrycie w 2016 roku? +1
iruvar

+1. Dzięki. Czy możesz podać źródła (referencje) w celu wykonania wbudowanego polecenia, do mojego (systematycznego) czytania / uczenia się?
Tim

Chcę znaleźć odniesienie, instrukcję lub standard, aby systematycznie czytać lub uczyć się. Próbowałem to sprawdzić w podręczniku bash i specyfikacjach POSIX. Ale nie mogę tego znaleźć. Nie jestem pewien, czy tęsknię.
Tim

@Tim: Jak wyjaśniono w tej i innych odpowiedziach, niektóre polecenia muszą być wbudowane w powłokę, inaczej nie będą mogły wykonywać swojej pracy. Wszystkie pozostałe są całkowicie opcjonalne . W zasadzie tak właśnie napisał mój fragment kodu źródłowego powłoki Bourne'a. Ponieważ wbudowanie takich poleceń w powłokę jest opcjonalne, autorytatywne uzasadnienie może dać opinię tylko jednego implementatora.
Warren Young,

19

Istnieje trzeci powód, dla którego niektóre polecenia mają być wbudowane: można ich używać, gdy wykonywanie poleceń zewnętrznych jest niemożliwe.

Czasami system jest tak zepsuty, że lspolecenie nie działa. W niektórych przypadkach echo *nadal będzie działać.

Innym (ważniejszym!) Przykładem jest kill: Jeśli w systemie zabraknie wolnych PID-ów, uruchomienie nie będzie możliwe /bin/kill(ponieważ potrzebuje PID-a :-), ale wbudowane killbędzie działać.

Btw., whichJest poleceniem zewnętrznym (przynajmniej nie jest wewnętrznym poleceniem bash), więc nie może wyświetlić poleceń wewnętrznych. Na przykład:

$ which echo
/bin/echo
$ type -a echo
echo is a shell builtin
echo is /bin/echo

Nie zapominaj, że prawie wszystkie zewnętrzne pliki wykonywalne korzystają z plików bibliotek. Czasami zdarzają się katastrofy i tych bibliotek nie można załadować (rada: NIGDY nie wydawaj, ldconfigchyba że DOKŁADNIE wiesz, co robisz). A co jeśli zdmuchniesz swoją partycję / bin lub, co gorsza, partycję / sbin, ale nadal masz załadowaną powłokę?
LawrenceC

Jeśli zabraknie PID, może być trudno ustalić, który PID chcesz zabić. Nie możesz uruchomić pspolecenia, więc musisz ręcznie znaleźć PID /proc.
kasperd

Chociaż na (przynajmniej) CentOS whichto uruchamiany alias bash, alias | /usr/bin/which --read-alias ...aby zewnętrzny which mógł identyfikować aliasy (ale nadal nie jest wbudowany). Nie mogę zdecydować, czy uznać to za genialne, czy zboczone.
dave_thompson_085

W momencie, gdy polecenie ls już nie działa, myślę, że powinieneś zamontować dysk jako slave zamiast boot / master i naprawić strukturę plików w ten sposób. Nie jestem pewien, jak można naprawić ten stopień uszkodzenia systemu za pomocą echa, chyba że echo> w pliku, a naprawa zajęłaby dużo czasu. Przyznaję, że możesz napisać skrypt bash, który miał naprawić strukturę systemu.
jonnyjandles,

13

Zgodnie z podręcznikiem użytkownika Bash chodzi o wygodę.

Powłoki zapewniają również niewielki zestaw wbudowanych poleceń (wbudowanych) implementujących funkcje niemożliwe lub niewygodne do uzyskania za pomocą oddzielnych narzędzi. Na przykład cd, break, Continue i exec) nie mogą być implementowane poza powłoką, ponieważ bezpośrednio manipulują samą powłoką. Wbudowane funkcje historii, getopts, kill lub pwd mogą być zaimplementowane w oddzielnych narzędziach, ale wygodniej jest ich używać jako poleceń wbudowanych. Wszystkie wbudowane powłoki zostały opisane w kolejnych sekcjach.

Przewodnik Advanced Bash Scripting Guide zawiera bardziej szczegółowe wyjaśnienie:

„Wbudowane to polecenie zawarte w zestawie narzędzi Bash, dosłownie wbudowane. Jest to albo ze względów wydajnościowych - wbudowane wykonują się szybciej niż polecenia zewnętrzne, które zwykle wymagają wykreślenia 1 oddzielnego procesu - lub dlatego, że konkretne wbudowane potrzebuje bezpośredniego dostęp do wewnętrznych elementów powłoki. ”

Należy również pamiętać, że echoistnieje jako samodzielne narzędzie w niektórych systemach. Oto, co mam w moim systemie Darwin (MacOSX 10.5.8 - Leopard)

$ uname -a
Darwin host.foo.org 9.8.0 Darwin Kernel Version 9.8.0: Wed Jul 15 16:55:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_I386 i386
$ bash --version
GNU bash, version 3.2.17(1)-release (i386-apple-darwin9.0)
Copyright (C) 2005 Free Software Foundation, Inc.
$ which echo
/bin/echo

echojest również dostępny jako wbudowany, ale najwyraźniej moje skrypty używają / bin / echo na moim Macu i używają wbudowanego Bash na większości moich systemów Linux i FreeBSD. Ale to nie wydaje się mieć znaczenia, ponieważ skrypty nadal działają dobrze wszędzie.


3
Mówiąc o wbudowanych powłokach, powinieneś używać „type” zamiast „which”.
Teddy

Dzięki @Teddy. Zacząłem to robić, kiedy pamiętam. Życie jest o wiele lepsze dzięki type.
Stefan Lasiewski

6

Aby uzupełnić odpowiedź bhm, powiedzmy, że /binzostał przypadkowo usunięty z twojego PATH. Chciałbyś móc echo $PATHto odkryć, prawda?


2

Chociaż większość powłok ma echoobecnie wbudowane funkcje, GNU CoreUtils zawiera również samodzielną implementację:

$ which echo
/bin/echo
$ dpkg -S /bin/echo
coreutils: /bin/echo

Wygląda na to, że nie masz zainstalowanego GNU Coreutils (większość systemów operacyjnych dla komputerów stacjonarnych i serwerów opartych na systemie Linux jest zainstalowanych domyślnie, ale osadzony Linux lub inny system UNIX może zamiast tego używać alternatywnych kolekcji narzędzi powłoki).

BTW: jeśli spojrzeć na Busybox , zobaczysz, że ls, psa cattakże wbudowanych komend tam (lub przynajmniej może być, jest używany dla systemów osadzone i nie wszystko potrzebne mogą zostać pominięte).


3
Testy oryginalnego plakatu nie potwierdzają hipotezy, /bin/echoktóra nie istnieje. Pokazują tylko, że wbudowane ma pierwszeństwo przed jakimkolwiek echoprogramem w ścieżce.
Warren Young,

1

Oto prawdziwy powód, dla którego echopowinna być wbudowana powłoka:

Załóżmy, że masz hasło $PASSWORD. Jak zapisać to do pliku ./password? Oczywiście większość programistów napisałaby:

echo "$PASSWORD" >./password

Jeśli echojednak nie byłyby wbudowane w powłokę, hasło przeciekłoby do wszystkich użytkowników za pośrednictwem psinformacji.

Oczywiście, jeśli chcesz być sprytny, możesz znaleźć sposób na przechowywanie hasła bez echo, być może wykorzystując inną funkcję powłoki:

cat >./password <<EOF
${PASSWORD}
EOF

Jednak posiadanie echowbudowanego jest ważnym pasem bezpieczeństwa, ponieważ najbardziej oczywisty sposób na zapisanie hasła do pliku powinien również działać.


3
Chociaż użyteczny efekt uboczny uważam za bardzo wątpliwe, że to był powód.
plugwash

@DepressedDaniel: Co cię wspiera? Gdzie jest odniesienie użyte w celu udzielenia odpowiedzi?
joker
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.