Quelle est la meilleure façon d'envoyer un signal à tous les membres d'un groupe de processus?
J'ai envie de tuer tout un processus d'arbre. Quelle est la meilleure façon de le faire à l'aide de tout les langages de script? Je suis à la recherche d'une solution simple.
Les Zombies devraient disparaître lorsque le système reaper fonctionne bien. Je vais vous avouer que j'ai vu des systèmes où les zombies s'attarder, mais c'est atypique.
Parfois, ceux qui s'attarder zombies sont responsables de certains effrayant de l'activité.
Utilisez l'une des
tuer $(pstree <PID> -p -a-l | cut-d, -f2 | cut-d' ' -f1)
Pourriez-vous s'il vous plaît lien vers ces programmes?
Parfois, ceux qui s'attarder zombies sont responsables de certains effrayant de l'activité.
Utilisez l'une des
chronos
ou herodes
commandes.tuer $(pstree <PID> -p -a-l | cut-d, -f2 | cut-d' ' -f1)
Pourriez-vous s'il vous plaît lien vers ces programmes?
OriginalL'auteur Adam Peck | 2008-12-24
Vous devez vous connecter pour publier un commentaire.
Vous ne dites pas si l'arbre que vous voulez tuer est un seul groupe de processus. (C'est souvent le cas si l'arbre est le résultat de bifurquer à partir d'un serveur de démarrage ou une ligne de commande shell.) Vous pouvez découvrir les groupes de processus à l'aide de GNU ps comme suit:
Si c'est un groupe de processus que vous voulez tuer, il suffit d'utiliser la
kill(1)
de commande, mais au lieu de donner un numéro de processus, de lui donner la négation du numéro de groupe. Par exemple, pour tuer tous les processus dans le groupe 5112, utilisezkill -TERM -- -5112
.Comme d'habitude avec presque n'importe quelle commande, si vous voulez un normal argument qui commence par un pour ne pas être interprété comme un interrupteur, faites-la précéder d' --: tuer -- -GPID
pgrep
peut offrir un moyen plus facile de trouver le processus de l'ID de groupe. Par exemple, pour tuer my-script.sh'le groupe de processus, exécutionkill -TERM -$(pgrep -o my-script.sh)
.Meilleur coup d'oeil à stackoverflow.com/questions/392022/... son, de loin, une solution plus élégante et si vous avez besoin de la liste des pid des enfants alors utiliser:
ps -o pid --no-headers --ppid $PARENT_PID
Et si vous modifiez le format légèrement et de tri, vous obtenez de voir tous les processus bien regroupés et début avec (éventuellement) de la maison mère du groupe dans chaque groupe:
ps x -o "%r %p %y %x %c" | sort -nk1,2
OriginalL'auteur Norman Ramsey
Tuer tous les processus appartenant à la même arborescence des processus à l'aide de la Processus d'ID de Groupe (
PGID
)kill -- -$PGID
Utiliser la valeur par défaut du signal (TERM
= 15)kill -9 -$PGID
Utiliser le signalKILL
(9)Vous pouvez récupérer le
PGID
de toute ID du Processus (PID
) de la même arborescence des processuskill -- -$(ps -o pgid= $PID | grep -o '[0-9]*')
(signalTERM
)kill -9 -$(ps -o pgid= $PID | grep -o '[0-9]*')
(signalKILL
)merci Spécial à tangara et Speakus pour les contributions sur
$PID
espaces restants et OSX compatibilité.Explication
kill -9 -"$PGID"
=> Envoyer un signal 9 (KILL
) à tous les enfants et petits-enfants...PGID=$(ps opgid= "$PID")
=> Récupérer le Processus-Group-ID de toute ID du Processus de l'arbre, non seulement la Processus Parent-ID. Une variation deps opgid= $PID
estps -o pgid --no-headers $PID
oùpgid
peut être remplacé parpgrp
.Mais:
ps
insère des espaces lorsquePID
est à moins de cinq chiffres et aligné à droite comme remarqué par tangara. Vous pouvez utiliser:PGID=$(ps opgid= "$PID" | tr -d ' ')
ps
à partir de OSX toujours imprimer l'en-tête, donc Speakus propose:PGID="$( ps -o pgid "$PID" | grep [0-9] | tr -d ' ' )"
grep -o [0-9]*
tirages successifs des chiffres (ne pas imprimer des espaces ou alphabétique des en-têtes).Plus de lignes de commande
Limitation
kill
est invoquée par un processus appartenant au même arbre,kill
risques de tuer lui-même avant de mettre fin à l'ensemble de l'arbre de tuer.Longue histoire
Exécuter l'arborescence des processus en arrière-plan à l'aide de " &"
La commande
pkill -P $PID
ne pas tuer le petit-fils:La commande
kill -- -$PGID
tue tous les processus, y compris le petit-enfant.Conclusion
Je remarque que dans cet exemple
PID
etPGID
sont égaux (28957
).C'est pourquoi j'ai pensé à l'origine
kill -- -$PID
était assez. Mais dans le cas où le processus est spawn dans unMakefile
la ID de Processus est différente de la ID de Groupe.Je pense que
kill -- -$(ps -o pgid= $PID | grep -o [0-9]*)
est le meilleur truc simple pour tuer un processus d'ensemble de l'arbre lorsqu'il est appelé à partir d'un autre ID de Groupe (un autre processus de l'arbre).kill
doit toujours envoyer le signal à l'ensemble de l'arbre avant de recevoir son propre signal. Mais dans certaines circonstances spécifiques/implémentations,kill
peut envoyer à lui-même le signal, être interrompu, et de recevoir son propre signal. Cependant, le risque doit être assez minime, et peut être ignoré dans la plupart des cas, parce que d'autres bugs doivent se produire avant que celui-ci. ce risque Peut être ignoré dans votre cas? en Outre d'autres réponses ont ce bug commun (kill
partie de l'arborescence des processus d'être tué). Espérons que cela aide.. Cheers 😉Cela ne fonctionne que si le sous-commandes elles-mêmes ne deviennent pas des chefs de groupe. Même la plus simple des outils comme
man
le faire. D'autre part, si vous voulez tuer gandchild processus de processus enfant,kill -- -$pid
ne fonctionne pas. Il n'est donc pas solution générique.L'exemple est "l'enfant" en essayant de tuer ses enfants (petits-enfants de l'utilisateur qui a initié la commande). OIE, essayez de tuer les processus en arrière-plan de la hiérarchie dans
child.sh
.> tuer -QUITTER -"$PGID" # même signal que [CTRL+C] du clavier ---- ARRÊTER de fumer devraient être remplacés pour INT pour être vrai
pour OSX option --no-têtes n'est pas pris en charge donc le code doit être mis à jour à: PGID="$( ps -o pgid "$PID" | grep [0-9] | tr -d '' )"
OriginalL'auteur olibre
Cela va tuer tous les processus qui ont le parent de l'ID de processus 27888.
Ou plus robustes:
qui annexe tuant 33 seconde plus tard et demandez poliment à ce processus de se terminer.
Voir cette réponse pour mettre fin à tous les descendants.
Je suis d'accord avec @haridsv:
pkill -P
envoie le signal à l'enfant seulement => le petit-fils de ne pas recevoir le signal => Donc j'ai wroten une autre réponse pour l'expliquer. Acclamations 😉À partir d'un script bash pour tuer vos propres enfants, l'utilisation
pkill -TERM -P ${$}
.n'est-il pas dangereux pour dormir, puis de les tuer? L'Id de processus peuvent avoir été réutilisé par le système d'exploitation dans le temps: vous pourriez peut-être tuer les processus qui ne sont pas vos enfants de plus. Je soupçonne l'appel à pkill serait de le faire à nouveau pour vous assurer contre cela.
Pour info, je suis en mesure de spawn 32768 processus, thread unique, avec de la lumière I/O accès en moins de 19 secondes sur ma machine:
$ time for i in {1..32768}; do ( echo $BASHPID >> pids ); done real 0m18.860s
OriginalL'auteur Onlyjob
De tuer un processus arbre de manière récursive, l'utilisation killtree():
--
arguments pourps
ne fonctionne pas sur OS X. Pour le faire fonctionner il y remplacer leps
commande par:ps ax -o "pid= ppid=" | grep -E "${_regex}" | sed -E "s/${_regex}/\1/g
où_regex
est défini avant lafor
boucle:local _regex="[ ]*([0-9]+)[ ]+${_pid}"
Arrêté processus de ne pas se faire tuer avec SIGTERM. Voir mon répondre
-1 utilise #!/bin/bash au lieu de #!/usr/bin/env bash (ou mieux encore POSIX seulement des constructions et /bin/sh)
Serait-il suffisant pour envoyer un signal SIGKILL à la place de SIGTERM à garantir que
killtree()
fonctionne de manière fiable?si
ps
ne prend pas en charge--ppid
, on peut utiliserpgrep -P ${_pid}
au lieuOriginalL'auteur zhigang
rkill commande à partir de pslist paquet envoie le signal donné (ou
SIGTERM
par défaut) pour processus spécifié et tous ses descendants:OriginalL'auteur Onlyjob
brad réponse est ce que j'avais trop recommander, sauf que vous pouvez faire disparaître
awk
tout à fait si vous utilisez le--ppid
option pourps
.OriginalL'auteur Kim Stebel
si vous savez passer le pid du processus parent, voici un script shell qui devrait fonctionner:
OriginalL'auteur brad.lane
J'utilise un peu une version modifiée de la méthode décrite ici:
https://stackoverflow.com/a/5311362/563175
De sorte qu'il ressemble à ça:
où 24901 est parent PID.
Assez laid, mais est-il du travail à la perfection.
pstree -p 24901 | grep -oP '(?<=\()[0-9]+(?=\))'
vous devez ajouter
-l
àpstree
, donc de longues lignes ne soyez pas tronqué; il peut être plus simple à lire aussi aveckill `pstree -l -p 24901 |grep "([[:digit:]]*)" -o |tr -d '()'`
(pas besoin de convertir\n
à l'espace comme il sera beau travail), thx!OriginalL'auteur Tomasz Werszko
Version modifiée de zhigang réponse:
wait $pid
uniquement sur les processus que vous avez commencé, pas tous les precesses, donc ce n'est pas une solution génériqueKario Dans ce cas, attendez va juste sortir avec des non-zéro de statut et de poursuivre l'exécution du script. Suis-je tort? Mais
wait
supprimerTerminated
message si c'est un enfant.OriginalL'auteur x-yuri
À ajouter à Norman Ramsey réponse, il peut être intéressant de regarder à setsid si vous souhaitez créer un groupe de processus.
http://pubs.opengroup.org/onlinepubs/009695399/functions/setsid.html
Qui, pour moi, signifie que vous pouvez créer un groupe à partir de ce processus. J'ai utilisé ce en php afin d'être en mesure de tuer un processus d'ensemble de l'arbre après le démarrage.
Cela peut être une mauvaise idée. Je serais intéressé par les commentaires.
OriginalL'auteur hajamie
Je ne peux pas commenter (pas assez de réputation), donc je suis obligé d'ajouter un nouveau réponse, même si ce n'est pas vraiment une réponse.
Il y a un léger problème avec l'sinon très belle et complète réponse donnée par @olibre sur 28 Fév. La sortie de
ps opgid= $PID
contiendra les espaces pour un PID plus courte que cinq chiffres carps
est de justifier la colonne (e) de mon droit d'aligner les chiffres). Au sein de l'ensemble de la ligne de commande, il en résulte un signe négatif, suivi par espace(s), suivi par le groupe PID. La solution la plus Simple est de pipeps
àtr
pour supprimer les espaces:OriginalL'auteur tanager
Inspiré par ysth commentaire
PGID
dePID
. Qu'en pensez-vous? CheersOriginalL'auteur Steven Penny
La suite de la fonction shell est semblable à beaucoup d'autres réponses, mais il fonctionne à la fois sur Linux et BSD (OS X, etc) sans dépendances externes comme
pgrep
:Ce n'est pas extra. Il limite le champ d'application de
$child
à cette fonction afin de ne pas déranger les autres (non local) variables avec le même nom et pour assurer le local de la variable valeur est nettoyé une fois que la fonction se termine.Oh, je vois maintenant, je pensais que c'était une partie de l'affectation. Je suppose que je devrais re-lire (plus lent) avant d'écrire un commentaire. 🙂 Merci.
Btw, ne serait-il pas préférable de créer une liste d'enfants et ensuite commencer à tuer par le haut (parent) ? .. Ainsi, nous avons pu éviter la situation où un parent recrée un enfant ou se poursuit l'exécution de code suivant, ce qui pourrait altérer l'intention de comportement.
OriginalL'auteur David Röthlisberger
Il est super facile à faire avec python à l'aide de psutil. Il suffit d'installer psutil avec pip et puis vous avez une gamme complète de processus d'outils de manipulation:
OriginalL'auteur genericdave
Basé sur zhigang réponse, cela évite l'auto-tuer:
OriginalL'auteur davide
Si vous voulez tuer un processus par nom:
ou
OriginalL'auteur Mika Vatanen
C'est ma version de tuer tous les processus enfants à l'aide de scripts bash.
Ne pas utiliser la récursivité et dépend de la commande pgrep.
Utilisation
Contenu de killtrees.sh
OriginalL'auteur marekdef
Ici est une variante de @zhigang de la réponse, qui n'est sans AWK, en ne s'appuyant que sur le coup de l'analyse native possibilités:
Il semble fonctionner sur les ordinateurs Mac et Linux. Dans les situations où vous ne pouvez pas compter sur d'être en mesure de gérer les groupes de processus-comme lors de l'écriture de scripts pour tester un morceau de logiciel qui doit être construit dans de multiples environnements -- cet arbre-la marche technique est certainement utile.
OriginalL'auteur solidsnack
Il est probablement préférable de tuer les parents devant les enfants; sinon, le parent peut probablement frayer de nouvelles à nouveau des enfants, avant qu'il soit tué lui-même. Ces survivront au massacre.
Ma version de ps est différente de celle ci-dessus; peut-être trop vieille, donc l'étrange grepping...
Utiliser un script shell au lieu d'une fonction shell a de nombreux avantages...
Cependant, il est fondamentalement zhigangs idée
OriginalL'auteur Peter Steier
Ce qui suit a été testé sur FreeBSD, Linux et MacOS X et ne dépend que de pgrep et de tuer (le ps -o versions ne fonctionnent pas sous BSD). Le premier argument est le parent pid dont les enfants doivent être résilié. deuxième argument est une valeur booléenne pour déterminer si le parent pid doit être arrêté trop.
Envoyer SIGTERM à tout enfant ou le petit-processus au sein d'un script shell et si SIGTERM ne réussit pas, il faudra attendre 10 secondes et ensuite l'envoyer tuer.
Antérieure réponse:
Suivantes fonctionne aussi mais va tuer le shell lui-même sur BSD.
OriginalL'auteur Orsiris de Jong
Je de développer la solution de zhigang, xyuri et solidsneck plus loin:
Cette version permettra d'éviter le meurtre de son ascendance qui provoque une inondation de processus enfants dans les solutions précédentes.
Processus sont correctement arrêtée avant que la liste des enfants est déterminée, de sorte qu'aucune nouvelle des enfants de la création ou de disparaître.
Après avoir été tué, l'arrêté d'emplois de la poursuite à disparaître à partir du système.
OriginalL'auteur Peter Steier
Vieille question, je sais, mais toutes les réponses semblent garder l'appelant ps, je n'ai pas aimé.
Ce awk-fondé de la solution ne nécessite pas de récursivité et seuls les appels ps la fois.
Ou sur une seule ligne:
L'idée de base est que nous construisons un tableau (a), de la mère de l'enfant:les entrées, puis la boucle autour de la matrice de trouver des enfants pour notre correspondance des parents, en les ajoutant à nos parents liste (p) que nous allons.
Si vous ne voulez pas tuer le premier niveau du processus, puis de le faire
juste avant que le système() de la ligne de l'enlèverait de la tuer ensemble.
Garder à l'esprit qu'il existe une condition de course ici, mais c'est vrai (aussi loin que je peux voir) de toutes les solutions. Il le fait ce dont j'avais besoin, parce que le script que j'ai besoin d'elle pour ne pas créer des lots de courte durée de vie des enfants.
Un exercice pour le lecteur d'en faire une 2-passer en boucle: après la première passe, envoyer SIGSTOP à tous les processus dans le p de la liste, puis la boucle pour exécuter ps de nouveau et après le deuxième passage, envoyer SIGTERM, puis son état. Si vous n'avez pas de soins sur nice terminaisons puis deuxième passage pourrait être simplement SIGKILL, je suppose.
OriginalL'auteur Whinger
Merci pour votre sagesse, des gens. Mon script a la sortie de certains de ses processus enfants à la sortie et la négation bout fait les choses plus faciles. J'ai écrit cette fonction pour être utilisé dans d'autres scripts si nécessaire:
Acclamations.
OriginalL'auteur
si vous avez pstree et perl sur votre système, vous pouvez essayer ceci:
OriginalL'auteur lyman
Si vous connaissez le pid de la chose que vous voulez vous tuer, vous pouvez généralement aller de l'id de session, et tout dans la même session. Je voudrais vérifier, mais j'ai utilisé ce pour les scripts de démarrage rsyncs dans les boucles que je veux mourir, et ne pas commencer à l'autre (à cause de la boucle), comme il le ferait si je venais de killall avais rsync.
Si vous ne connaissez pas le pid, vous pouvez toujours nest plus
OriginalL'auteur Morgan
kill -9
, vraiment.Parfois
kill -15
ne va pas aider.OriginalL'auteur
Dans les poissons, les emplois de commande liste les processus en arrière-plan. Dans certains cas, il peut être mieux pour tuer le plus récent d'abord le processus, par exemple, le plus ancien créé un socle commun. Dans ces cas, les trier, les PIDs dans l'ordre inverse. Parfois, vous voulez moment d'attente pour les emplois d'écrire quelque chose sur le disque ou des trucs comme ça avant d'arrêter.
Et de ne pas la tuer si vous n'avez pas à!
OriginalL'auteur jens
Tuer processus enfant dans un shell script:
Beaucoup de temps, nous avons besoin de tuer le processus enfant qui sont pendus ou de bloquer pour une raison quelconque. par exemple. FTP problème de connexion.
Il y a deux approches,
1) Pour créer des nouveaux parents pour chaque enfant qui sera chargé de surveiller et de tuer les processus enfant une fois le délai atteint.
Créer test.sh comme suit,
et de regarder les processus qui ont un nom 'test' dans d'autres terminaux utilisant la commande suivante.
Script ci-dessus va créer 4 nouveaux processus enfants et de leurs parents. Chaque processus enfant continuera de fonctionner pendant 10sec. Mais une fois le délai d'attente de 5 secondes, d'atteindre, de leurs parents respectifs processus de tuer ceux childs.
Si l'enfant ne sera pas en mesure de terminer l'exécution(10sec).
Jouer autour de ces horaires(switch 10 et 5) de voir un autre comportement. Dans ce cas, l'enfant va se terminer l'exécution en 5sec avant qu'il n'atteigne délai de 10sec.
2) Laisser le parent actuel contrôler et tuer des processus enfant une fois le délai atteint. Cela ne crée pas de séparer les parents de surveiller chaque enfant. Aussi, vous pouvez gérer tous les processus fils correctement dans le même parent.
Créer test.sh comme suit,
et de regarder les processus qui ont un nom 'test' dans d'autres terminaux utilisant la commande suivante.
Script ci-dessus va créer 4 nouveaux processus enfant. Nous sommes de stockage des pids de tous les processus enfant et de boucle pour vérifier si ils ont fini de leur exécution ou en cours d'exécution.
Processus enfant d'exécution jusqu'à CMD_TIME temps. Mais si CNT_TIME_OUT délai d'attente , Tous les enfants seront tués par les processus parent.
Vous pouvez changer de calendrier et de jouer avec le script pour voir le comportement.
Un inconvénient de cette approche est , c'est à l'aide de l'id de groupe pour tuer tous les enfants de l'arbre. Mais le processus parent lui-même appartiennent à un même groupe, donc il sera également se faire tuer.
Vous devrez peut-être attribuer d'autres id du groupe de processus parent si vous ne voulez pas parent d'être tué.
Plus de détails peuvent être trouvés ici,
Tuer le processus enfant en script shell
OriginalL'auteur Hemant Thorat
Ce script aussi des travaux:
#/bin/sh
while true
do
echo "Enter parent process id [type quit for exit]"
read ppid
if [ $ppid -eq "quit" -o $ppid -eq "QUIT" ];then
exit 0
fi
for i in `ps -ef| awk '$3 == '$ppid' { print $2 }'`
do
echo killing $i
kill $i
done
done
OriginalL'auteur Nullpointer
Je sais que c'est vieux, mais c'est la meilleure solution que j'ai trouvé:
OriginalL'auteur Luciano Andress Martini