Jaka jest różnica między poleceniami wbudowanymi w cd i cd?

Odpowiedzi:

41

cdKomenda jest wbudowany, więc zazwyczaj builtin cdzrobi to samo co cd. Istnieje jednak różnica, jeśli cdzostanie ona ponownie zdefiniowana jako funkcja lub alias, w którym to przypadku cdwywoła funkcję / alias, ale builtin cdnadal zmieni katalog (innymi słowy, zachowa dostęp do wbudowanej funkcji, nawet jeśli zostanie zablokowana przez funkcję).

Na przykład:

user:~$ cd () { echo "I won't let you change directories"; }
user:~$ cd mysubdir
I won't let you change directories
user:~$ builtin cd mysubdir
user:~/mysubdir$ unset -f cd  # undefine function

Lub z aliasem:

user:~$ alias cd='echo Trying to cd to'
user:~$ cd mysubdir
Trying to cd to mysubdir
user:~$ builtin cd mysubdir
user:~/mysubdir$ unalias cd  # undefine alias

Użycie builtinjest również dobrym sposobem na zdefiniowanie cdfunkcji, która coś robi i zmienia katalog (ponieważ wywołanie cdz niej po prostu wywoływałoby funkcję ponownie w nieskończonej rekurencji).

Na przykład:

user:~ $ cd () { echo "Changing directory to ${1-home}"; builtin cd "$@"; }
user:~ $ cd mysubdir
Changing directory to mysubdir
user:~/mysubdir $ cd
Changing directory to home
user:~ $ unset -f cd  # undefine function
filbranden
źródło
5
+1 Przykłady są tutaj szczególnie ilustracyjne.
Tashus
2
Czy w przypadku aliasu istnieje różnica między builtin cd mysubdiri \cd mysubdir?
gerrit 19.01.19
2
@gerrit Tylko jeśli istnieje funkcja o nazwie cd, w takim przypadku pominie \cdalias i uruchomi funkcję. Zobacz stackoverflow.com/a/16506263/4518341
wjandrea
15

W większości przypadków nie ma różnicy (ale patrz poniżej). cdPolecenie jest wbudowane polecenie we wszystkich muszli. Musi być wbudowany 1, ponieważ zewnętrzne polecenie nie może zmienić środowiska powłoki wywołującej, a zmiana katalogu roboczego stanowi zmianę w jego środowisku.

Na bashpolecenie builtinsiły powłoka użyć wbudowanego w wersji polecenia, choć może istnieć funkcja powłoki, alias lub komenda zewnętrzna dostępna z tej samej nazwie.

W przypadku tam gdzie jest np funkcję powłoki z nazwą cd, to builtin cdbyłoby nie nazwać. Użycie builtin cdpomija wszelkie przeciążone funkcje, które użytkownik mógł dodać za pomocą funkcji powłoki lub aliasu.

Przykład:

cdWbudowanego polecenia mogą być przeciążone przez funkcję, która zaktualizuje komunikat:

cd() {
    builtin cd "$@" && PS1=$(__update_prompt)
}

gdzie __update_promptjest inna funkcja dostarczona przez użytkownika, która generuje ciąg znaków.

Funkcja builtin cdin nie wywołałaby funkcji rekurencyjnie. Użycie builtin cdw powłoce, w której ta funkcja jest aktywna, dodatkowo nie wywołałoby tej funkcji.


1 Są Unices z zewnętrznym cdpoleceniem (macOS i, jak sądzę, Solaris). Celem tego polecenia, które nie może zmienić katalogu roboczego powłoki, jest prawdopodobnie spełnienie standardu POSIX, który wymienia cdjako jedno z zewnętrznych narzędzi, które powinny być dostępne ( cdnie jest to jeden z „specjalnych wbudowanych narzędzi”) . Może również służyć jako test sprawdzający, czy możliwa jest zmiana katalogu roboczego na dany katalog .

Kusalananda
źródło
FWIW, MacOS należałoby również do kategorii systemów operacyjnych z zewnętrznym cdpoleceniem.
yoann
@yoann Rzeczywiście tak jest.
Kusalananda
Dziękuję - sprawiłeś, że mój dzień był na najwyższym poziomie, dobrze zbadany, z przypisaną pedantrią.
James
większość powłok - jest to zewnętrzny program do execlineb, ale potem cd wykona pozostałe argumenty
Grump