Comment trouver un processus zombie?

100
System information as of Fri Mar  9 19:40:01 KST 2012

  System load:    0.59               Processes:           167
  Usage of /home: 23.0% of 11.00GB   Users logged in:     1
  Swap usage:     0%                 IP address for eth1: 192.168.0.1

  => There is 1 zombie process.

  Graph this data and manage this system at https://landscape.canonical.com/

10 packages can be updated.
4 updates are security updates.

Last login: Fri Mar  9 10:23:48 2012
a@SERVER:~$ ps auxwww | grep 'Z'
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
usera     13572  0.0  0.0   7628   992 pts/2    S+   19:40   0:00 grep --color=auto Z
a@SERVER:~$ 

Comment trouver ce processus zombie?

Pablo
la source
pourquoi ne pas ouvrir le moniteur du système et rechercher le processus zombie?
dlin
8
Comment faire cela sur un serveur no-X sans tête?
SabreWolfy
2
Étonnamment, aucune réponse ci-dessous ne dit en réalité qu'il n'y a pas de processus zombie dans le système basé sur la sortie ci-dessus. S'il y en avait vraiment un, la ps auxwww | grep 'Z'commande aurait dû montrer un processus dans un Zétat. Le dicton "informations système" => There is 1 zombie process.semble être un bug. Soit ça, soit il manque des informations dans la question.
arielf

Réponses:

126

Pour tuer un zombie (processus), vous devez tuer son processus parent (comme de vrais zombies!), Mais la question était de savoir comment le trouver.

Trouvez le zombie (La question a répondu à cette partie):

a@SERVER:~$ ps aux | grep 'Z'

Vous obtenez des zombies et tout ce qui contient un Z, vous obtiendrez donc le grep:

USER       PID     %CPU %MEM  VSZ    RSS TTY      STAT START   TIME COMMAND
usera      13572   0.0  0.0   7628   992 pts/2    S+   19:40   0:00 grep --color=auto Z
usera      93572   0.0  0.0   0      0   ??       Z    19:40   0:00 something

Trouvez le parent du zombie:

a@SERVER:~$ pstree -p -s 93572

Te donnera:

init(1)---cnid_metad(1311)---cnid_dbd(5145)

Dans ce cas, vous ne voulez pas tuer ce processus parent et vous devriez être assez satisfait d'un zombie, mais tuer le processus parent immédiat 5145 devrait s'en débarrasser.

Ressources supplémentaires sur askubuntu:

Duncanmoo
la source
1
Le résultat que vous indiquez dans votre réponse est la commande grep elle-même, pas le processus zombie. C'est la même erreur d'interprétation que Pablo a faite dans sa réponse. La réponse de Rinzwind ci-dessous recherche le processus zombie et l’énumère. Une autre option pourrait être grep pour "défunt"
FvD
pstree -H votre_desired_pid -p
Greg M. Krsak Le
Merci, Greg, d’avoir participé à la discussion, mais n’oubliez pas qu’il s’agit d’un site d’aide. Il ne suffit pas de coller une commande sans rien expliquer, ce qui n’aide en rien la plupart des gens qui viennent chercher de l’aide ici.
Duncanmoo
1
C'est une excellente réponse! Il est toujours valable aujourd'hui! J'ai pu trouver mon processus zombie et tuer son processus parent sans aucun problème. Je vous remercie!
Terrance
1
si vous n'avez pas installé pstree, ps wauxffait la même chose
JDS
35

Même si cette question est ancienne, je pensais que tout le monde méritait une réponse plus fiable:

ps axo pid=,stat=

Cela émettra deux colonnes délimitées par des espaces, la première étant un PID et la seconde son état.

Je ne pense pas que même GNU psfournisse un moyen de filtrer directement par État, mais vous pouvez le faire de manière fiable avecawk

ps axo pid=,stat= | awk '$2~/^Z/ { print }'

Vous avez maintenant une liste de PID qui sont des zombies. Comme vous connaissez l'état, il n'est plus nécessaire de l'afficher, vous pouvez donc filtrer ce dernier.

ps axo pid=,stat= | awk '$2~/^Z/ { print $1 }'

Donner une liste délimitée par une nouvelle ligne de PID zombies.

Vous pouvez maintenant utiliser cette liste avec une simple boucle shell

for pid in $(ps axo pid=,stat= | awk '$2~/^Z/ { print $1 }') ; do
    echo "$pid" # do something interesting here
done

ps est un outil puissant et vous n'avez rien à faire de compliqué pour en extraire des informations de processus.

