Pgrep gibt mehrere PIDs zurück

7

Mein Skript akzeptiert einen Prozessnamen als Eingabe und beendet ihn. Ich habe versucht, pgrep zu verwenden, aber es werden zwei PIDs zurückgegeben, eine für den laufenden Prozess und eine für das Skript, das den Prozessnamen als Eingabe akzeptiert. Ich habe auch versucht, die pgrep -foOption zu verwenden, aber das hat auch nicht geholfen. Anregungen wären hilfreich. Das ist mein Skript

#!/bin/bash
ProcessName=$1

pID= pgrep -fl $ProcessName

echo $pID

Wenn ich das Skript aufrufe, werden zwei PIDs zurückgegeben:

bash-3.00$ ./dynamic_values.sh test-Process

10534 /xxx/xxo/xxx/xxe --run --propFile /application/test/test-Process_Archive.tra --innerProcess
23401 /bin/bash ./dynamic_values.sh test-Process

Ich hatte nur 10534 erwartet, aber es hat auch das Drehbuch aufgenommen. Version des Betriebssystems nur für den Fall:

bash-3.00$ uname -a
Linux xxxxxx 2.6.9-67.0.1.
Grünschnabel
quelle
Warum ein Skript dafür schreiben? Es wurden bereits viele Tools für diese Art von Jobs geschrieben. Sie müssen nur das richtige finden. Aufgrund Ihrer Frage würde ich vorschlagen, dass Sie es versuchen pkill. Es verwendet dieselbe Prozessfindungslogik pgrep, mit der Sie bereits wissen, wie Sie Ihren Prozess finden können. Anstatt die PIDs an Sie zurückzugeben, wird lediglich ein Kill-Signal für Sie gesendet. In der Zwischenzeit kümmert es sich auch um Details wie nicht sich selbst zu töten.
Caleb
pkillbei der Verwendung -f(was er tut) wird das gleiche Problem haben.
Bahamat
@ Bahamat: Wirklich? Müssen Sie also -xin Kombination mit verwenden -f, um sicherzustellen, dass Sie das Ganze zusammenbringen? Ich bin überrascht, pkilldass ich keine eingebaute Möglichkeit habe, damit umzugehen.
Caleb
@Caleb Nach meinen Erfahrungen macht es unter OS X und Solaris das Richtige, aber Linux verwendet eine andere Implementierung. Ich musste mit meinem regulären Ausdruck wirklich zielgerichtet werden, um unter Linux das zu bekommen, was ich wollte (ich schrieb ein Skript, das alte Instanzen von sich selbst töten würde).
Bahamat
Ich hatte mich noch nie selbst pkillgetötet, bevor ich die Prozesse beendet hatte, die ich beenden wollte, daher hatte ich immer angenommen, dass die Implementierung gut war.
jw013

Antworten:

3

Ich musste das gleiche Problem vor ein paar Wochen angehen. pgrepund pkillunterstützen Sie erweiterte reguläre Ausdrücke, so dass es einfach ist, den richtigen regulären Ausdruck zu erhalten.

Dies ist Ihr Skript mit dem regulären Ausdruck, den ich verwendet habe.

#!/bin/bash
ProcessName=$1

pID= pgrep -fl "^(/.*)?${ProcessName}\s"

echo $pID

Obwohl die Verwendung pkill(wie von Caleb vorgeschlagen) besser ist.

pkill -fl "^(/.*)?${ProcessName}\s"

Möglicherweise müssen Sie den regulären Ausdruck noch anpassen, um die gewünschten Ergebnisse für Ihren Anwendungsfall und die Ausführung des Programms zu erhalten.

Nun, wenn es sind tatsächlich mehrere Prozesse mit diesem Namen laufen sie natürlich getötet werden. Wenn Sie dies vermeiden möchten, können Sie -onur den ältesten Matching-Prozess oder -nnur den neuesten beenden . Wenn Sie nur einen möchten, aber weder den ältesten noch den neuesten, sollten Sie ihn wahrscheinlich nicht verwenden p(kill|grep).

Bahamat
quelle
bahamat, danke für den tipp und ich konnte regex erfolgreich einsetzen.
Greenhorn
1
#!/bin/bash

ProcessName=$1

pID=`pgrep -fl $ProcessName`

echo "$pID" | grep -v  "^$$"
Hostmaster
quelle
Der Punkt von pgrepund pkillist, dass Sie es nicht an grep weiterleiten müssen.
Bahamat
1
es hängt davon ab, ob. In diesem Fall sollten wir den aktuellen Prozess nach
PID herausfiltern
Nein, du verstehst nicht. Der einzige Punkt pgrepist, nicht zu leiten grep. Wenn Sie verwenden möchten, können grepSie es auch verwenden ps | grep.
Bahamat
Ich fürchte, Sie haben hier ein Missverständnis. Hauptpunkt der Vorbereitung suchen Prozesse basierend auf Namen und anderen Attributen
Hostmaster
2
Vor Jahren während des Starts von Solaris wurde jedes Init-Skript als Äquivalent von bezeichnet kill $(ps -ef | grep somedaemon | grep -v grep | awk '{print $2}'). Die zusätzlichen Gabeln verlängerten die Startzeit, indem sie die fünffache Anzahl der erforderlichen Prozesse starteten. pkillund pgrepwurden geschrieben, damit Sie einfach aufrufen pkill somedaemonund die Startzeiten erheblich verkürzen können.
Bahamat
0

Wenn Sie das #! / bin / bash ausschließen, wird kein anderer Prozess für das Skript verzweigt, aber Sie verlieren die Wahl, mit welcher Shell es ausgeführt wird. Bash ist jedoch Standard genug und diejenigen, die smiler sind, sollten in der Lage sein, dies auszuführen.

Ich bin mir nicht sicher, ob dadurch die zweite Prozess-ID entfernt wird.

Ich verstehe, dass dies nicht vollständig ist, aber es ist spät und ich muss am Morgen arbeiten, aber dies sollte als schnelle Lösung funktionieren.

Joe
quelle
Vielen Dank, dass Sie sich so spät am Abend Zeit genommen haben. Leider wird eine leere Zeichenfolge sowie die richtige PID zurückgegeben, wie dieser Bash-3.00 $ ./dynamic_values.sh Test-Prozess 10534 / opt / XXengine --run --propFile / opt /application/test/test-Process_Archive.tra --innerProcess $
Grünschnabel
0

Würde nicht benutzen

| grep -v $$

um Ihren Prozess von der Listenhilfe auszuschließen?

Didi Kohen
quelle
Der Punkt von pgrepund pkillist, dass Sie es nicht an grep weiterleiten müssen.
Bahamat