Etwas verwirrt darüber, ob printf in der Yash-Shell ein integrierter Befehl ist oder nicht

Etwas verwirrt darüber, ob printf in der Yash-Shell ein integrierter Befehl ist oder nicht

Die yashSchale verfügt über einen printfeingebauten,gemäß Handbuch.

Dies ist jedoch, was ich in einer yashShell mit Standardkonfiguration sehe:

$ command -v printf
/usr/bin/printf
$ type printf
printf: a regular built-in at /usr/bin/printf

Ist printfin 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( kshunter OpenBSD, wo printfistnichtein 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 yashMuscheltuthat 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 -vund formuliert type.

Wie Mosvy kommentierterfordert der POSIX-Standard, dass ein regulärer integrierter Befehl als externer Befehl verfügbar ist, $PATHdamit 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:

  1. 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.
  2. Wenn der Befehlsname mindestens einen <Schrägstrich> enthält, [...]

Das bedeutet, dass die Ausgabe von command -v printfbedeutet, dass der printfBefehlWarim Suchpfad gefunden, während die Ausgabe von type printfhinzufügt, dass der Befehl ein reguläres integriertes ist.

Da der printfBefehl im Suchpfad gefunden wurde und in der Shell regulär integriert ist,yashruft die integrierte Version des Befehls aufWenn das printfwarnichtim Pfad gefunden und wenn die yashShell im POSIX-korrekten Modus ausgeführt würde, wäre stattdessen ein Fehler generiert worden.

yashist 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 aufzurufen command_name.

  • Dienstprogramme,reguläre integrierte Dienstprogramme, command_nameseinschließlich eines <slash>Zeichens, und alle implementierungsdefinierten Funktionen, die mit der PATHVariable 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.

printfist 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-correctShell-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 shmit 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, printfwenn es nicht eingeschaltet ist, PATHist das Verhalten der PD Korn-Shell, der Heirloom Bourne-Shell und der MirBSD Korn-Shell, da sie printfvon 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 ...]
$

verwandte Informationen