Ein Prozess kann nicht beendet werden, der im Task-Manager läuft, aber anscheinend nicht sichtbar ist

6718
aweeeezy

Ich habe eine Anwendung gestartet, die nicht ausgeführt werden kann. Ich kann sie jedoch nicht löschen, da sie noch läuft. Ich kann die PID drucken, aber den Prozess nicht damit beenden.

~ $ ps ax | grep snappr | awk '' 70824 ~ $ kill $(ps ax | grep snappr | awk '') -bash: kill: (70832) - No such process 
6
@ BeowulfOF: "Reihenfolge der ps-Ausgabe"? Huh Wie macht das Sinn? Wenn "snappr" ausgeführt wird, hätte der erste Befehl zwei PIDs aufgelistet: die von "snappr" und die der "grep" - wie in meiner Antwort erläutert, die ich eine halbe Stunde gepostet habe, bevor Sie diesen Kommentar gepostet haben. ... ... ... ... ... PS Vielleicht möchten Sie Ihre Beiträge ein wenig besser korrigieren ("Ich meldet den Fehler", "Anzeige", "mit"). Scott vor 9 Jahren 0
Sorry Scott, die Fehler kamen von der Autokorrektur, ich habe dies kurz von meinem Handy aus geschrieben. Keine Entschuldigung, deshalb habe ich den Kommentar gelöscht. Oliver Friedrich vor 9 Jahren 0
Ihr "grep snappr" passt zu dem Prozess "grep snappr". Sobrique vor 9 Jahren 4
Welche Plattform? Mac OS X? Linux? Cygwin? Peter Mortensen vor 9 Jahren 0

2 Antworten auf die Frage

17
Scott

Haben Sie bemerkt, dass Sie in den beiden Versuchen zwei verschiedene PIDs erhalten haben?

Beachten Sie Folgendes: Wenn Sie einen Befehl wie vi raven.txteingeben, ps axwird eine Zeile mit einem Befehl von angezeigt vi raven.txt. Wenn Sie einen Befehl wie grep snappreingeben, ps axwird eine Zeile angezeigt, in der ein Befehl von angezeigt wird grep snappr. Und wenn Sie die Ausgabe davon psweiterleiten grep snappr, grepwird der die Zeile finden , die sich selbst beschreibt . Also, wenn du tippst

$ ps ax | grep snappr | awk '' 

Wiederholt wird jedes Mal eine andere Zahl gedruckt (da die PID-Nummer gedruckt grepwird und Sie grepjedes Mal einen neuen, eindeutigen Prozess erhalten, wenn Sie den Befehl ausführen).

Bedenken Sie abschließend: Der killBefehl kann erst ausgeführt werden, wenn seine Argumente bekannt sind. Damit das Argument bekannt ist, $(ps ax | grep snappr | awk '')muss die Pipeline abgeschlossen sein. Dies bedeutet, dass der grepMost 1 beendet sein muss . Daher killerhält das System die PID des grepProzesses, jedoch erst, nachdem der grepProzess beendet wurde - daher meldet es natürlich "Kein solcher Prozess".

Vielleicht hätte ich erwähnen sollen, dass kein snapprProzess läuft. Wenn ja, würde Ihr erster Befehl zwei Zahlen ausgeben: die PID von snapprund die PID von grep snappr. Wenn Sie jetzt snapprausgeführt werden, wird Ihr Befehl möglicherweise halb korrekt ausgeführt. Damit meine ich, dass er das tut, was Sie möchten, aber es wird auch eine Fehlermeldung angezeigt. Wenn das snapprmit der PID 42097 und grep snapprmit der PID 70848 ausgeführt wird, lautet der killBefehl kill 42097 70858, der den Befehl beendet snappr und eine Fehlermeldung ausgibt, wenn versucht wird, den grepnicht mehr vorhandenen Prozess abzubrechen .

Sie möchten dies wahrscheinlich verbessern. Meine Lieblings - Weg, die ich vor 20 Jahren erfunden, um es zu ändern das grepzu grep "[s]nappr", was dem Betrag entspricht, snappraber wird sich nicht überein. Ein anderer Ansatz ist pgrepeher zu verwenden als ps | grep.


1 Alternativ awkkönnte das auch beendet werden, wenn das grepSystem lediglich geschlossen wird. Dies wäre ein sehr ungewöhnliches Verhalten für ein * nix-Programm.

