Kinder / Gentler / Subtiler äquivalente Alternative zu Killall (zB "Endall")?

17

Wie beende ich alle gleichnamigen Prozesse auf sanftere Weise als bisher killall? Ich möchte die Prozesse nicht unterbrechen, sondern ihnen Zeit lassen, um sie ordnungsgemäß zu beenden.


Siehe auch:

Wie kann ich Prozesse in Ubuntu beenden?

Was ist der Unterschied zwischen Kill Process und End Process im Systemmonitor?

Warum muss killall (manchmal?) Zweimal angewendet werden?

tl; dr

verrückt nach natty
quelle
1
Und deine Frage ist?
Pilot6
@Pilot6 umformuliert : Was ist eine "weichere" Alternative zu Killall?
nussig über natty
1
Was ist "weicher"?
Pilot6
@Pilot6 "weicher" im Sinne von "End" vs "Kill"
verrückt nach natty

Antworten:

43

1. `killall` schon nett (SIGTERM)

killallstandardmäßig sendet SIGTERM. Dies ist bereits der nette Ansatz, der Anwendungen die Möglichkeit lässt, nach sich selbst aufzuräumen. Das "geh schon sterben, gerade jetzt!" Ansatz ist es, ein SIGKILLSignal zu senden , bei dem dies als Option angegeben werden muss killall. Aus der GNU C-Bibliothek: Beendigungssignale :

Makro: int SIGTERM

[...] Es ist die übliche Art , ein Programm höflich zum Abbruch aufzufordern.


2. Der "End process" des Systemmonitors ist genauso schön (auch SIGTERM)

Sie verlinken auf eine Frage zu GNOME System Monitor. Dies wird auch SIGTERMfür die Aktion "Prozess beenden" verwendet (und mir ist klar, dass ich der Antwort auf diese Frage widerspreche). Sie finden es im Quellcode, um sich zu verifizieren:

Daten / Menüs.ui :

<item>
  <attribute name="label" translatable="yes">_End</attribute>
  <attribute name="action">win.send-signal-end</attribute>
  <attribute name="accel">&lt;Primary&gt;e</attribute>
  <attribute name="target" type="i">15</attribute>
</item>

Die 15 hier ist die Signalnummer. Signal 15 ist SIGTERM. Und der Systemmonitor wurde bereits verwendet, SIGTERMbevor andere Fragen gestellt und beantwortet wurden.


Technischer Nachtrag (als Antwort auf einen Kommentar)

In der Github-Darstellung von sehen Sie git blamedie Änderungen, die an der Schreibweise der Signale im Quellcode von GNOME System Monitor vorgenommen wurden:

383007f2 24. Juli 2013 Ersetzter duplizierter Code zum Senden von Signalen mit GAction-Parametern.
0e766b2d 18. Juli 2013 Popup-Menü für den Port-Prozess an GAction
97674c79 3. Oktober 2012 ProcData-Struktur
entfernen 38c5296c 3. Juli 2011 Einheitliche Einrückung für alle Quelldateien.

Nichts davon änderte sich von SIGQUITzu SIGTERM, und das letzte war von, bevor die verknüpfte Frage gestellt wurde.

hvd
quelle
7
+1 für den Verweis auf den Quellcode! (+2 für den Widerspruch zu "konventioneller Weisheit", wie es war;)
verrückt nach natty
Nun, bevor Sie feststellen, dass Sie der Antwort widersprechen: Haben Sie überprüft, ob alle Versionen des Quellcodes verwendet werden 15? Es könnte irgendwann geändert worden sein, sodass die alte Antwort in Bezug auf eine alte Version zu 100% richtig sein könnte .
Bakuriu,
1
@ Bakuriu Ich widerspreche dieser Antwort so oder so, aber fairerweise werde ich versuchen, mich daran zu erinnern, das nächste Mal zu überprüfen, wenn ich kann.
HDV
@ Bakuriu im Quell-Git-Baum git grep 'SIGQUIT'verrät nichts. Es wurde auch nichts in Bezug auf Signale gefunden git grep '>3<'. Ich schließe daraus, dass der Gnome-System-Monitor wahrscheinlich noch nie benutzt wurde SIGQUIT.
Ruslan,
@Ruslan git grepdurchsucht nur den aktuellen Baum, nicht den gesamten Verlauf. Ich habe git blame(eigentlich das Github-Äquivalent) benutzt, um ein bisschen tiefer zu graben, aber immer noch nichts.
HDV
5

Die Antwort von @hvd ist grundsätzlich richtig. Um das noch mehr zu sichern, wird der initProzess zuerst SIGTERMan Prozesse gesendet, SIGKILLwenn Sie Ihren Computer herunterfahren, und wird dann nach einer Verzögerung gesendet, wenn sie noch nicht beendet wurden. Prozesse können nicht verarbeitet / ignoriert werden SIGKILL.

