
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) $0
funktioniert .-bash
Dies 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 /proc
oder 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 $0
ist 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 myscript
als 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
-c
wird$0
auf 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
$0
ist daher auf das Argument Null gesetzt. Es istlogin
,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, execve
erfolgt letztendlich ein Systemaufruf. Dieser Systemaufruf benötigt drei Argumente:
ein Dateiname, der eine vorhandene, ausführbare Datei bezeichnen muss. Der Kernel lädt diese Datei und überträgt ihr die Ausführung.
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
$PATH
Umgebungsvariable ermittelt wurde. Es gibt Ausnahmen von dieser Konvention, z. B. Login-Shells.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 execve
vom laufenden Programm übergeben wurde. Unter Linux ist er normalerweise verfügbar, /proc/$$/exe
wobei $$
die Prozess-ID ist. Jedes Unix macht ihn verfügbar, ps
aber die Funktionsweise ps
unterscheidet sich stark. Die ausführbare Datei kann gelöscht oder umbenannt werden, während das Programm ausgeführt wird. In diesem Fall ps
werden 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.