Warum hat die Fehlermeldung für zwei Doppelpunkte als Befehl (: :) in der Bash drei Doppelpunkte, aber ein einzelner Doppelpunkt gibt keine Ausgabe aus?

27

Wenn ich tippe

::

In eine Bash-Shell bekomme ich:

-bash: ::: command not found

Aber nur eines :führt zu keiner Ausgabe. Warum ist das?

NerdOfLinux
quelle
Kommentare sind nicht für eine längere Diskussion gedacht. Diese Unterhaltung wurde in den Chat verschoben .
Thomas Ward
Wie hängt das mit Ubuntu zusammen?
NerdOfCode
@NerdOfCode genauso wie das ist? meta.askubuntu.com/q/17076/158442
muru

Antworten:

40

Die :Shell eingebaut vs nicht vorhanden::

Der : eingebaute Shell-Befehl existiert (beachte den Unterschied zwischen externen und eingebauten Befehlen ), der nichts bewirkt; es gibt nur Erfolg zurück, genau wie der trueBefehl. Das :eingebaute ist Standard und wird durch den POSIX-Standard definiert , wo es auch als "Null-Dienstprogramm" bezeichnet wird. Es wird häufig zum Testen oder Ausführen von Endlosschleifen wie in verwendetwhile : ; do ...;done

bash-4.3$ type :
: is a shell builtin

Allerdings werden ::- zwei Doppelpunkte zusammen - als ein "Wort" für die Shell interpretiert und es wird davon ausgegangen, dass es sich um einen Befehl handelt, den der Benutzer eingegeben hat. Die Shell überprüft die eingebauten Funktionen und anschließend alle Verzeichnisse in der PATHVariablen auf das Vorhandensein dieses Befehls. Es gibt jedoch weder einen eingebauten :: noch einen externen Befehl ::. Daher erzeugt das einen Fehler.

Was ist ein typisches Format für einen Fehler?

<shell>: <command user typed>: error message

Was Sie also sehen, sind nicht drei Doppelpunkte, sondern das, was Sie eingegeben haben, wurde in das Standardfehlerformat eingefügt.

Beachten Sie auch, dass :dies Befehlszeilenargumente annehmen kann, dh es ist zulässig, Folgendes zu tun:

: :

In diesem Fall betrachtet die Shell dies als zwei "Wörter", von denen eines ein Befehl und das andere ein Positionsparameter ist. Das wird auch keinen Fehler erzeugen! (Siehe auch den historischen Hinweis (weiter unten in dieser Antwort) zur Verwendung von :mit Positionsparametern.)


In anderen Schalen als Bash

Beachten Sie, dass die Formatierung auch zwischen verschiedenen Shells variieren kann. Für bash, kshund ist mkshdas Verhalten konsistent. Zum Beispiel Ubuntus Standard- /bin/shShell (die eigentlich ist /bin/dash):

$ dash
$ ::
dash: 1: ::: not found

Dabei ist 1 die Befehlsnummer (entspricht der Zeilennummer in einem Skript).

csh im Gegensatz dazu erzeugt überhaupt keine Fehlermeldung:

$ csh
% ::
%

Tatsächlich wird bei der Ausführung strace -o csh.trace csh -c ::der Ablaufverfolgungsausgabe in der csh.traceDatei angezeigt, dass sie cshmit dem Beendigungsstatus 0 (keine Fehler) beendet wird. Aber tcshgibt den Fehler aus (allerdings ohne seinen Namen auszugeben):

$ tcsh
localhost:~> ::
::: Command not found.

Fehlermeldungen

Im Allgemeinen sollte das erste Element in der Fehlermeldung der ausführende Prozess oder die ausgeführte Funktion sein (Ihre Shell versucht auszuführen ::, daher kommt die Fehlermeldung von der Shell). Zum Beispiel ist hier der ausführende Prozess stat:

$ stat noexist
stat: cannot stat 'noexist': No such file or directory

Tatsächlich definiert POSIX die perror () -Funktion, die gemäß der Dokumentation ein Zeichenfolgenargument verwendet, eine Fehlermeldung nach dem Doppelpunkt ausgibt und dann eine neue Zeile. Zitat:

