Sie können sh -c
und verwenden exec
, um die PID des Befehls zu ermitteln, noch bevor dieser ausgeführt wird.
Zum Starten myCommand
, damit die PID gedruckt wird, bevor die Ausführung beginnt, können Sie Folgendes verwenden:
sh -c 'echo $$; exec myCommand'
Wie es funktioniert:
Dies startet eine neue Shell, gibt die PID dieser Shell aus und ersetzt die Shell mit dem exec
eingebauten Befehl, um sicherzustellen, dass sie dieselbe PID hat. Wenn Ihre Shell einen Befehl mit der eingebauten Funktion ausführt, wird Ihre Shell tatsächlich zu diesem Befehl und nicht zu dem häufigeren Verhalten, eine neue Kopie von sich selbst zu erstellen, die eine eigene separate PID hat und dann zum Befehl wird.exec
Ich finde das viel einfacher als Alternativen, die asynchrone Ausführung (mit &
), Jobsteuerung oder Suche mit beinhalten ps
. Diese Ansätze sind in Ordnung, aber es sei denn, Sie haben einen bestimmten Grund, sie zu verwenden. Beispielsweise wird der Befehl bereits ausgeführt. In diesem Fall ist es sinnvoll, nach seiner PID zu suchen oder die Jobsteuerung zu verwenden. (Und ich würde sicherlich nicht in Betracht ziehen, ein komplexes Skript oder ein anderes Programm zu schreiben, um dies zu erreichen).
Diese Antwort enthält ein Beispiel für diese Technik.
Teile dieses Befehls könnten gelegentlich weggelassen werden, aber normalerweise nicht.
Auch wenn die von Ihnen verwendete Shell einen Bourne-Stil hat und daher die exec
integrierte Semantik unterstützt, sollten Sie im Allgemeinen nicht versuchen, die Verwendung sh -c
(oder eine gleichwertige Methode ) zum Erstellen eines neuen, separaten Shell-Prozesses für diesen Zweck zu vermeiden , da:
- Sobald die Shell geworden ist
myCommand
, gibt es keine Shell, die darauf wartet, nachfolgende Befehle auszuführen. sh -c 'echo $$; exec myCommand; foo
wäre nicht in der Lage zu versuchen, foo
nach dem Ersetzen durch myCommand
. Wenn Sie kein Skript schreiben, das dieses als letzten Befehl ausführt, können Sie es nicht einfach echo $$; exec myCommand
in einer Shell verwenden, in der Sie andere Befehle ausführen.
- Sie können hierfür keine Unterschale verwenden .
(echo $$; exec myCommand)
kann syntaktisch besser sein als sh -c 'echo $$; exec myCommand'
, aber wenn Sie $$
innerhalb ausführen (
)
, gibt es die PID der übergeordneten Shell, nicht der Subshell selbst. Es ist jedoch die PID der Subshell, die die PID des neuen Befehls ist. Einige Schalen bieten ihre eigenen , nicht tragbaren Mechanismen für die Subshell PID zu finden, die Sie könnten für diese. Insbesondere in Bash 4 , (echo $BASHPID; exec myCommand)
funktioniert.
Beachten Sie schließlich, dass einige Shells eine Optimierung ausführen, bei der sie einen Befehl ausführen, als ob exec
sie dies tun (dh zuerst auf das Forken verzichten), wenn bekannt ist, dass die Shell danach nichts mehr tun muss. Einige Shells versuchen dies immer dann, wenn es sich um den letzten auszuführenden Befehl handelt, während andere dies nur tun, wenn vor oder nach dem Befehl keine anderen Befehle vorhanden sind, und andere dies überhaupt nicht tun. Der Effekt ist , dass , wenn Ihr vergessen zu schreiben exec
und einfach zu verwenden , sh -c 'echo $$; myCommand'
dann wird manchmal Sie die richtige PID geben auf einigen Systemen mit einigen Muscheln. Ich rate davon ab, sich jemals auf ein solches Verhalten zu verlassen und stattdessen immer exec
anzugeben, wann Sie dies benötigen.