Alle angehaltenen Prozesse per Pipe beenden

Alle angehaltenen Prozesse per Pipe beenden

Ich führe ein Skript aus, das vor dem Beenden angehalten werden muss. Beim ersten Ausführen gibt es nur eine PID für den Prozess. Ich beende es und führe es erneut aus, und die Anzahl der PIDs steigt. Zunächst einmal: Warum dieses Verhalten? Und wie kann ich alle angehaltenen Prozesse beenden, ohne jede PID explizit zu erwähnen?

./toplog.sh

Aussetzen:

Ctrl-Z

Auflisten angehaltener Prozesse:

jobs -l

Ausgabe:

[1]  12055 Stopped                 ./toplog.sh
[2]  12752 Stopped                 ./toplog.sh
[3]- 13276 Stopped                 ./toplog.sh
[4]+ 13579 Stopped                 ./toplog.sh

Tötung:

kill 12055 12752 13276 13579

Antwort1

Ich führe ein Skript aus, das vor dem Beenden angehalten werden muss.

Äh, nein. Ein Skript muss nicht angehalten werden, bevor es beendet wird. Sie können es jederzeit beenden.

Beim ersten Ausführen gibt es nur eine PID für den Prozess. Ich beende es und führe es erneut aus, und die Anzahl der PIDs steigt.

Dann beenden Sie es nicht wirklich! Wenn Sie ./toplog.shes ausführen und anhalten, wird nur ein einziger Job erstellt, d. h. eine einzige Zeile in der Ausgabe von jobs. Das Skript selbst erstellt möglicherweise mehrere Prozesse, jobslistet aber nur das Skript selbst auf (technisch ausgedrückt den Prozessgruppenleiter). Wenn Sie immer mehr Jobs sehen, bedeutet dies, dass Sie immer noch die alten Jobs sehen, die Sie erfolglos zu beenden versucht haben.

Der Grund, warum Sie die Jobs nicht beenden konnten, ist wahrscheinlich, dass sie angehalten sind. Wenn ein Prozess angehalten ist, kann er nicht auf Signale reagieren. Wenn Sie ein Signal an einen angehaltenen Prozess senden, hat das Signal nur dann eine Auswirkung, wenn der Prozess fortgesetzt wird. Ausnahmen sind Signale, die direkt vom Kernel verwaltet werden, ohne den Prozess einzubeziehen. Eine solche Ausnahme ist das Signal zum Fortsetzen eines Prozesses (SIGCONT), das den Prozess offensichtlich sofort aufweckt. Eine andere Kategorie von Ausnahmen sind Signale, die den Prozess ohne Aufforderung beenden: Dazu gehört immer SIGKILL und auch andere Signale (SIGINT, SIGHUP, SIGTERM, SIGQUIT, …), wenn der Prozess keinen Handler für dieses Signal festgelegt hat.

Wenn kill %1Job 1 beendet wird, teilt Ihnen die Shell mit, dass der Job beendet ist. Wenn der Prozess einen Handler für SIGTERM festgelegt hat, kill %1hat dies keine Auswirkung, während der Prozess angehalten ist. Um den Prozess zu beenden, müssen Sie ihn auch fortsetzen:

kill %1; kill -CONT %1

Wenn Sie den Prozess zwangsweise beenden möchten, ohne ihm die Möglichkeit zur Bereinigung zu geben, dann tun Sie dies

kill -KILL %1

(oder kill -9 %1kurz).

Wenn Sie alle Prozesse beenden möchten toplog.sh, unabhängig davon, ob sie von diesem Terminal gestartet wurden oder nicht, können Sie verwenden pkill toplog.sh.

Antwort2

Sie können alle Instanzen Ihres Skripts beenden, wenn Sie wissen, wie Ihr Prozess zur Laufzeit aufgerufen wird (in diesem Beispiel toplog.sh).

ps x | grep toplog.sh | grep -v grep | cut -d" " -f1 | xargs kill -9

ps xgibt Ihnen eine Liste aller Ihrer Prozesse, von denen aus der Zielprozess gegrept wird. Das zweite Grep stellt nur sicher, dass der Grep-Aufruf selbst aus der Liste entfernt wird. Andernfalls erhalten Sie einen Fehler (was eigentlich immer noch kein Problem ist, aber hässlich).Schnitt -d" " -f1schneidet jede Zeile in mehrere durch Leerzeichen getrennte Teile, wobei *-f1** den ersten Teil nimmt.xargs töten -9tötet alle PIDs, die zuvor aus der Befehlskette geworfen wurden.

Der Einfachheit halber können Sie diese Zeile in ein Kill-Skript einfügen, wobei der Prozessname durch das Kill-Skript-Argument ersetzt wird:

#!/bin/bash
ps x | grep $1 | grep -v grep | cut -d" " -f1 | xargs kill -9

Das Skript wird dann mit dem Namen der zu beendenden Prozesse aufgerufen.

./kill.sh toplog.sh

verwandte Informationen