Nieznacznie zdezorientowany, czy printf w powłoce yash jest wbudowanym poleceniem, czy nie


14

yashPowłoka posiada printfwbudowany, zgodnie z instrukcją .

Jednak to widzę w yashpowłoce z domyślną konfiguracją:

kk@eeyore ~ $ command -v printf
/usr/bin/printf
kk@eeyore ~ $ type printf
printf: a regular built-in at /usr/bin/printf

Czy printfjest wbudowany w tę powłokę, czy nie? Wynik jest podobny w przypadku wielu innych rzekomo wbudowanych narzędzi, które są również dostępne jako polecenia zewnętrzne.

Dla porównania, w pdksh( kshw OpenBSD, gdzie printfjest nie wbudowany):

$ command -v printf
/usr/bin/printf
$ type printf
printf is /usr/bin/printf

I w bash(gdzie printf jest wbudowany):

$ command -v printf
printf
$ type printf
printf is a shell builtin

1
Jest wbudowany - zwykły , a nie specjalny wbudowany. Jeśli jesteś zdezorientowany co do różnicy między specjalnymi i zwykłymi wbudowanymi funkcjami lub zachowaniem nakazanym przez standard (patrz wyszukiwanie poleceń i wykonywanie 1.eia) - co wymaga, aby plik binarny istniał PATHw celu regularnego wbudowanego do wykonania - zadaj pytanie na ten temat.
mosvy

1
@mosvy To był szczegół standardu, który był mi nieznany. Jeśli chcesz zmienić to w odpowiedź, byłbym szczęśliwy. Nie sądzę, że musiałbym zaktualizować pytanie, aby była to odpowiednia odpowiedź, ponieważ nie byłem świadomy tego konkretnego szczegółu. Albo napiszę to później.
Kusalananda

Odpowiedzi:


14

yashPowłoka nie mają, a nie wykorzystania, wbudowany w wersję printf(i innych narzędzi). Zdarza się, że jest bardzo pedantycznie zgodny ze standardem POSIX w sposobie formułowania wyniku poleceń command -vi type.

W komentarzach mosvy standard POSIX wymaga, aby regularne wbudowane polecenie było dostępne jako polecenie zewnętrzne w $PATHcelu wykonania wbudowanej wersji polecenia.

To jest odpowiedni tekst standardu :

Wyszukiwanie i wykonywanie poleceń

Jeśli proste polecenie daje nazwę polecenia i opcjonalną listę argumentów, należy wykonać następujące czynności:

  1. Jeśli nazwa polecenia nie zawiera żadnych znaków <ukośnik>, nastąpi pierwszy udany krok w następującej kolejności:

    • za. Jeśli nazwa polecenia jest zgodna z nazwą specjalnego wbudowanego narzędzia, należy wywołać to specjalne wbudowane narzędzie.

      [...]

    • mi. W przeciwnym razie polecenie należy wyszukać za pomocą zmiennej środowiskowej PATH, jak opisano w zmiennych środowiskowych XBD:
      • ja. Jeśli wyszukiwanie się powiedzie:
        • za. Jeśli system zaimplementował narzędzie jako zwykłą funkcję wbudowaną lub funkcję powłoki, należy je wywołać w tym punkcie wyszukiwania ścieżki.
        • b. W przeciwnym razie powłoka wykonuje narzędzie w oddzielnym środowisku narzędzia [...]
          [...]
      • ii. Jeśli wyszukiwanie się nie powiedzie, polecenie zakończy się niepowodzeniem ze statusem wyjścia 127 i powłoka zapisze komunikat o błędzie.
  2. Jeśli nazwa polecenia zawiera co najmniej jeden <slash>, [...]

Oznacza to, że dane wyjściowe command -v printfoznaczają, że printfpolecenie zostało znalezione w ścieżce wyszukiwania, a dane wyjściowe type printfdodają, że polecenie jest normalnie wbudowane.

Ponieważ printfpolecenie zostało znalezione w ścieżce wyszukiwania, a ponieważ jest ono normalnie wbudowane w powłokę, yashwywoła swoją wbudowaną wersję polecenia . Jeśli printfbył nie znalazł się na ścieżce, a jeśli yashpowłoka została uruchomiona w POSIX-ly właściwym trybie, błąd zostałby wygenerowany zamiast.

yashszczyci się tym, że jest powłoką bardzo zgodną z POSIX, i jest to również prawdą, jeśli spojrzymy na to, co mówi POSIXcommand -v :

-v

Napisz ciąg do standardowego wyjścia, który wskazuje nazwę ścieżki lub polecenie, które będzie używane przez powłokę, w bieżącym środowisku wykonywania powłoki (patrz Środowisko wykonywania powłoki ), aby wywoływać command_name, ale nie wywoływać command_name.

  • Narzędzia, regularne wbudowane narzędzia , command_namesw tym <slash>charakterze, oraz wszelkich funkcji wykonawczych zdefiniowane, które znajdują się za pomocą PATHzmiennej (jak opisano w polecenia wyszukiwania i wykonanie ), powinien być zapisany jako bezwzględnych ścieżek .

3
Czy ktoś wie, dlaczego POSIX ma takie wymaganie, aby istniała komenda zewnętrzna przed uruchomieniem komendy wbudowanej?
studog

@studog Możesz zadać to pytanie jako osobne nowe pytanie, prawdopodobnie odnosząc się do tej odpowiedzi i / lub pytania.
Kusalananda


6

Powłoka Watanabe ma trzy rodzaje wbudowanych elementów, szczegółowo opisanych w instrukcji. Wszystkie wbudowane polecenia są tam również wymienione, ale należy wnioskować, że coś jest „zwykłym” wbudowanym poleceniem na podstawie braku jakiejkolwiek uwagi mówiącej, że polecenie jest „specjalne” lub „pół-specjalne” wbudowany Zwykłe wbudowane elementy są nieoznaczone.

