W podręczniku bash jest napisane, że
Builtin commands are contained >>> within <<< the shell itself
Również ta odpowiedź stwierdza, że
A built-in command is simply a command that the shell carries out itself,
instead of interpreting it as a request to load and run some
>>> other program <<<
Kiedy biegnę compgen -b
na bash 4.4
, ja otrzymać listę wszystkich WBUDOWANE POLECENIA POWŁOKI. I patrz na przykład, że [
a kill
wymienione się builtins powłoki. Ale ich rzeczywiste lokalizacje to:
/usr/bin/[
/bin/kill
Pomyślałem, że to builtin
oznacza, że polecenie jest wkompilowane w /bin/bash
plik wykonywalny. Co mnie naprawdę dezorientuje: Proszę mnie poprawić, ale jak może być osobne polecenie builtin
, skoro tak naprawdę nie jest częścią powłoki?
bash
shell
shell-builtin
manifestant
źródło
źródło
exec
do manipulowania deskryptorami plików ieval
do oceny poleceń. Nie są potrzebne jako samodzielne poleceniaOdpowiedzi:
Polecenia wbudowane w powłokę są często wbudowane ze względu na wzrost wydajności, jaki to daje. Na przykład wywołanie zewnętrznego
printf
jest wolniejsze niż użycie wbudowanegoprintf
.Ponieważ niektóre narzędzia nie muszą być wbudowane, chyba że są wyjątkowe, na przykład
cd
są również dostarczane jako narzędzia zewnętrzne . Dzieje się tak, aby skrypty nie uległy awarii, jeśli są interpretowane przez powłokę, która nie zapewnia wbudowanego odpowiednika.Niektóre wbudowane powłoki dostarczają również rozszerzenia zewnętrznego równoważnego polecenia. Na
printf
przykład Bash's jest w stanie to zrobić(wypisz do zmiennej), czego zewnętrzny
/usr/bin/printf
po prostu nie byłby w stanie zrobić, ponieważ nie ma dostępu do zmiennych powłoki w bieżącej sesji powłoki (i nie może ich zmienić).Wbudowane narzędzia również nie mają ograniczenia, że ich rozszerzona linia poleceń musi być krótsza niż pewna długość. Robić
jest zatem bezpieczny, jeśli
printf
jest wbudowanym poleceniem powłoki. Ograniczenie długości wiersza poleceń wynika zexecve()
funkcji biblioteki C używanej do wykonania polecenia zewnętrznego. Jeśli linia poleceń i bieżące środowisko jest większe niżARG_MAX
bajty (patrzgetconf ARG_MAX
w powłoce), wywołanie doexecve()
nie powiedzie się. Jeśli narzędzie jest wbudowane w powłokę,execve()
nie musi być wywoływane.Wbudowane narzędzia mają pierwszeństwo przed narzędziami znalezionymi w
$PATH
. Aby wyłączyć wbudowane polecenie wbash
, użyj npIstnieje krótka lista narzędzi, które muszą zostać wbudowane w powłokę (wzięte z listy specjalnych wbudowanych w standardzie POSIX )
Należy je wbudować, ponieważ bezpośrednio manipulują środowiskiem i przepływem programu bieżącej sesji powłoki. Zewnętrzne narzędzie nie byłoby w stanie tego zrobić.
Co ciekawe,
cd
nie jest częścią tej listy, ale POSIX mówi o tym:W związku z tym zakładam, że „specjalne” wbudowane elementy nie mogą mieć zewnętrznych odpowiedników, podczas gdy
cd
teoretycznie mogłyby mieć (ale niewiele by to zrobiły).źródło
chdir
/cd
były zewnętrznymi plikami binarnymi we wczesnych Unicach / wcześniejszych niż Unix, zanimfork
zostały wprowadzone./usr/bin/cd
, ale tak naprawdę nie zmieni bieżącego katalogu roboczego. Jego instrukcja mówi:/usr/bin/cd
nie ma wpływu na proces wywoływania, ale można go użyć do ustalenia, czy dany katalog może być ustawiony jako katalog bieżący.kill
jest również miły, ponieważ nie musi rozwidlać innego procesu, dobrze, jeśli osiągniesz limit liczby procesów.Jesteś (bardzo zrozumiały) zdezorientowany faktem, że niektóre wbudowane funkcje istnieją zarówno jako wbudowane, jak i jako zewnętrzne polecenia. Tak więc, chociaż masz rację, że na przykład istnieje
/bin/[
polecenie, nie oznacza to, że jest w nim „rzeczywista lokalizacja”/bin
.Jakiś prosty sposób na sprawdzenie tego jest prowadzony
type
z-a
przełącznikiem, który pokaże wszystkie dostępne instancje polecenia. W moim systemie Arch pokazuje:Należy zauważyć, że
/sbin
,/usr/sbin
i/bin
są wszystkie dowiązania wskazujące/usr/bin
, więc jest tylko jeden zewnętrzny[
:Jak widać,
[
jest to zarówno polecenie wbudowane, jak i polecenie zewnętrzne, to samo dotyczy różnych innych poleceń wbudowanych powłoki. Nie zmienia to jednak faktu, że są one również wbudowanymi powłokami, wkompilowanymi w samą powłokę.źródło
/bin/printf
jest instalowany przezcoreutils
pakiet i/bin/kill
przezutil-linux
.