Tuer tous les processus appartenant au même arbre des processus en utilisant le ID du groupe de processus ( PGID
)
-
kill -- -$PGID
Utiliser le signal par défaut ( TERM
= 15)
-
kill -9 -$PGID
Utilisez le signal KILL
(9)
Vous pouvez récupérer le PGID
de n'importe quel Process-ID ( PID
) de la même arbre des processus
- *`kill -- -$(ps -o pgid= $PID | grep -o '[0-9]')
** (signal
TERM` )
- *`kill -9 -$(ps -o pgid= $PID | grep -o '[0-9]')
** (signal
KILL` )
Remerciements particuliers à Tangara y Speakus pour des contributions sur $PID
espaces restants et compatibilité OSX.
Explication
-
kill -9 -"$PGID"
=> Envoyer le signal 9 ( KILL
) à tous les enfants et petits-enfants...
-
PGID=$(ps opgid= "$PID")
=> Récupérer le Process-Group-ID de n'importe quel Process-ID de l'arbre, pas seulement le Process-Parent-ID . Une variation de ps opgid= $PID
es ps -o pgid --no-headers $PID
donde pgid
peut être remplacé par pgrp
.
Mais :
-
ps
insère des espaces en tête lorsque PID
est inférieur à cinq chiffres et aligné à droite, comme le remarque l'inspecteur de la Commission européenne. Tangara . Vous pouvez utiliser :
PGID=$(ps opgid= "$PID" | tr -d ' ')
-
ps
d'OSX impriment toujours l'en-tête, par conséquent Speakus propose :
PGID="$( ps -o pgid "$PID" | grep [0-9] | tr -d ' ' )"
- *`grep -o [0-9]`** imprime uniquement les chiffres successifs (n'imprime pas les espaces ni les en-têtes alphabétiques).
Autres lignes de commande
PGID=$(ps -o pgid= $PID | grep -o [0-9]*)
kill -TERM -"$PGID" # kill -15
kill -INT -"$PGID" # correspond to [CRTL+C] from keyboard
kill -QUIT -"$PGID" # correspond to [CRTL+\] from keyboard
kill -CONT -"$PGID" # restart a stopped process (above signals do not kill it)
sleep 2 # wait terminate process (more time if required)
kill -KILL -"$PGID" # kill -9 if it does not intercept signals (or buggy)
Limitation
- Comme l'a remarqué davide y Hubert Kario quand
kill
est invoqué par un processus appartenant au même arbre, kill
risque de se tuer lui-même avant de mettre fin à l'abattage de l'arbre entier.
- Par conséquent, assurez-vous d'exécuter la commande à l'aide d'un processus ayant un autre nom d'utilisateur. Process-Group-ID .
Longue histoire
> cat run-many-processes.sh
#!/bin/sh
echo "ProcessID=$$ begins ($0)"
./child.sh background &
./child.sh foreground
echo "ProcessID=$$ ends ($0)"
> cat child.sh
#!/bin/sh
echo "ProcessID=$$ begins ($0)"
./grandchild.sh background &
./grandchild.sh foreground
echo "ProcessID=$$ ends ($0)"
> cat grandchild.sh
#!/bin/sh
echo "ProcessID=$$ begins ($0)"
sleep 9999
echo "ProcessID=$$ ends ($0)"
Exécuter l'arbre des processus en arrière-plan en utilisant '&'.
> ./run-many-processes.sh &
ProcessID=28957 begins (./run-many-processes.sh)
ProcessID=28959 begins (./child.sh)
ProcessID=28958 begins (./child.sh)
ProcessID=28960 begins (./grandchild.sh)
ProcessID=28961 begins (./grandchild.sh)
ProcessID=28962 begins (./grandchild.sh)
ProcessID=28963 begins (./grandchild.sh)
> PID=$! # get the Parent Process ID
> PGID=$(ps opgid= "$PID") # get the Process Group ID
> ps fj
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
28348 28349 28349 28349 pts/3 28969 Ss 33021 0:00 -bash
28349 28957 28957 28349 pts/3 28969 S 33021 0:00 \_ /bin/sh ./run-many-processes.sh
28957 28958 28957 28349 pts/3 28969 S 33021 0:00 | \_ /bin/sh ./child.sh background
28958 28961 28957 28349 pts/3 28969 S 33021 0:00 | | \_ /bin/sh ./grandchild.sh background
28961 28965 28957 28349 pts/3 28969 S 33021 0:00 | | | \_ sleep 9999
28958 28963 28957 28349 pts/3 28969 S 33021 0:00 | | \_ /bin/sh ./grandchild.sh foreground
28963 28967 28957 28349 pts/3 28969 S 33021 0:00 | | \_ sleep 9999
28957 28959 28957 28349 pts/3 28969 S 33021 0:00 | \_ /bin/sh ./child.sh foreground
28959 28960 28957 28349 pts/3 28969 S 33021 0:00 | \_ /bin/sh ./grandchild.sh background
28960 28964 28957 28349 pts/3 28969 S 33021 0:00 | | \_ sleep 9999
28959 28962 28957 28349 pts/3 28969 S 33021 0:00 | \_ /bin/sh ./grandchild.sh foreground
28962 28966 28957 28349 pts/3 28969 S 33021 0:00 | \_ sleep 9999
28349 28969 28969 28349 pts/3 28969 R+ 33021 0:00 \_ ps fj
La commande pkill -P $PID
ne tue pas le petit-enfant :
> pkill -P "$PID"
./run-many-processes.sh: line 4: 28958 Terminated ./child.sh background
./run-many-processes.sh: line 4: 28959 Terminated ./child.sh foreground
ProcessID=28957 ends (./run-many-processes.sh)
[1]+ Done ./run-many-processes.sh
> ps fj
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
28348 28349 28349 28349 pts/3 28987 Ss 33021 0:00 -bash
28349 28987 28987 28349 pts/3 28987 R+ 33021 0:00 \_ ps fj
1 28963 28957 28349 pts/3 28987 S 33021 0:00 /bin/sh ./grandchild.sh foreground
28963 28967 28957 28349 pts/3 28987 S 33021 0:00 \_ sleep 9999
1 28962 28957 28349 pts/3 28987 S 33021 0:00 /bin/sh ./grandchild.sh foreground
28962 28966 28957 28349 pts/3 28987 S 33021 0:00 \_ sleep 9999
1 28961 28957 28349 pts/3 28987 S 33021 0:00 /bin/sh ./grandchild.sh background
28961 28965 28957 28349 pts/3 28987 S 33021 0:00 \_ sleep 9999
1 28960 28957 28349 pts/3 28987 S 33021 0:00 /bin/sh ./grandchild.sh background
28960 28964 28957 28349 pts/3 28987 S 33021 0:00 \_ sleep 9999
La commande kill -- -$PGID
tue tous les processus, y compris le petit-fils.
> kill -- -"$PGID" # default signal is TERM (kill -15)
> kill -CONT -"$PGID" # awake stopped processes
> kill -KILL -"$PGID" # kill -9 to be sure
> ps fj
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
28348 28349 28349 28349 pts/3 29039 Ss 33021 0:00 -bash
28349 29039 29039 28349 pts/3 29039 R+ 33021 0:00 \_ ps fj
Conclusion
Je remarque dans cet exemple PID
y PGID
sont égales ( 28957
).
C'est pourquoi j'ai d'abord pensé kill -- -$PID
était suffisante. Mais dans le cas où le processus est frayé dans une Makefile
el ID du processus est différente de la ID du groupe .
Creo que *`kill -- -$(ps -o pgid= $PID | grep -o [0-9])`** est la meilleure astuce pour tuer un processus entier lorsqu'il est appelé à partir d'un autre processus. ID du groupe (un autre arbre de processus).
4 votes
Les zombies devraient disparaître quand le système de faucheur fonctionne. J'admets que j'ai vu des systèmes où les zombies s'attardent, mais c'est atypique.
10 votes
Parfois, ces zombies persistants sont responsables d'une activité effrayante.
0 votes
Utilisez l'un des
chronos
oherodes
des commandes.9 votes
Kill $(pstree <PID> -p -a -l | cut -d, -f2 | cut -d' ' -f1)
0 votes
@MichaelLeBarbierGrünewald Pourriez-vous établir un lien vers ces programmes ?
0 votes
TL;DR :
ps -ej | grep whatever
puis prendre la deuxième colonne qui est l'ID de groupe (PGID) et fairekill -- -groupID
. Donc si vous voulez tuer votre VPN, faitesps -ej | grep vpn
alors si l'ID du groupe est 1234, faiteskill -- -1234
. Cela devrait le tuer entièrement.