Kolejność plików wykonywalnych rozpoczęła się w bash

14

Jeśli wykonam testpolecenie w bash, test(ocenia wyrażenie warunkowe), uruchomione zostanie wbudowane narzędzie:

$ type test
test is a shell builtin
$ type -a test
test is a shell builtin
test is /usr/local/bin/test
test is /usr/bin/test
$ 

Jednak, jak widać na type -a testpowyższym przykładzie, testw katalogu / usr / local / bin jest jeszcze jeden, a jeszcze inny w katalogu / usr / bin. W jaki sposób są uporządkowane pliki wykonywalne, tj. Czy zawsze preferowane są wbudowane polecenia, a następnie pozostałe polecenia zależą od kolejności katalogów w zmiennej $ PATH? Ponadto, czy można zmienić kolejność uruchamianych plików wykonywalnych, np. Jeśli testwpisuję, to uruchamiane jest / usr / bin / test zamiast wbudowanego bash test?

Jaskółka oknówka
źródło
Możesz podać pełną ścieżkę podczas wywoływania polecenia, np. /usr/bin/test -f "$file"...
jasonwryan
@ jasonwryan Jestem tego świadomy, ale jestem tylko zainteresowany, czy istnieje sposób na zmianę kolejności plików wykonywalnych.
Martin

Odpowiedzi:

25

Najwyższy priorytet to alias bash, następnie specjalne wbudowane (tylko w trybie POSIX), następnie funkcje, następnie wbudowane, a następnie wyszukiwanie $PATH.

Aby uruchomić wbudowane, użyj builtin test.
Aby wykonać zewnętrzną aplikację, należy wyraźne ścieżki: /bin/test.
Aby zignorować funkcje i aliasy, użyj command test.
Aby ominąć tylko alias, użyj \testlub innego rodzaju rozszerzenia.

Możliwe jest wyłączenie / włączenie wbudowanego za pomocą enable test.

(Zaktualizowano zgodnie z komentarzami poniżej)
(Naprawiono niepoprawną edycję administratora, którą wbudowała bash disable- w rzeczywistości jest tylko enable)

gena2x
źródło
1
@ 1_CR gena2x ma rację. Moja odpowiedź pominęła specjalne wbudowane funkcje, które mają pierwszeństwo przed funkcjami zgodnymi z POSIX (chociaż niektóre powłoki nie są zgodne; bash jest zgodny tylko w trybie POSIX).
Gilles „SO- przestań być zły”
1
Sugerowana edit: Pseudonimy są wyłączone, gdy cytujesz polecenia (lub jej części), jak na \testlub 'test'lub tes't'.
John Kugelman
2
To nie jest pełny obraz. Wydaje się, że każdy rodzaj rozszerzenia (w podręczniku bash, wszystkie podstawienia, rozwinięcie tyldy i tak zwane rozszerzenie ) wyłącza aliasy. Próbowałem.
gena2x
1
Cytat ze strony atakujących człowieka. „. Pierwsze słowo każdego prostego polecenia, jeżeli jest cytowany, jest sprawdzana, jeśli ma aliasu Jeśli tak, to słowo zostaje zastąpiony tekstem aliasu Znaki /, $, grawis i =a żaden z wyżej wymienionych metaznaków powłoki lub znaków cytowania wymienionych powyżej może nie występować w nazwie aliasu. ”
John Kugelman
2
+1 za wskazówki pomagające mi znaleźć źródło tych informacji: znajduje się na stronie podręcznika użytkownika bash, w sekcji WYKONANIE POLECEŃ, akapit drugi i trzeci.
twan163
6

Wbudowane polecenia są zawsze preferowane od poleceń zewnętrznych. Uzasadnieniem jest to, że wbudowane polecenie jest szybsze (aw kilku przypadkach, takich jak cdlub , tylko wbudowane polecenie może mieć pożądany efekt).test -o BASH_OPTION

Czasami zewnętrzne polecenie może mieć funkcje, których nie ma wbudowana powłoka. W takim przypadku możesz wywołać zewnętrzne polecenie, podając wyraźną ścieżkę (tj. Zawierającą ukośnik) (pomija to wszelkie obawy dotyczące kolejności w $PATH). Jeśli nie chcesz sztywno kodować ścieżki zewnętrznej, ale chcesz uniemożliwić korzystanie z wbudowanej funkcji, możesz użyć "$(type -P test)"(uwaga kapitału P) w bash, "$(whence -p test)"w ksh i =testw zsh. Innym sposobem wymuszenia użycia polecenia zewnętrznego jest użycie commandwbudowanego ( command -p test …) lub przejście przez envnarzędzie ( env test …).

W Zsh możesz wyłączyć wbudowane za pomocą disable test. Jest to stałe (dla bieżącej powłoki lub podpowłoki), dopóki wbudowane narzędzie nie zostanie ponownie włączone za pomocą enable test. W bash możesz zrobić to samo z, enable -n testaby wyłączyć i enable testwłączyć ponownie.

Możesz użyć aliasu lub funkcji, aby wymusić wykonanie innego polecenia, na przykład alias test=/usr/bin/testlub test () { /usr/bin/test "$@"; }. Jeśli masz taki alias, możesz uniemożliwić jego użycie, cytując dowolną jego część, np. \testWykona normalną funkcję / wbudowane / wyszukiwanie zewnętrzne. Zauważ, że w zależności od powłoki i jej ustawień, definicje aliasów w funkcji mogą być rozszerzane, gdy funkcja jest czytana lub kiedy jest wykonywana. Jeśli zdefiniowałeś funkcję, możesz jej użyć, command testaby zapobiec wyszukiwaniu funkcji oraz wyszukiwaniu aliasów (więc tutaj testwbudowane będą wywoływane, chyba że wyłączone).

Gilles „SO- przestań być zły”
źródło
envczy tutaj też nie byłoby odpowiednie?
Steven Penny
więc jeśli powłoka działa z BusyBox, czy inne, zwykle zewnętrzne polecenia z tego samego BusyBox są uważane za wewnętrzne? np. dodałem pełny dfdo ŚCIEŻKI na pierwszej pozycji, usunąłem alias „df”, which dfpokazuje / opt / bin / df, ale df działa / bin / df -> busybox
papo
@papo which dfniekoniecznie pokazuje, co dfdziała. unix.stackexchange.com/questions/85249/…
Gilles „SO- przestań być zły”