GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie man einen gerade gestarteten Prozess pipi bekommt

Lösung 1:

Was kann einfacher sein als echo $! ? Als eine Zeile:

myCommand & echo $!

Lösung 2:

Sie können sh -c verwenden und exec um die PID des Befehls noch vorher zu erhalten es läuft.

Um myCommand zu starten , damit seine PID gedruckt wird, bevor es zu laufen beginnt, können Sie verwenden:

sh -c 'echo $$; exec myCommand'

Wie es funktioniert:

Dies startet eine neue Shell, gibt die PID dieser Shell aus und verwendet dann den exec eingebaut, um zu ersetzen die Shell mit Ihrem Befehl und stellen Sie sicher, dass sie dieselbe PID hat. Wenn Ihre Shell einen Befehl mit dem exec ausführt builtin, Ihre Shell wird tatsächlich werden diesen Befehl, anstatt das üblichere Verhalten, eine neue Kopie von sich selbst zu forken, die ihre eigene separate PID hat und die dann zum Befehl wird.

Ich finde das viel einfacher als Alternativen mit asynchroner Ausführung (mit & ), Auftragssteuerung oder Suche mit ps . Diese Ansätze sind in Ordnung, aber es sei denn, Sie haben einen bestimmten Grund, sie zu verwenden - beispielsweise wird der Befehl möglicherweise bereits ausgeführt, in diesem Fall wäre die Suche nach seiner PID oder die Verwendung der Jobsteuerung sinnvoll -, schlage ich vor, zuerst diesen Weg in Betracht zu ziehen. (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önnen gelegentlich weggelassen werden, aber normalerweise nicht.

Auch wenn die von Ihnen verwendete Shell im Bourne-Stil ist und daher die exec unterstützt Mit dieser Semantik eingebaut, sollten Sie im Allgemeinen nicht versuchen, die Verwendung von sh -c zu vermeiden (oder gleichwertig), um eine neue, separate zu erstellen Shell-Prozess für diesen Zweck, denn:

  • Sobald die Shell zu myCommand geworden ist , gibt es keine Shell, die darauf wartet, nachfolgende Befehle auszuführen. sh -c 'echo $$; exec myCommand; foo nicht versuchen könnte, foo auszuführen nachdem es sich selbst durch myCommand ersetzt hat . Sofern Sie kein Skript schreiben, das dies als letzten Befehl ausführt, können Sie nicht einfach echo $$; exec myCommand verwenden in einer Shell, in der Sie andere Befehle ausführen.
  • Sie können dafür keine Subshell verwenden. (echo $$; exec myCommand) kann syntaktisch schöner sein als sh -c 'echo $$; exec myCommand' , aber wenn Sie $$ ausführen innerhalb von ( ) , gibt es die PID der übergeordneten Shell an, nicht der Subshell selbst. Aber es ist die PID der Subshell, die die PID des neuen Befehls sein wird. Einige Shells bieten ihre eigenen nicht-portablen Mechanismen, um die PID der Subshell zu finden, was Sie könnten dafür verwenden. Insbesondere in Bash 4, (echo $BASHPID; exec myCommand) funktioniert.

Beachten Sie schließlich, dass einige Shells eine Optimierung durchführen, bei der sie einen Befehl wie von exec ausführen (d.h. sie verzichten zuerst auf das Forken), wenn bekannt ist, dass die Shell danach nichts tun muss. Einige Shells versuchen dies immer dann zu tun, wenn es der letzte auszuführende Befehl ist, 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 Sie vergessen, exec zu schreiben und verwenden Sie einfach sh -c 'echo $$; myCommand' dann wird es manchmal geben Ihnen die richtige PID für einige Systeme mit einigen Muscheln. Ich rate davon ab, sich jemals auf ein solches Verhalten zu verlassen und stattdessen immer exec einzufügen wenn Sie das brauchen.

Lösung 3:

Verpacken Sie den Befehl in ein kleines Skript

#!/bin/bash
yourcommand &
echo $! >/path/to/pid.file

Lösung 4:

Ich kenne keine einfachere Lösung, aber ich verwende kein $! gut genug? Sie können den Wert jederzeit einer anderen Variablen zuweisen, wenn Sie ihn später benötigen, wie andere sagten.

Als Randbemerkung, anstatt von ps zu pipen, könnten Sie pgrep verwenden oder pidof .

Lösung 5:

Verwenden Sie exec aus einem Bash-Skript, nachdem Sie die PID in einer Datei registriert haben:

Beispiel:

Angenommen, Sie haben ein Skript namens "forever.sh", das Sie mit den Argumenten p1,p2,p3

ausführen möchten

Quellcode für forever.sh:

#!/bin/sh

while [ 1 -lt 2 ] ; do
    logger "$0 running with parameters \"[email protected]\""
    sleep 5
done

erstelle eine reaper.sh:

#!/bin/sh

echo $$ > /var/run/$1.pid
exec "[email protected]"

Führen Sie forever.sh bis reaper.sh aus:

./reaper.sh ./forever.sh p1 p2 p3 p4 &

forever.sh tut nichts anderes, als alle 5 Sekunden eine Zeile im Syslog zu protokollieren

Sie haben jetzt die PID in /var/run/forever.sh.pid

cat /var/run/forever.sh.pid 
5780

und forever.sh läuft einwandfrei. syslog grep:

Nov 24 16:07:17 pinkpony cia: ./forever.sh running with parameters "p1 p2 p3 p4"

Sie können es in der Prozesstabelle sehen:

ps axuwww|grep 'forever.sh p1' |grep -v grep
root      5780  0.0  0.0   4148   624 pts/7    S    16:07   0:00 /bin/sh ./forever.sh p1 p2 p3 p4

Linux
  1. Linux-Startvorgang:Ein Leitfaden für den Einstieg

  2. Übergeordnete PID eines anderen Prozesses programmgesteuert abrufen?

  3. So erhalten Sie einen untergeordneten Prozess aus einem übergeordneten Prozess

  4. Wie erhalte ich die übergeordnete PID eines bestimmten Prozesses in GNU/Linux von der Befehlszeile aus?

  5. Wie erhalte ich die PID eines Prozesses und rufe im Shell-Skript kill -9 darauf auf?

Lxc und wie fange ich an?

Wie fange ich mit Juju an?

So finden Sie den Prozessnamen anhand seiner PID

Erste Schritte mit Arch Linux

Erste Schritte mit Midnight Commander im Jahr 2022

Wie man pgrep dazu bringt, die vollständigen Prozessinformationen anzuzeigen