Wie kann ich die PID einer Subshell erhalten?
Zum Beispiel:
$ echo $$
16808
Dies funktioniert nicht, da die ursprüngliche Shell erweitert wird $$
:
$ ( echo $$ )
16808
Warum funktioniert das einfache Zitieren nicht? Erweitert $$
sich die Unterschale nicht in sich selbst, nachdem die ursprüngliche Shell das einfache Anführungszeichen entfernt hat?
$ ( echo '$$' )
$$
Warum funktioniert das auch eval
nicht? Wird eval
von der Subshell betrieben? Warum gibt es mir die PID der Originalschale?
$ ( eval echo '$$' )
16808
Vielen Dank.
$$
Erweiterung?" Im Vergleich zu "Unterschiedliche PID in der Unterschale").Antworten:
Zusätzlich zu
bash
's$BASHPID
können Sie dies portabel tun mit:Beispiel:
Sie können daraus eine Funktion machen:
Beachten Sie, dass einige Shells (z. B.
zsh
oderksh93
) NICHT einen Unterprozess für jede mit erstellte Subshell starten(...)
. In diesem Fall$pid
kann es sein, dass es dasselbe ist wie$$
, was genau richtig ist, da dies die PID des Prozesses ist, von dem ausgetpid
aufgerufen wurde.quelle
ksh93
.(...)
aus dem Beispiel, das möglicherweise keinen separaten Prozess erzeugt, wie es inbash
.zsh
oderyash
optimieren afork()
für den letzten Befehl in einer Subshell. Sie können sogar die Abzweigung für die Unterschale optimieren, wenn dies der letzte Befehl in einem Skript ist, sodass Siegetpid
sogar das übergeordnete Element von melden können$$
. Sie können Folgendes definierengetpid
:getpid(){ sh -c 'echo "$PPID"'; return; }
Deaktivieren, um das Problem zu vermeiden.exec
oder ohne diese Optimierung ist dersh -c ...
Prozess ein Enkelkind anstelle eines untergeordneten Elements des Prozesses, in dem eine$(...)
Befehlssubstitution verwendet wird, und$PPID
ist die$(...)
PID der Subshell. Genau das passiert im obigenset -E
+trap ERR
Bash-Beispiel.test "$1"
testet, ob$1
es sich um eine leere Zeichenfolge handelt oder nicht - eine schnelle und schmutzige Methode, um zu testen, ob dieser Funktion einvarname
Argument zum Zuweisen der PID zugewiesen wurde oder nicht; Die Verwendung einer Funktion war überhaupt nicht die beste Idee .Aus dem Handbuch:
Verbunden:
quelle
$$
in Subshells.$BASHPID
in einer Variablen speichern und diese in der Subshell verwenden. Es gibt$PPID
, aber das ist die übergeordnete PID der Shell in demselben Sinne wie$$
die PID der Shell (sie wird in einer Subshell nicht zurückgesetzt). Es gibt keine$BASHPPID
Variable.