
Die yash
Schale verfügt über einen printf
eingebauten,gemäß Handbuch.
Dies ist jedoch, was ich in einer yash
Shell mit Standardkonfiguration sehe:
$ command -v printf
/usr/bin/printf
$ type printf
printf: a regular built-in at /usr/bin/printf
Ist printf
in dieser Shell ein integriertes Dienstprogramm enthalten oder nicht? Das Ergebnis ist für eine Reihe anderer angeblich integrierter Dienstprogramme, die auch als externe Befehle verfügbar sind, ähnlich.
Zum Vergleich: In pdksh
( ksh
unter OpenBSD, wo printf
istnichtein eingebautes):
$ command -v printf
/usr/bin/printf
$ type printf
printf is /usr/bin/printf
Und in bash
(woprintf
Istein eingebautes):
$ command -v printf
printf
$ type printf
printf is a shell builtin
Antwort1
die yash
Muscheltuthat und verwendet eine integrierte Version von printf
(und anderen Dienstprogrammen). Es ist nur sehr pedantisch POSIX-kompatibel in der Art und Weise, wie es das Ergebnis der Befehle command -v
und formuliert type
.
Wie Mosvy kommentierterfordert der POSIX-Standard, dass ein regulärer integrierter Befehl als externer Befehl verfügbar ist, $PATH
damit die integrierte Version des Befehls ausgeführt werden kann.
Das istder entsprechende Text aus der Norm:
Befehlssuche und -ausführung
Wenn ein einfacher Befehl einen Befehlsnamen und eine optionale Liste von Argumenten ergibt, sollen die folgenden Aktionen ausgeführt werden:
Wenn der Befehlsname keine <Slash>-Zeichen enthält, erfolgt der erste erfolgreiche Schritt in der folgenden Sequenz:
a. Wenn der Befehlsname mit dem Namen eines speziellen integrierten Dienstprogramms übereinstimmt, soll dieses spezielle integrierte Dienstprogramm aufgerufen werden.
[...]
- e. Andernfalls soll nach dem Befehl mithilfe der Umgebungsvariable PATH gesucht werden, wie in XBD-Umgebungsvariablen beschrieben:
- ich.Wenn die Suche erfolgreich ist:
- A.Wenn das System das Dienstprogramm als reguläre integrierte Funktion oder als Shell-Funktion implementiert hat, soll es an diesem Punkt der Pfadsuche aufgerufen werden.
- b. Andernfalls führt die Shell das Dienstprogramm in einer separaten Dienstprogrammumgebung aus [...]
[...]- ii. Wenn die Suche nicht erfolgreich ist, schlägt der Befehl mit einem Exit-Status von 127 fehl und die Shell schreibt eine Fehlermeldung.
- Wenn der Befehlsname mindestens einen <Schrägstrich> enthält, [...]
Das bedeutet, dass die Ausgabe von command -v printf
bedeutet, dass der printf
BefehlWarim Suchpfad gefunden, während die Ausgabe von type printf
hinzufügt, dass der Befehl ein reguläres integriertes ist.
Da der printf
Befehl im Suchpfad gefunden wurde und in der Shell regulär integriert ist,yash
ruft die integrierte Version des Befehls aufWenn das printf
warnichtim Pfad gefunden und wenn die yash
Shell im POSIX-korrekten Modus ausgeführt würde, wäre stattdessen ein Fehler generiert worden.
yash
ist stolz darauf, eine sehr POSIX-kompatible Shell zu sein, und das gilt auch, wenn wir uns ansehenwas POSIX sagt übercommand -v
:
-v
Schreibt einen String in die Standardausgabe, der den Pfadnamen oder Befehl angibt, der von der Shell in der aktuellen Shell-Ausführungsumgebung verwendet wird (sieheShell-Ausführungsumgebung), um aufzurufen
command_name
, aber nicht aufzurufencommand_name
.
- Dienstprogramme,reguläre integrierte Dienstprogramme,
command_names
einschließlich eines<slash>
Zeichens, und alle implementierungsdefinierten Funktionen, die mit derPATH
Variable gefunden werden (wie beschrieben inBefehlssuche und -ausführung),sollen als absolute Pfadnamen geschrieben werden.
Antwort2
Die Watanabe-Shell hat drei Arten von eingebauten Befehlen, die im Handbuch ausführlich beschrieben werden. Alle eingebauten Befehle sind dort auch aufgeführt, aber man muss daraus schließen, dass es sich um einen "normalen" eingebauten Befehl handelt, wennAbwesenheitvon jedem Hinweis, der besagt, dass der Befehl ein „spezieller“ oder „halbspezieller“ integrierter Befehl ist. Normale integrierte Befehle sind nicht markiert.
printf
ist ein solches "normales" eingebautes. Im nativen Modus ist esstetsaufgerufen, unabhängig davon, ob ein externer Befehl mit diesem Namen gefunden wird.
$PATH=/usr/bin $druckenf printf: dieser Befehl erfordert einen Operanden $Typ printf printf: ein reguläres integriertes Element unter /usr/bin/printf $ $PFAD=/ $druckenf printf: dieser Befehl erfordert einen Operanden $Typ printf printf: ein reguläres integriertes Feature (nicht in $PATH gefunden) $
Wenn die posixly-correct
Shell-Option jedoch gesetzt ist, handelt es sich nur dann um eine integrierte Funktion, wenn der externe Befehl auf gefunden werden kann PATH
.
$--posixly-correct festlegen $ $PATH=/usr/bin $druckenf printf: dieser Befehl erfordert einen Operanden $ $PFAD=/ $druckenf yash: kein solcher Befehl „printf“ $
Dies entspricht tatsächlich den Angaben der Single Unix Specification, und zwar seit mindestens 1997.
Es unterscheidet sich von der Z-Shell, der 93 Korn-Shell, der Bourne Again-Shell und der Debian Almquist-Shell, von denen keine ein solches Verhalten für reguläre integrierte Ins implementiert oder dokumentiert. Die Z-Shell dokumentiert beispielsweise, dass reguläre integrierte Insstetsgefunden,Vorder Schritt, der sucht PATH
. Dasselbe tut die Debian Almquist-Shell. Und genau das tun diese Shells alle, auch wenn sie sh
mit ihren Turn-on-POSIX-Optionen aufgerufen werden.
%/bin/exec -a sh zsh -c "PATH=/ ; Typ printf ; printf" printf ist eine Shell-integrierte zsh:printf:1: nicht genügend Argumente %/bin/exec -a sh ksh93 -c "PATH=/ ; Typ printf ; printf" printf ist eine Shell-integrierte Verwendung: printf [Optionen] Format [Zeichenfolge ...] %/bin/exec -a sh bash --posix -c "PATH=/ Typ printf; printf" printf ist eine Shell-integrierte printf: Verwendung: printf [-v var] Format [Argumente] %/bin/exec -a sh dash -c "PATH=/ ; Typ printf ; printf" printf ist eine Shell-integrierte sh: 1: printf: Verwendung: printf-Format [Argument …] %
Dass es nicht läuft, printf
wenn es nicht eingeschaltet ist, PATH
ist das Verhalten der PD Korn-Shell, der Heirloom Bourne-Shell und der MirBSD Korn-Shell, da sie printf
von vornherein über keine integrierte Funktion verfügen. ☺
%/bin/exec -a sh `Befehl -v ksh` -c "PATH=/ ; Typ printf ; printf" printf nicht gefunden sh: printf: nicht gefunden %/bin/exec -a sh `Befehl -v oksh` -c "PATH=/ ; Typ printf ; printf" printf nicht gefunden sh: printf: nicht gefunden %/bin/exec -a sh `Befehl -v jsh` -c "PATH=/ ; Typ printf ; printf" printf nicht gefunden sh: printf: nicht gefunden %/bin/exec -a sh mksh -c "PATH=/ ; Typ printf ; printf" printf nicht gefunden sh: printf: nicht gefunden %ksh -c "Typ printf; printf" printf ist ein verfolgter Alias für /usr/bin/printf Verwendung: printf-Format [Argumente ...] %oksh -c "Typ printf; printf" printf ist ein verfolgter Alias für /usr/bin/printf Verwendung: printf-Format [Argumente ...] %jsh -c "Typ printf; printf" printf wird gehasht (/usr/bin/printf) Verwendung: printf-Format [Argumente ...] %mksh -c "Typ printf; printf" printf ist ein verfolgter Alias für /usr/bin/printf Verwendung: printf-Format [Argumente ...] $