Um ein bisschen mehr Details zu geben, ist die eigentliche Antwort, dass Sie nicht sicher wissen können, ob das Programm damit fertig wird. SIGTERMist das gebräuchlichste Signal, um ein Programm höflich zum Beenden aufzufordern, aber die gesamte Signalverarbeitung hängt davon ab, ob das Programm etwas mit dem Signal tut.

Anders ausgedrückt, basierend auf den anderen Antworten, wenn Sie ein Programm von @Jos oder @AlexGreg geschrieben hätten, dann wären sie vermutlich handhabbar, SIGQUITaber möglicherweise nicht SIGTERM, und daher SIGTERMwäre das Senden weniger "leise" als SIGQUIT.

Ich habe einen Code geschrieben, mit dem Sie selbst herumspielen können. Speichern Sie das unten stehende als signal-test.c, dann kompilieren Sie mit

gcc -o signal-test signal-test.c

Sie können es dann ausführen ./signal-testund sehen, was passiert, wenn Sie verschiedene Signale mit senden killall -s <signal>.

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

int flag = 0;

void handle_signal(int s)
{
    flag = s;
}

int main(int argc, char *argv[])
{
    signal(SIGTERM, handle_signal);
    signal(SIGQUIT, handle_signal);

    while(flag == 0){
        sleep(1);
    }
    printf("flag is %d\n", flag);
    return flag;
}

Der Code behandelt sowohl SIGTERM als auch SIGQUIT ordnungsgemäß. Sie können versuchen, die Zeilen zu kommentieren signal(SIG...(mit einem //am Zeilenanfang), um den Signal-Handler zu entfernen, und dann die Signale erneut ausführen und senden. Sie sollten in der Lage sein, diese verschiedenen Ausgaben zu sehen:

$ ./signal-test
Terminated

$ ./signal-test
Quit (core dumped)

$ ./signal-test
flag is 15

$ ./signal-test
flag is 3

je nachdem, ob Sie mit den Signalen umgehen oder nicht.

Sie können auch versuchen, die Signale zu ignorieren:

signal(SIGTERM, SIG_IGN);

Wenn Sie dies tun, führt das Senden zu SIGTERMnichts, und Sie müssen SIGKILLden Vorgang mit beenden.

Weitere Details in man 7 signal. Beachten Sie, dass die Verwendung signal()auf diese Weise als nicht portabel gilt - es ist jedoch viel einfacher als die Alternative!

Eine weitere kleine Fußnote zu Solaris killallversucht, alle Prozesse abzubrechen. Alle von ihnen. Wenn Sie es als root ausführen, werden Sie überrascht sein :)

Roger Light
quelle
1
Dies ist einer der Gründe, die ich bevorzuge pkill. Der andere Grund ist, dass es mit gepaart ist, pgrepwas es einfacher macht, genau zu überprüfen, welche Prozesse beendet werden, und welches selbst eine besser übereinstimmende Semantik aufweist als ps | grep.
Random832
1

"End all" wäre killall -s SIGQUIT [process name]. Wenn Sie eine ausgefallene Lösung wünschen, definieren Sie alias endall='killall -s SIGQUIT'.

Jos
quelle
13
SIGQUITist wie das Erstellen eines Prozesses abort(3): Der Prozess wird gelöscht und anschließend abgebrochen. Dies ist in keiner Weise netter / sanfter / freundlicher als SIGTERMdie Standardeinstellung für killall.
Ruslan
3
Bei einem Prozess, der mit Signalen umgeht SIGQUIT(oder sogar besser SIGINT), wird er möglicherweise „weicher“ behandelt als SIGTERM, dies liegt jedoch an der Anwendung. Unbearbeitet verursachen sie eine sofortige Kündigung.
R ..
1
Dies ist eine großartige Idee, wenn Sie Core-Dateien auf Ihrer gesamten Festplatte löschen möchten.
Nate Eldredge
2
@Qix: Eine Sache, die pro Signal variiert, ist, ob eine Kerndatei für die Standardaktion erstellt wird oder nicht (wenn diese nicht von der Anwendung verarbeitet wird). Es ist wahrscheinlich vorzuziehen, Signale zu verwenden, die keine Kerndateien generieren.
R ..
1
Es ist erwähnenswert, dass Ubuntu die Beschränkung der Core-Dateigröße standardmäßig auf 0 setzt, sodass SIGQUIT keine Core-Datei erzeugt (falls nicht behandelt), es sei denn, Sie ändern die Beschränkung.
Roger Light