Ich habe eine Anwendung gestartet, die nicht ausgeführt werden kann, aber ich kann sie nicht löschen, da sie noch ausgeführt wird. Ich kann die PID ausdrucken, aber den Prozess, der sie verwendet, nicht beenden.
~ $ ps ax | grep snappr | awk '{print $1}'
70824
~ $ kill $(ps ax | grep snappr | awk '{print $1}')
-bash: kill: (70832) - No such process
Antwort1
Haben Sie bemerkt, dass Sie bei den beiden Versuchen zwei unterschiedliche PIDs erhalten haben?
Bedenken Sie Folgendes: Wenn Sie einen Befehl wie eingeben vi raven.txt
, ps ax
wird eine Zeile angezeigt, die einen Befehl von anzeigt vi raven.txt
. Ebenso wird, wenn Sie einen Befehl wie eingeben grep snappr
, ps ax
eine Zeile angezeigt, die einen Befehl von anzeigt grep snappr
. Und wenn Sie die Ausgabe davon ps
durch weiterleiten grep snappr
, grep
wird die Zeile gefunden.das beschreibt sich selbstWenn Sie also
$ ps ax | grep snappr | awk '{print $1}'
wiederholt, wird jedes Mal eine andere Nummer gedruckt (weil die PID von gedruckt wird grep
und Sie grep
bei jeder Ausführung des Befehls einen neuen, eindeutigen Prozess erhalten).
Bedenken Sie abschließend: Der kill
Befehl kann nicht ausgeführt werden, bis seine Argumente bekannt sind. Damit seine Argumente bekannt sind, $(ps ax | grep snappr | awk '{print $1}')
muss die Pipeline abgeschlossen sein. Dies impliziert, dass die grep
beendet sein muss 1 . Daher kill
wird die PID des grep
Prozesses angegeben, aber erst, nachdem der grep
Prozess beendet wurde – daher meldet sie natürlich „Kein solcher Prozess“.
Vielleicht hätte ich erwähnen sollen, dass kein snappr
Prozess ausgeführt wird. Wenn dies der Fall wäre, würde Ihr erster Befehl zwei Zahlen ausgeben: die PID von snappr
und die PID von grep snappr
. Wenn nun snappr
ausgeführt würde, könnte Ihr Befehl halbwegs korrekt ausgeführt werden, d. h. er tut, was Sie wollen, gibt aber auch eine Fehlermeldung aus. Wenn der snappr
mit PID 42097 ausgeführt wird und grep snappr
mit PID 70848 ausgeführt wird, kill
lautet der Befehl kill 42097 70858
, wodurch der beendet wird snappr
und eine Fehlermeldung angezeigt wird, weil versucht wird, den Prozess zu beenden, grep
der nicht mehr existiert.
Sie möchten das wahrscheinlich verbessern. Meine bevorzugte Methode, die ich vor 20 Jahren erfunden habe, besteht darin, in zu ändern grep
, grep "[s]nappr"
was zwar übereinstimmt snappr
, aber nicht mit sich selbst übereinstimmt. Ein anderer Ansatz besteht darin, pgrep
anstelle von zu verwenden ps | grep
.
1 Alternativ awk
könnte der beendet werden, wenn grep
lediglich die Standardausgabe geschlossen wird. Dies wäre ein sehr ungewöhnliches Verhalten für ein *nix-Programm.
Antwort2
Kürzere Antwort
Springen Sie nicht durch Bash-Reifen, um es snappr
mit zu beenden ps
, durchgeleitet und dann so grep
durchgeleitet . Versuchen Sie stattdessen, es auf diese Weise zu beenden, indem Sieawk
pkill
; kein Stress oder Aufhebens und die Zielausrichtung erfolgt sofort auf Basis des Prozessnamens:
sudo pkill snappr
Längere Antwort
Nicht ganz klar, wieSchnapperarbeitet auf Systemprozessebene, das Problem könnte jedoch darin liegen, dass Sie nur die ID des untergeordneten Prozesses und nicht die ID des übergeordneten Prozesses erfassen.
Tatsächlich glaube ich, dass die Methode, die Sie verwenden, um eine Prozess-ID ( ps ax | grep snappr | awk '{print $1}'
) zu erfassen, eine ganze Liste der verknüpften Prozess-IDs zurückgeben würde, snappr
unabhängig davon, ob es sich um ein übergeordnetes oder untergeordnetes Element handelt. Wenn Sie das also verwenden,könnteBeenden Sie eine Prozess-ID, bei der es sich lediglich um eine untergeordnete Prozess-ID handelt, doch die übergeordnete ID wäre weiterhin aktiv und könnte zum Ausgleich einen anderen untergeordneten Prozess „erzeugen“.
Vielleicht können Sie so etwas tun, um die definitive übergeordnete ID der Prozess-ID, die Sie eingeben, abzurufen und entsprechend zu handeln. Einfacher Proof of Concept für die Funktionsweise:
ps -p [process ID] -o ppid=
Wenn Sie diesen einfachen Befehl in Bash ausführen, erhalten Sie die übergeordnete Prozess-ID der von Ihnen eingegebenen untergeordneten Prozess-ID [process ID]
. Wenn die untergeordnete ID also 4567
eine übergeordnete Prozess-ID von hat, 123
lautet der Befehl:
ps -p 4567 -o ppid=
Und das würde zurückkommen, 123
.
Dies kann jedoch eine gefährliche Methode sein, mit einem fehlgeleiteten Prozess umzugehen, denn wenn Ihr Skript die tatsächliche übergeordnete Prozess-ID von abruft snapper
, könnte der übergeordnete Prozess dieser Prozess-ID in Wirklichkeit Ihre eigene Bash-Shell sein. Sie könnten also versehentlich Ihre Bash-Shell beenden, anstatt snapper
Sie aus dem System zu werfen, während snapper
der Prozess weiterläuft.
Aber warum machen Sie sich das Leben nicht leichter und laufen einfachpkill
so was:
sudo pkill snappr
Dadurch werden alle verbundenen Prozesse beendet, snappr
ohne dass Sie mit der Befehlszeile herumspielen müssen.