Ich habe ein Bash-Skript, das ich nur einmal auf meinem Rechner ausführen möchte. Innerhalb des Skripts verwende ich diesen Code zur Überprüfung (wobei $ THIS der Name des Skripts ist): PRIOR = "$ (ps --no-headers -Ao" pid, ppid, sid, args "| grep" $ THIS ") | grep -Ev "(grep | $ PPID | $$ |) ")" `. Wenn $ PRIOR nicht null ist, wird das Skript bereits ausgeführt. Ich hatte damit mehr Erfolg als mit "pgrep". gogoud vor 9 Jahren 0
Ah ja, das alte "grep |." grep -v` lösung. Warum einen zusätzlichen Prozess ausführen, den Sie nicht benötigen? Arbeite schlauer, nicht härter. Scott vor 9 Jahren 0
Ich stimme zu, dass es unordentlich aussieht. Ich würde gerne einen besseren, zuverlässigen Weg finden. ps -C erfasst nicht alle Prozesse, pgrep enthält nicht mehr vorhandene Prozesse. gogoud vor 9 Jahren 0
(1) Kennen Sie ein Problem mit meiner Lösung "grep" [s] nappr ""? (2) Wenn es um Tötungsprozesse geht, wen interessiert es dann, ob nicht mehr vorhandene Prozesse enthalten sind? Einen nicht mehr funktionierenden Prozess zu töten ist ein No-Op. Scott vor 9 Jahren 0
Mir ist klar, dass wir hier ein Thema bekommen. Ich mag Ihre [s] Napper-Lösung! Aber ich muss Ausfälle ausschließen, weil ich wirklich wissen möchte, ob es da draußen einen Live-Prozess gibt (in welchem ​​Fall jetzt aufhören!) Oder nur etwas, das stirbt. Und ich muss nicht nur den grep-Aufruf ausschließen, sondern auch die laufende Instanz des Skripts ($$) und möglicherweise den übergeordneten Aufruf ($ PPID). gogoud vor 9 Jahren 0
+1 für eine gute Antwort (aber ... vor 20 Jahren den [x] Trick erfunden? Oder einfach in der Unix-FAQ darüber gelesen?);)) Olivier Dulac vor 9 Jahren 0
Ich bevorzuge diesen Trick `ps axe egrep "[/] (PID | $ )" `oder` ps axe | grep "[/] $ " `, um das dreimal dumme` grep $ | zu vermeiden grep -v grep`. daniel Azuelos vor 9 Jahren 0
8
JakeGould

Kürzere Antwort

Springen Sie nicht durch Bash-Reifen, um snapprmit ihnen zu töten ps, durch grepund dann durch awk. Versuchen Sie es stattdessen so zu töten mit pkill; Kein Muss oder viel Aufhebens und es richtet sich nach dem Prozessnamen aus der Box:

sudo pkill snappr 

Längere Antwort

Nicht ganz klar mit der Funktionsweise von Snapper auf Systemprozessebene, aber das Problem könnte sein, dass Sie statt der übergeordneten Prozess-ID nur die untergeordnete Prozess-ID verwenden.

In der Tat glaube ich, dass die Methode, die Sie zum Erfassen einer Prozess-ID ( ps ax | grep snappr | awk '') verwenden, eine vollständige Liste von Prozess-IDs zurückgibt, mit denen eine Verbindung hergestellt wurde, snapprunabhängig davon, ob sie übergeordnet oder untergeordnet ist. Also mit, dass Sie vielleicht einen Prozess - ID töten, die gerade ein Kind Prozess - ID ist noch die übergeordnete ID noch aktiv und in der Lage sein würde, „Spawn“ ein anderes Kind Prozess zu kompensieren.

Vielleicht können Sie so etwas tun, um die endgültige übergeordnete ID der Prozess-ID zu ermitteln, für die Sie sie eingeben, und darauf reagieren. Ein einfacher Beweis für das Konzept, wie es funktioniert:

ps -p [process ID] -o ppid= 

Wenn Sie diesen bloßen Befehl in Bash ausführen, erhalten Sie die übergeordnete Prozess-ID der von Ihnen eingegebenen untergeordneten Prozess-ID [process ID]. Wenn also die untergeordnete ID 4567eine übergeordnete Prozess- ID hat, lautet 123der Befehl:

ps -p 4567 -o ppid= 

Und das würde wiederkommen 123.

Dies könnte jedoch ein gefährlicher Weg sein, um mit einem verirrten Prozess umzugehen, da das übergeordnete Prozess-ID eines Skripts tatsächlich snapperdie eigene Bash-Shell sein kann. Sie könnten also versehentlich Ihre Bash-Shell töten, anstatt snapperSie vom System zu stoßen, während der snapperProzess läuft.

Aber alles in allem, warum nicht dein Leben einfacher machen und einfach so laufen pkill:

sudo pkill snappr 

Dadurch werden alle Prozesse beendet, mit denen snapprkeine Jonglierfäden in der Befehlszeile verbunden sind.

Wenn Sie versuchen, einen von Ihnen gestarteten Prozess abzubrechen (wie in der Frage angegeben), ist Ihnen der Prozess, sofern er nicht setuid ist, nicht eigen und Sie brauchen nicht "sudo". Sie sollten `sudo` nicht verwenden, wenn Sie dies nicht brauchen. Scott vor 9 Jahren 1
Wahrscheinlicher - der Prozess existiert nicht wirklich, `grep` passt sich an. Sobrique vor 9 Jahren 2
Verwenden Sie "killall" anstelle von "pkill", da standardmäßig "pkill" Overkills verwendet werden. Hongxu Chen vor 9 Jahren 0