Alternative équivalente plus douce / subtile à killall (par exemple «endall»)?

17

Comment puis-je terminer tous les processus avec le même nom d'une manière plus douce que le killallfait? Je ne veux pas interrompre les processus, mais laissez-leur le temps de quitter correctement.


Voir également:

Comment tuer les processus dans Ubuntu?

Dans System Monitor, quelle est la différence entre Kill Process et End Process?

Pourquoi killall (parfois?) Doit être appliqué deux fois?

tl; dr

noisette sur natty
la source
1
Et votre question est?
Pilot6
@ Pilot6 reformulé: qu'est-ce qu'une alternative "plus douce" à killall?
noisette sur natty
1
Qu'est-ce qui est "plus doux"?
Pilot6
@ Pilot6 "plus doux" dans le sens de "End" vs "Kill"
fou de natty

Réponses:

43

1. `killall` déjà sympa (SIGTERM)

killallenvoie par défaut SIGTERM. C'est déjà la bonne approche qui laisse aux applications la possibilité de se nettoyer après elles-mêmes. Le "allez mourir déjà, maintenant!" L'approche consiste à envoyer un SIGKILLsignal, ce qui nécessite de le spécifier en option killall. De la bibliothèque GNU C: Signaux de terminaison :

Macro: int SIGTERM

[...] C'est la manière normale de demander poliment à un programme de se terminer.


2. Le "processus de fin" de System Monitor est tout aussi agréable (SIGTERM aussi)

Vous créez un lien vers une question sur GNOME System Monitor. Cela vaut également SIGTERMpour son action "Fin du processus" (et je me rends compte que je contredit la réponse à cette question). Vous pouvez le trouver dans le code source pour vous vérifier:

data / menus.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>

Le 15 ici est le numéro du signal. Le signal 15 est SIGTERM. Et System Monitor a utilisé SIGTERMbien avant cette autre question a été posée et répondue.


Addendum technique (en réponse à un commentaire)

En regardant à travers la représentation Github de git blame, voici les changements qui ont été apportés à la façon dont les signaux sont énoncés dans le code source de GNOME System Monitor:

383007f2 24 juil. 2013 Code dupliqué remplacé pour l'envoi de signaux avec les paramètres
GAction 0e766b2d 18 juil. 2013 Menu contextuel du processus de port vers GAction
97674c79 3 oct. 2012 Supprimez la structure
ProcData 38c5296c 3 juil. 2011 Uniformisez l' indentation entre les fichiers source.

Aucun de ces éléments n'est passé de SIGQUITà SIGTERM, et ce dernier date d'avant la question liée.

hvd
la source
7
+1 pour faire référence au code source! (+2 pour contredire la "sagesse conventionnelle", pour ainsi dire;)
noisette sur natty
Eh bien, avant de déclarer que vous contredisez la réponse: avez-vous vérifié que toutes les versions du code source utilisent 15? Il a peut-être été modifié à un moment donné, de sorte que l'ancienne réponse pourrait être correcte à 100% par rapport à une ancienne version.
Bakuriu
1
@Bakuriu Je contredit cette réponse de toute façon, mais bon point, je vais essayer de me rappeler de vérifier cela la prochaine fois que je le pourrai.
hvd
@Bakuriu dans l'arbre git source, git grep 'SIGQUIT'ne révèle rien. Aucun élément lié aux signaux n'est trouvé git grep '>3<'non plus. Je conclus que le gnome-system-monitor n'a probablement jamais été utilisé SIGQUIT.
Ruslan
@Ruslan git grepne recherche que l'arborescence actuelle, pas toute l'histoire. J'ai utilisé git blame(en fait l'équivalent de Github) pour creuser un peu plus profondément, mais toujours rien.
2015 à 7h59
5