(Signification des différents états de processus ici - https://unix.stackexchange.com/a/18477/121634 )

Sorpigal
la source
2
awkest également un outil puissant qui ne divise pas le texte mais peut également correspondre. +1 ... les autres sont utilisés greplà où c'est inutile et imprécis.
0xC0000022L
Alors maintenant que j'ai la liste des processus zombies. Comment puis-je les tuer?
Chovy
@chovy: Cela dépendra, mais implique généralement de tuer ou de signaler le parent. D'autres réponses vont ici à cela. Dans la boucle ci-dessus, vous pouvez trouver le pid parent comme ceci:ps -p "$pid" -opid=,ppid=
Sorpigal
si je veux que le parent ne tue-t-il pas tous ses processus enfants? Je veux juste tuer le processus d'un zombie. Je connais le PPID.
Chovy
1
Je suggère d'ajouter ppid=à la liste des options, donc pas besoin d'utiliser une commande distincte pour obtenir ppid.
Ding-Yi Chen le
3

ps aux | awk '{ print $8 " " $2 }' | grep -w Z

De: http://www.cyberciti.biz/tips/killing-zombie-process.html

Parmi les commentaires améliorés:

for p in $(ps jauxww | grep Z | grep -v PID | awk '{print $3}'); do
    for every in $(ps auxw | grep $p | grep cron | awk '{print $2}'); do
        kill -9 $every;
    done;
done;

Attention cependant: celui-ci tue également le processus.

Rinzwind
la source
ne retourne toujours rien. Je pense aussi que mon chemin n'était pas mauvais.
Pablo
Le 2ème exemple est infernal et le premier est inutilement prolixe (essayez ps axo pid=,stat= | awk '$2~/Z/ {print $1}'plutôt).
Sorpigal le
3

Moins, c'est plus si:

ps afuwwx | less +u -p'^(\S+\s+){7}Z.*'

C’est comme, donnez-moi une forêt (arborescence) de tous les processus des utilisateurs dans un format orienté utilisateur avec une largeur illimitée sur n’importe quel tty et montrez-la-moi sur un demi-écran au-dessus où cela correspond au cas où la huitième colonne contient un Z, et pourquoi ne pas souligner toute la ligne.

Format orienté utilisateur semble vouloir dire: USER, PID, %CPU, %MEM, VSZ, RSS, TTY, STAT, START, TIME, COMMANDainsi le statut de Zombie apparaîtra dans la 8ème colonne.

Vous pouvez ajouter un Navant le psi vous voulez des numéros de ligne et un Jsi vous voulez un astérisque lors du match. Malheureusement, si vous utilisez Gpour ne pas mettre en surbrillance la ligne que l'astérisque ne s'affichera pas, Jcréez un espace pour elle.

Vous finissez par avoir quelque chose qui ressemble à:

…
  root      2919  0.0  0.0  61432  5852 ?      Ss Jan24 0:00 /usr/sbin/sshd -D
  root     12984  0.0  0.1 154796 15708 ?      Ss 20:20 0:00  \_ sshd: lamblin [priv]
  lamblin  13084  0.0  0.0 154796  9764 ?      S  20:20 0:00      \_ sshd: lamblin@pts/0
* lamblin  13086  0.0  0.0  13080  5056 pts/0  Z  20:20 0:00          \_ -bash <defunct>
  lamblin  13085  0.0  0.0  13080  5056 pts/0  Ss 20:20 0:00          \_ -bash
  root     13159  0.0  0.0 111740  6276 pts/0  S  20:20 0:00              \_ su - nilbmal
  nilbmal  13161  0.2  0.0  13156  5004 pts/0  S  20:20 0:00                  \_ -su
  nilbmal  13271  0.0  0.0  28152  3332 pts/0  R+ 20:20 0:00                      \_ ps afuwwx
  nilbmal  13275  0.0  0.0   8404   848 pts/0  S+ 20:20 0:00                      \_ less +u -Jp^(\S+\s+){7}Z.*
…

Vous pouvez suivre ceci (et il détectera si votre terminal aime -U Unicode ou -A Ascii):

pstree -psS <PID LIST>

OU juste, vous savez, utilisez la flèche vers le haut lesspour suivre cet arbre / cette forêt à travers la hiérarchie; c'est ce que je recommandais avec l'approche "Moins, c'est plus".

Dlamblin
la source
0

Je vous suggère cette commande:

ps aux | awk '"[Zz]" ~ $8 { printf("%s, PID = %d\n", $8, $2); }'
Peycho Dimitrov
la source
Utiliser auxet assembler des chaînes est inutilement peu fiable lorsque vous pouvez utiliser -oet demander exactement ce que vous voulez. Utilisez à la ps ax -o pid=,stat= | awk '$2 ~ "[Zz]" { printf("%s, PID = %d\n", $2, $1); }'place.
Sorpigal
-1

Pour lister les zombies de processus, essayez cette commande:

ps j | awk '$7 ~ "Z"'

Vous devrez peut-être changer en $7fonction de votre système d'exploitation.

Cela renverra également la liste de leurs identifiants de processus parents ( PPID).

Pour essayer de tuer les zombies (après avoir testé la commande ci-dessus), essayez:

kill -9 $(ps j | awk 'NR>1 && $7 ~ "Z" {print $2}')

Pour identifier leurs parents, essayez avec pstree, comme:

$ ps j | awk 'NR>1 && $7 ~ "T" {print $2}' | xargs -L1 pstree -sg
systemd(1)───sshd(1036)───sshd(2325)───sshd(2325)───bash(2383)───zombie(2430)
systemd(1)───sshd(1036)───sshd(2325)───sshd(2325)───bash(2383)───zombie(2431)
systemd(1)───sshd(1036)───sshd(2325)───sshd(2325)───bash(2383)───zombie(2432)
Kenorb
la source
jIl est inutilement compliqué de supprimer une colonne du format. Utilisez -opour sélectionner ce que vous voulez à la place.
Sorpigal
2
ps jn'imprime pas tous les processus du système. Il ne répertorie que les procs de l'utilisateur actuel (dans le style des travaux BSD), de sorte qu'il peut manquer des processus zombies.
arielf