Z pytania o to, czy printf jest wbudowanym narzędziem yash , pochodzi ta odpowiedź, która cytuje standard POSIX .
Odpowiedź wskazuje, że sekwencja wyszukiwania POSIX polega na znalezieniu zewnętrznej implementacji żądanego polecenia, a następnie, jeśli powłoka zaimplementowała go jako wbudowaną, uruchom wbudowaną. (Dla wbudowanych, które nie są specjalnymi wbudowanymi ).
Dlaczego POSIX ma takie wymaganie, aby istniała zewnętrzna implementacja przed zezwoleniem na uruchomienie wewnętrznej implementacji?
Wydaje się ... arbitralny, więc jestem ciekawy.
shell
posix
shell-builtin
studog
źródło
źródło
printf
.PATH
a następnie wywołała wbudowane narzędzie, a nie zewnętrzny skrypt. Co jeśli chcesz wywołać zewnętrzny skrypt na swojej ścieżce? Hmm ... Wydaje się, że wymaga to tabeli opisującej różne możliwości. Jest tutaj jeden , ale dla mnie to nie ma sensu.Odpowiedzi:
Jest to reguła „jak gdyby”.
Mówiąc najprościej: Zachowanie powłoki, jak widzą użytkownicy, nie powinno się zmieniać, jeśli implementacja zdecyduje się udostępnić standardowe polecenie zewnętrzne również jako wbudowane powłoki.
Kontrast, który pokazałem na /unix//a/496291/5132 między zachowaniami (z jednej strony) skorup PD Korn, MirBSD Korn i Heirloom Bourne; (z drugiej strony) pociski Z, 93 Korn, Bourne Again i Debian Almquist; i (na chwytającej ręce) powłoka Watanabe podkreśla to.
W przypadku powłok, które nie są
printf
wbudowane, usunięcie/usr/bin
zPATH
powoduje wywołanieprintf
zatrzymania działania. Zachowanie zgodne z POSIX, wykazywane przez powłokę Watanabe w trybie zgodności, powoduje ten sam wynik. Zachowanie powłoki, która maprintf
wbudowane, jest tak, jakby wywoływała zewnętrzne polecenie.Podczas gdy zachowanie wszystkich niezgodnych powłok nie zmienia się, jeśli
/usr/bin
zostanie usuniętePATH
, i nie zachowują się tak, jakby wywoływały zewnętrzne polecenie.To, co standard próbuje Ci zagwarantować, to to, że powłoki mogą wbudowywać wszelkiego rodzaju normalnie zewnętrzne polecenia (lub implementować je jako własne funkcje powłoki), a nadal będziesz mieć takie samo zachowanie z wbudowanych funkcji, jak to robiłeś z zewnętrznymi poleceniami, jeśli dostosujesz,
PATH
aby zatrzymać wyszukiwanie poleceń.PATH
pozostaje narzędziem do wybierania i kontrolowania poleceń, które można wywoływać.(Jak wyjaśniono na /unix//a/448799/5132 , lata temu ludzie wybrali osobowość swojego Uniksa, zmieniając to, co było włączone
PATH
.)Można by pomyśleć, że sprawienie, by polecenie zawsze działało bez względu na to, czy można je znaleźć,
PATH
jest w rzeczywistości celem wbudowania normalnie zewnętrznych poleceń. (Właśnie dlatego mój zestaw narzędzi nosh właśnie uzyskał wbudowaneprintenv
polecenie w wersji 1.38. Chociaż nie jest to powłoka).Ale standard daje ci gwarancję, że zobaczysz to samo zachowanie dla zwykłych poleceń zewnętrznych, które nie są włączone
PATH
z powłoki, jak zobaczysz w innych programach innych niż powłoki wywołujących tęexecvpe()
funkcję, a powłoka nie będzie magicznie mogła uruchamiaj (najwyraźniej) zwykłe polecenia zewnętrzne, których inne programy nie mogą znaleźć przy tym samymPATH
. Wszystko działa spójnie z perspektywy użytkownika iPATH
jest narzędziem do kontrolowania, jak to działa.Dalsza lektura
źródło
To dość absurdalne i dlatego żadna powłoka nie implementuje go w trybie domyślnym.
Średnia za uzasadnienie i jego ilustrujący przykład sugerują, że była to nieudana próba mieć regularny wbudowaną związane ze ścieżką, i niech nadpisanie użytkownika, poprzez ich własny binarny stawienia się przed nią w
PATH
(np.printf
Wbudowaną związane z/usr/bin/printf
może zostać zastąpione przez/foo/bin/printf
polecenie zewnętrzne przez ustawieniePATH=/foo/bin:$PATH
).Jednak standard nie wymagał tego, ale coś zupełnie innego (a także bezużytecznego i nieoczekiwanego).
Możesz przeczytać więcej na ten temat w tym raporcie o błędzie . Cytowanie z końcowego przyjętego tekstu :
FWIW, nie sądzę też, żeby istniała jakaś powłoka implementująca zmienione wymagania z zaakceptowanego tekstu.
źródło
/usr/bin/printf
lub/foo/bin/printf
w PATH aktywuje wbudowane printf. Jedyne, coprintf
zrobi brakujący (w PATH) zewnętrzny , to wyłączenie wbudowanego. (Według litery specyfikacji).