La réponse de @hvd est fondamentalement correcte. Pour sauvegarder cela encore plus, le initprocessus sera d'abord envoyé SIGTERMaux processus lorsque vous éteignez votre ordinateur, puis après un délai sera envoyé SIGKILLs'ils ne sont pas déjà sortis. Les processus ne peuvent pas gérer / ignorer SIGKILL.

Pour donner un peu plus de détails, la vraie réponse est que vous n'avez aucun moyen de savoir avec certitude que le programme le gère. SIGTERMest le signal le plus courant à utiliser pour demander poliment à un programme de quitter, mais tout traitement du signal dépend du programme qui fait quelque chose avec le signal.

Pour le dire différemment, sur la base des autres réponses, si vous aviez un programme écrit par @Jos ou par @AlexGreg, ils seraient probablement en train de gérer SIGQUITmais peut-être pas SIGTERM, et donc l'envoi SIGTERMserait moins "doux" que SIGQUIT.

J'ai écrit du code pour que vous puissiez jouer avec lui-même. Enregistrez ci-dessous sous signal-test.c, puis compilez avec

gcc -o signal-test signal-test.c

Vous pouvez ensuite l'exécuter ./signal-testet voir ce qui se passe lorsque vous envoyez différents signaux avec 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;
}

En l'état, le code gère à la fois SIGTERM et SIGQUIT avec élégance. Vous pouvez essayer de commenter les lignes signal(SIG...(en utilisant un //au début de la ligne) pour supprimer le gestionnaire de signal, puis exécuter et envoyer à nouveau les signaux. Vous devriez pouvoir voir ces différentes sorties:

$ ./signal-test
Terminated

$ ./signal-test
Quit (core dumped)

$ ./signal-test
flag is 15

$ ./signal-test
flag is 3

selon que vous gérez ou non les signaux.

Vous pouvez également essayer d'ignorer les signaux:

signal(SIGTERM, SIG_IGN);

Si vous faites cela, l'envoi SIGTERMne fera rien, vous devrez utiliser SIGKILLpour mettre fin au processus.

Plus de détails dans man 7 signal. Notez que l'utilisation signal()de cette manière est considérée comme non portable - c'est beaucoup plus facile que l'alternative!

Une autre note de bas de page mineure - sur Solaris killalltente de tuer tous les processus. Tous. Si vous l'exécutez en tant que root, vous pourriez être surpris :)

Roger Light
la source
1
C'est une des raisons pour lesquelles je préfère pkill. L'autre raison est qu'il s'associe avec pgrep, ce qui facilite la vérification exacte des processus qui seront tués et celui qui a lui-même une meilleure sémantique de correspondance que ps | grep.
Random832
1

"Tout mettre fin" serait killall -s SIGQUIT [process name]. Si vous voulez une solution sophistiquée, définissez alias endall='killall -s SIGQUIT'.

Jos
la source
13
SIGQUITc'est comme faire le processus abort(3): il vide le noyau puis tue le processus. Ce n'est en aucun cas plus agréable / plus doux / plus gentil que SIGTERMcelui par défaut killall.
Ruslan
3
Pour un processus qui gère les signaux SIGQUIT(ou même mieux SIGINT), il pourrait être traité plus «doucement» que SIGTERM, mais cela dépend de l'application. Non gérés, l'un d'eux entraîne une résiliation immédiate.
R .. GitHub STOP HELPING ICE
1
C'est une excellente idée, si vous aimez nettoyer les fichiers de base sur tout votre disque.
Nate Eldredge
2
@Qix: Une chose qui varie selon le signal est de savoir s'il crée un fichier core ou non sur l'action par défaut (lorsqu'il n'est pas géré par l'application). Il est probablement préférable d'utiliser des signaux qui ne génèrent pas de fichiers core.
R .. GitHub STOP HELPING ICE
1
Il convient de noter que ubuntu définit la limite de taille du fichier principal à 0 par défaut, donc SIGQUIT ne produira pas réellement un fichier principal (s'il n'est pas géré) à moins que vous ne modifiiez la limite.
Roger Light