printfjest jednym z takich „zwykłych” wbudowanych. W trybie natywnym jest zawsze wywoływane, niezależnie od tego, czy istnieje taka komenda zewnętrzna.

$ PATH = / usr / bin 
$ printf
printf: to polecenie wymaga operandutyp 
$ printf
printf: zwykłe wbudowane w / usr / bin / printf
$
$ PATH = / 
$ printf
printf: to polecenie wymaga operandutyp 
$ printf
printf: zwykłe wbudowane (nie znaleziono w $ PATH)
$

Ale gdy posixly-correctustawiona jest opcja powłoki, jest ona wbudowana tylko wtedy, gdy zewnętrzne polecenie można znaleźć w PATH.

$ set --poprawnie poprawne
$
$ PATH = / usr / bin 
$ printf
printf: to polecenie wymaga operandu
$
$ PATH = / 
$ printf
yash: nie ma takiego polecenia `printf '
$

Jest to faktycznie zgodne z tym, co mówi specyfikacja Single Unix i co najmniej od 1997 roku.

Różni się od powłoki Z, powłoki 93 Korn, powłoki Bourne Again i powłoki Debian Almquist, z których żadna z nich nie implementuje ani nie dokumentuje takiego zachowania w przypadku zwykłych wbudowań. Na przykład powłoka Z zawiera dokumenty, w których zawsze znajdują się zwykłe wbudowane elementy , przed przeszukiwanym krokiem PATH. Podobnie jest z powłoką Debian Almquist. I to właśnie robią wszystkie te powłoki, nawet jeśli są wywoływane tak, jak w shprzypadku ich opcji włączania POSIX.

% / bin / exec -a sh zsh -c "ŚCIEŻKA = /; wpisz printf; printf"
printf jest wbudowaną powłoką
zsh: printf: 1: za mało argumentów
% / bin / exec -a sh ksh93 -c "ŚCIEŻKA = /; wpisz printf; printf"
printf jest wbudowaną powłoką
Zastosowanie: printf [opcje] format [ciąg ...]
% / bin / exec -a sh bash --posix -c "ŚCIEŻKA = / type printf; printf"
printf jest wbudowaną powłoką
printf: użycie: printf [-v var] format [argumenty]
% / bin / exec -a sh dash -c "ŚCIEŻKA = /; wpisz printf; printf"
printf jest wbudowaną powłoką
sh: 1: printf: wykorzystanie: format printf [arg ...]
% 

Jednak nie działa, printfgdy nie jest włączony, PATHjest zachowanie powłoki PD Korn, powłoki Heirloom Bourne i powłoki MirBSD Korn; ponieważ printfprzede wszystkim nie mają wbudowanego. ☺

% / bin / exec -a sh `polecenie -v ksh` -c" ŚCIEŻKA = /; wpisz printf; printf "
nie znaleziono printf
sh: printf: nie znaleziono
% / bin / exec -a sh `polecenie -v oksh` -c" ŚCIEŻKA = /; wpisz printf; printf "
nie znaleziono printf
sh: printf: nie znaleziono
% / bin / exec -a sh `polecenie -v jsh` -c" ŚCIEŻKA = /; wpisz printf; printf "
nie znaleziono printf
sh: printf: nie znaleziono
% / bin / exec -a sh mksh -c "ŚCIEŻKA = /; wpisz printf; printf"
nie znaleziono printf
sh: printf: nie znaleziono
% ksh -c "typ printf; printf"
printf to śledzony alias dla / usr / bin / printf
użycie: format printf [argumenty ...]
% oksh -c "typ printf; printf"
printf to śledzony alias dla / usr / bin / printf
użycie: format printf [argumenty ...]
% jsh -c "typ printf; printf"
printf jest hashed (/ usr / bin / printf)
użycie: format printf [argumenty ...]
% mksh -c "typ printf; printf"
printf to śledzony alias dla / usr / bin / printf
użycie: format printf [argumenty ...]
$

Dobry! Dziękuję za potwierdzenie i dodanie do mojej wiedzy bitów specyficznych dla powłoki! Już bardziej podoba mi się ta skorupa.
Kusalananda

-1

Sformułowanie można poprawić.

Jeśli powłoka jest w trybie posix set --posixly-correct:

W przypadku zwykłych wbudowań, które nie istnieją w ŚCIEŻCE, jest to drukowane:

pushd: a regular built-in (not found in $PATH)

Co jest jasnym opisem: jest wbudowany, ale nie ma pliku wykonywalnego o tej samej nazwie w ścieżce PATH.

Jednak w przypadku zwykłych wbudowań, których nazwy istnieją również w ścieżce, jest to drukowane:

echo: a regular built-in at /bin/echo

Co wydaje się sugerować, że plik wykonywalny w / bin / echo zostanie wykonany (co nie będzie). I sugerują, że zmiana z atcelu also found in PATH at:

echo: a regular built-in also found in PATH at /bin/echo

byłby lepszy opis. Może ujęcie tego w nawiasie (tak jak w przypadku drugiej odpowiedzi) mogłoby to poprawić.


W trybie POSIX żadne wbudowane narzędzie nie będzie działać, chyba że zostanie również znalezione w ŚCIEŻCE.

Jednak oba (POSIX) specjalne:

break colon continue dot eval exec exit export
readonly return set shift times trap unset

I pół-specjalne yash (nie specjalne dla POSIX):

alias bg cd command false fc fg getopts jobs
kill pwd read true umask unalias wait

wbudowane nadal działają.

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.