Dlaczego POSIX wymaga pewnych wbudowanych powłok do zewnętrznej implementacji?


19

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.


Uważam, że jest to sposób na włączenie / wyłączenie wbudowanych funkcji, jeśli jest to pożądane / wymagane.
Izaak

2
Wyłączanie wbudowanego przez usunięcie zewnętrznej implementacji? Teraz nie ma dostępnych poleceń dotyczących nazw printf.
studog

@studog, więc utwórz pusty plik o tej samej nazwie co wbudowany, włącz bit wykonawczy i umieść go w katalogu w PATH. : P
Wildcard

@Wildcard Ściśle zgodna powłoka zobaczyłaby nazwę podczas wyszukiwania, PATHa 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.
Kusalananda

@Kusalananda, ponownie twoje pierwsze zdanie, o to mi chodziło. Dlatego powiedziałem, żeby stworzyć pusty plik.
Wildcard

Odpowiedzi:


15

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ą printfwbudowane, usunięcie /usr/binz PATHpowoduje wywołanie printfzatrzymania działania. Zachowanie zgodne z POSIX, wykazywane przez powłokę Watanabe w trybie zgodności, powoduje ten sam wynik. Zachowanie powłoki, która ma printfwbudowane, jest tak, jakby wywoływała zewnętrzne polecenie.

Podczas gdy zachowanie wszystkich niezgodnych powłok nie zmienia się, jeśli /usr/binzostanie usunięte PATH, 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, PATHaby zatrzymać wyszukiwanie poleceń. PATHpozostaje 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ł wbudowane printenvpolecenie 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 PATHz 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 samym PATH. Wszystko działa spójnie z perspektywy użytkownika i PATHjest narzędziem do kontrolowania, jak to działa.

Dalsza lektura


13

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. printfWbudowaną związane z /usr/bin/printfmoże zostać zastąpione przez /foo/bin/printfpolecenie zewnętrzne przez ustawienie PATH=/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 :

Wiele istniejących implementacji wykonuje regularne operacje wbudowane bez wykonywania wyszukiwania PATH. To zachowanie nie pasuje do tekstu normatywnego i nie pozwala autorom skryptów zastępować zwykłych wbudowanych narzędzi za pomocą specjalnie spreparowanej ścieżki. Ponadto uzasadnienie wyjaśnia, że intencją jest umożliwienie autorom zastąpienia wbudowanych ustawień przez modyfikację PATH, ale nie tak mówi tekst normatywny .

FWIW, nie sądzę też, żeby istniała jakaś powłoka implementująca zmienione wymagania z zaakceptowanego tekstu.


Zobacz także dyskusję na article.gmane.org/gmane.comp.standards.posix.austin.general / ... (i było kilka innych).
Stéphane Chazelas


Nie, (np. Wbudowane printf związane z / usr / bin / printf może zostać zastąpione przez zewnętrzne polecenie / foo / bin / printf poprzez ustawienie PATH = / foo / bin: $ PATH). , to jest nieprawidłowe. Istnienie bądź / oba / którykolwiek /usr/bin/printflub /foo/bin/printfw PATH aktywuje wbudowane printf. Jedyne, co printfzrobi brakujący (w PATH) zewnętrzny , to wyłączenie wbudowanego. (Według litery specyfikacji).
Izaak
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.