Die perror () -Funktion soll die Fehlernummer, auf die über das Symbol errno zugegriffen wird, einer sprachabhängigen Fehlermeldung zuordnen, die wie folgt in den Standardfehlerstrom geschrieben werden soll:

  • Erstens (wenn s kein Nullzeiger ist und das Zeichen, auf das s zeigt, nicht das Nullbyte ist), die Zeichenfolge, auf die s zeigt, gefolgt von einem Doppelpunkt und einem <Leerzeichen>.

  • Dann eine Fehlermeldung gefolgt von einer <newline>.

Und das String-Argument für perror()technisch könnte alles sein, aber der Übersichtlichkeit halber ist es normalerweise der Funktionsname oder argv[0].

Im Gegensatz dazu GNU hat seinen eigenen Satz von Funktionen und Variablen für die Fehlerbehandlung , die ein Programmierer mit verwenden kann , fprintf()um stderrStrom. Wie eines der Beispiele auf der verlinkten Seite zeigt, könnte Folgendes geschehen:

  fprintf (stderr, "%s: Couldn't open file %s; %s\n",
           program_invocation_short_name, name, strerror (errno));

Historische Notiz

In der alten Unix- und Thompson-Shell :wurde mit gotoAnweisung (die laut Benutzer namens Perderabo in diesem Thread keine eingebaute Shell war) gearbeitet. Zitat aus dem Handbuch:

Die gesamte Befehlsdatei wird nach einer Zeile durchsucht, die mit einem: als erstem nicht leeren Zeichen beginnt, gefolgt von einem oder mehreren Leerzeichen und dann der Bezeichnung. Wenn eine solche Zeile gefunden wird, wird der Versatz der Befehlsdatei zur Zeile nach dem Label neu positioniert und beendet. Dadurch wird die Shell auf die beschriftete Zeile übertragen.

Sie könnten also so etwas tun, um ein Endlosschleifenskript zu erstellen:

: repeat
echo "Hello World"
goto repeat
Sergiy Kolodyazhnyy
quelle
Tippfehler "3 Spalten" für "3 Doppelpunkte"
Barmar
1
DOS command.comund Windows cmd.exehaben eine ähnliche, aber entgegengesetzte Situation: Es :handelt sich explizit um ein goto-Label (kein Befehl) und wird häufig als Kommentarzeichen (z :: This is a comment. B. ) umfunktioniert .
Grawity
54

Der letzte Doppelpunkt ist nur ein Teil der Standardmeldung "Nicht gefunden":

$ x
x: command not found
$ ::
::: command not found

Der Grund, warum ein einzelner Doppelpunkt nichts erzeugt, ist, dass : es sich um einen gültigen Befehl handelt - obwohl er nichts tut (außer return TRUE). Aus dem SHELL BUILTIN COMMANDSBereich man bash:

   : [arguments]
          No effect; the command does nothing beyond  expanding  arguments
          and  performing any specified redirections.  A zero exit code is
          returned.

Sie werden es manchmal in Konstruktionen wie sehen

while :
do
  something
done

Siehe zum Beispiel Welchen Zweck erfüllt der eingebaute Doppelpunkt?

Stahlfahrer
quelle
Ja, das ist der umfassendste Kommentar. Viel beredter als meiner. Viel besser erklärt: D
John Orion
8

Versuchen Sie es mit einem anderen nicht vorhandenen Befehl, und Sie werden feststellen, dass der Befehl :auf Englisch seinen normalen Zweck erfüllt:

$ ---
---: command not found
Olorin
quelle
6

Der hinzugefügte Doppelpunkt ist Teil der Fehlermeldung. Wenn man cd owes eingibt bash: cd: ow: No such file or directory, ergibt das, dass der Fehler im zusätzlichen Doppelpunkt steht: No such file or directory

John Orion
quelle
6
$ ::
bash: ::: command not found
$ kkkk
bash: kkkk: command not found

Der dritte ist ein Abstandhalter von der Formatierung

in bash a :ist eine leere Zeilenanweisung

user688056
quelle
4

Sie erhalten 3 Doppelpunkte, da das Fehlerformat einen Doppelpunkt enthält:

bash: <command>: command not found
Schwärmerei
quelle