Was bedeutet der Gedankenstrich "-" vor "Bash" bei "Befehl nicht gefunden" -Fehlern?

28

Wenn Sie an einer Bash-Eingabeaufforderung einen ungültigen Befehl eingeben, wird die Meldung angezeigt

-bash: {command}: command not found

Was bedeutet das ganz -am Anfang?

Evan Purkhiser
quelle
Wie genau führen Sie den Befehl aus? Ich habe versucht, zu replizieren, aber ich erhalte nicht die gleichen Ergebnisse - z. B.> jhgjbjbkjln: command not found- nein -bash: . Verwenden Sie bashin Unix, Linux, OSX, ...? Ich frage, weil dies möglicherweise eine bestimmte Implementierung ist, die standardmäßig vor die Fehlermeldung gestellt wird, und sie nichts bedeutet ... vielleicht.
Jimmy-Cl
@jim Versuchen Sie ssh computernameund Ihr Befehl nicht zu zählen, um zu replizieren.
Bernhard

Antworten:

27

Dies bedeutet, dass es sich um eine Anmeldeshell handelt.

Von man bash:

Eine Login-Shell ist eine Shell, deren erstes Zeichen des Arguments Null ein - ist, oder eine Shell, die mit der Option --login gestartet wurde.

(In der bashTerminologie ist das "nullte" Argument der Befehlsname, der in Ihrem Fall lautete bash.) bashVerwendet diesen als Signal für Anmeldeaktivitäten wie das Ausführen .bash_profileusw.

Ein Weg, wie der Bindestrich automatisch hinzugefügt werden kann, ist, wenn die Shell mit gestartet wird exec. Aus dem Bash-Handbuch :

exec [-cl] [-a name] [command [arguments]]

[...] Wenn die -lOption angegeben ist, setzt die Shell einen Bindestrich am Anfang des nullten Arguments, das an command übergeben wird .

Beispiel

Vergleichen Sie diese beiden Versuche, um den Befehl auszuführen nonexistent. Zuerst ohne -l:

$ exec bash
$ nonexistent
bash: nonexistent: command not found

Und zweitens mit:

$ exec -l bash
$ nonexistent
-bash: nonexistent: command not found
John1024
quelle
3
Ich denke, der Teil der Dokumentation, den Sie zitieren, stimmt nicht mit Ihrer Erklärung überein. Die Tatsache , dass exec -lein Strich prepends ist eine mögliche Art und Weise , die bash verursachen kann wie ausgeführt werden -bash, aber das allein sagt nicht , dass es sich um ein Login - Shell ist, und es gibt eine sehr gute Chance , dass die OP nicht verwendet hat exec -lüberhaupt . Der Teil der Dokumentation, der besagt, -bashdass es sich um eine Anmeldeshell handelt, lautet "INVOCATION Eine Anmeldeshell ist eine Shell, deren erstes Zeichen des Arguments Null ein - ist, oder eine Shell, die mit der Option --login gestartet wurde."
HDV
@hvd, einverstanden. Diese Antwort ist zwar richtig, geht aber am eigentlichen Punkt vorbei.
Stéphane Chazelas
1
"Das nullte Argument" ist keine bashTerminologie, sondern Unix-Konvention + C-Indizierung: Jedem Programm wird eine Parameterliste übergeben, deren erster Eintrag der Programmname ist, gefolgt von den Argumenten. Da C-Arrays beginnend mit Null indiziert werden, ist das Argument Null (
dh
15

Die andere Antwort ist in Ordnung, aber es ist erwähnenswert, dass die Funktion allgemeiner ist als bash.

Seit loginjeher hat das Programm der Ausführung argv[0]der Benutzer-Shell einen Gedankenstrich vorangestellt , und die Shell hat dies als Zeichen dafür erkannt, dass sie sich als "Anmelde-Shell" verhalten sollte. Dies ist in den V7-Manpages hier dokumentiert: login (1) , sh (1) .

Alle Programme, die einen anmeldungsähnlichen Dienst bereitstellen (Benutzer authentifizieren und eine Shell ausführen), sollten der Regel "Bindestrich voranstellen" folgen. Zum Beispiel macht sshd, wie Sie in ssh / session.c unter diesem Kommentar sehen können:

/*
 * If we have no command, execute the shell.  In this case, the shell
 * name to be passed in argv[0] is preceded by '-' to indicate that
 * this is a login shell.
 */

Alle Muscheln erkennen den führenden Strich. Die entsprechende -lOption gibt es in der klassischen Bourne-Shell oder der ursprünglichen csh nicht, aber die meisten neueren Shells (bash, dash, ksh, yash, tcsh, zsh, rc, es, fish und alle neueren Versionen von csh) haben sie.

Stéphane Chazelas
quelle
2
Obwohl die meisten Shells jetzt die -lOption haben, wird sie loginimmer noch nicht verwendet. Von allen Shells wird erwartet, dass sie das Präfix argv[0]als "offiziellen" Mechanismus erkennen.
Barmar