Warum steht bei „$0“ auf dem Mac ein Minuszeichen?

Warum steht bei „$0“ auf dem Mac ein Minuszeichen?

Ich bin seit Jahren ein GNU/Linux-Benutzer, kann aber nicht herausfinden, wie ich auf dem Mac an verwertbare Prozessinformationen komme.

Mir ist aufgefallen, dass dies in meiner Login-Shell unter Mac OS (Snow Leopard) $0funktioniert .-bashDies kann dazu führen, dass bestimmte Shell-Skripte, die in einer Linux-Umgebung einwandfrei funktionieren, nicht mehr funktionieren.*.

Leider wird dies in der Manpage nicht erwähnt.

Wenn bash mit einer Datei mit Befehlen aufgerufen wird, wird $0 auf den Namen dieser Datei gesetzt. Wenn bash mit der Option -c gestartet wird, wird $0 auf das erste Argument nach der auszuführenden Zeichenfolge gesetzt, falls eine solche vorhanden ist. Andernfalls wird es auf den Dateinamen gesetzt, der zum Aufrufen von bash verwendet wird und durch das Argument Null angegeben wird.

Hat das Minuszeichen eine besondere Bedeutung? Gibt es so etwas /procoder ein Kommandozeilentool, das mir beim Auffinden der zugehörigen ausführbaren Datei helfen könnte?

* Dumm von mir. Natürlich wird $0 als Skriptname ausgewertet, wie im Handbuch angegeben

Antwort1

Das Minuszeichen ist die Art und Weise, wie das System der Shell mitteilt, dass sie als Login-Shell aufgerufen wird und dass sie als Quelle verwendet werden soll ~/.profile(für Bourne-kompatible Shells). Dies gilt für Linux, OSX und alle anderen Unix-Versionen. Ein Skript würde nicht in einer Login-Shell ausgeführt. Für ein Skript $0ist dies der Name der Skriptdatei (mit oder ohne vollständigen Pfad).

HINZUGEFÜGT: Die Manpage erklärt (fast alle) verschiedenen Fälle:

  • „Wenn Bash mit einer Befehlsdatei aufgerufen wird, wird $0 auf den Namen dieser Datei gesetzt.“ Dies gilt sowohl für mit ausgeführte Skripte bash myscriptals auch für den indirekten Fall, in dem das Skript direkt ausgeführt wird und mit beginnt #!/bin/bash.

  • „Wenn bash mit der Option -c gestartet wird, wird $0 auf das erste Argument nach dem auszuführenden String gesetzt, sofern ein solcher vorhanden ist.“ Mit -cwird $0auf das gesetzt, was der Anrufer explizit angibt.

  • „Andernfalls wird es auf den Dateinamen gesetzt, der zum Aufrufen von Bash verwendet wird, wie durch das Argument Null angegeben.“ Eine Login-Shell fällt in diesen Fall: Die Shell wird ohne andere Argumente als das Argument Null aufgerufen und $0ist daher auf das Argument Null gesetzt. Es ist login, su, oder welches Programm auch immer die Anmeldung verarbeitet hat, das die Argumente auswählt, die es an die Shell übergibt, und -dem Argument Null ein voranstellt, um der Shell mitzuteilen, dass es sich um eine Login-Shell handelt.

Vielleicht ist eine Erklärung des Arguments Null angebracht. Wenn ein Programm ausgeführt wird, execveerfolgt letztendlich ein Systemaufruf. Dieser Systemaufruf benötigt drei Argumente:

  1. ein Dateiname, der eine vorhandene, ausführbare Datei bezeichnen muss. Der Kernel lädt diese Datei und überträgt ihr die Ausführung.

  2. ein Array von Strings, die Argumente genannt werden. Das Element Null in diesem Array istvereinbarungsderselbe Dateiname wie oben oder nur der Dateiname ohne den vollständigen Pfad, wenn der Speicherort der ausführbaren Datei durch Durchsuchen der $PATHUmgebungsvariable ermittelt wurde. Es gibt Ausnahmen von dieser Konvention, z. B. Login-Shells.

  3. ein weiteres Array von Zeichenfolgen, das als Umgebung bezeichnet wird.

Wenn Sie ein Programm aus der Shell aufrufen myprogram foo bar, indem Sie eingeben, lauten die Argumente für execve:
    1. /usr/bin/myprogram(vorausgesetzt, die Shell hat hier gefunden myprogram)
    2. myprogram, foo, bar
    3. für jede exportierte Shell-Variable der Variablenname, gefolgt von einem Gleichheitszeichen und dem Wert.

Es gibt keine allgemeine Möglichkeit, den Namen der ausführbaren Datei zu finden, die execvevom laufenden Programm übergeben wurde. Unter Linux ist er normalerweise verfügbar, /proc/$$/exewobei $$die Prozess-ID ist. Jedes Unix macht ihn verfügbar, psaber die Funktionsweise psunterscheidet sich stark. Die ausführbare Datei kann gelöscht oder umbenannt werden, während das Programm ausgeführt wird. In diesem Fall pswerden möglicherweise veraltete oder gar keine Informationen gemeldet.

Antwort2

Aus man bash:

exec [-cl] [-a Name] [Befehl [Argumente]]
Wenn Befehl angegeben ist, ersetzt er die Shell. Es wird kein neuer Prozess erstellt. Die Argumente werden zu den Argumenten für Befehl. Wenn die Option -l angegeben ist, setzt die Shell einen Bindestrich an den Anfang des nullten Arguments, das an Befehl übergeben wird. Dies ist, was login(1) macht. ...

Antwort3

Ich bin nicht sicher, was mit -bash los ist, aber wenn Sie bash erneut in der Shell ausführen, scheint der Wert $0 in Ordnung zu sein.

Es scheint sich um eine spezielle Funktion von OS X zu handeln, denn wenn Sie /usr/bin/login ausführen, das vom Terminalprogramm verwendete Standardskript, tritt dasselbe Problem mit $0 auf.

verwandte Informationen