Как найти зомби-процесс?

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:~$ 

Как найти этот процесс зомби?

Pablo
источник
почему вы не открываете системный монитор и не ищите процесс зомби?
Длин
8
Как это сделать на безголовом сервере no-X?
SabreWolfy
2
Удивительно, что ни один ответ ниже фактически не говорит о том, что в системе нет процесса зомби, основанного на вышеупомянутом выводе. Если он действительно был, ps auxwww | grep 'Z'команда должна была показать процесс в Zсостоянии. Поговорка «системная информация» => There is 1 zombie process.кажется ошибкой. Либо так, либо в вопросе отсутствует информация.
Ариэльф

Ответы:

126

Чтобы убить зомби (процесс), вы должны убить его родительский процесс (как настоящие зомби!), Но вопрос был в том, как его найти.

Найди зомби (на вопрос ответила эта часть):

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

То, что вы получите, это Zombies и все остальное с Z в нем, так что вы также получите 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

Найдите родителя зомби:

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

Дам тебе:

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

В этом случае вы не хотите убивать этот родительский процесс, и вы должны быть вполне довольны одним зомби, но уничтожение непосредственного родительского процесса 5145 должно от него избавиться.

Дополнительные ресурсы по Askubuntu:

Duncanmoo
источник
1
Результатом, который вы показываете в своем ответе, является сама команда grep, а не процесс zombie. Это та же самая неверная интерпретация, которую сделал Пабло в своем ответе. Ответ Rinzwind ниже действительно ищет процесс зомби и перечисляет их. Другим вариантом может быть grep для «несуществующей»
FvD
pstree -H your_desired_pid -p
Грег М. Крсак,
Спасибо Грегу за добавление к обсуждению, но, пожалуйста, помните, что это справочный сайт, просто вставка команды без объяснения чего-либо не помогает большинству людей, которые приходят сюда за помощью.
Дунканму
1
Это отличный ответ! Это все еще действует сегодня! Я смог найти свой процесс зомби и убить его родительский процесс без каких-либо проблем. Спасибо!
Терренс
1
если у вас не установлен pstree, ps wauxfделает то же самое
JDS
35

Хотя этот вопрос старый, я думал, что все заслуживают более надежного ответа:

ps axo pid=,stat=

Это создаст два столбца, разделенных пробелами, первый из которых - PID, а второй - его состояние.

Я не думаю, что даже GNU psпредоставляет способ фильтрации по состоянию напрямую, но вы можете надежно сделать это сawk

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

Теперь у вас есть список PID, которые являются зомби. Поскольку вы знаете состояние, его больше не нужно отображать, чтобы его можно было отфильтровать.

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

Предоставление списка разделенных новой строкой PID зомби.

Теперь вы можете работать с этим списком с помощью простого цикла оболочки

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

ps это мощный инструмент, и вам не нужно делать ничего сложного, чтобы извлечь из него информацию о процессе.

(Значение различных состояний процесса здесь - https://unix.stackexchange.com/a/18477/121634 )

Sorpigal
источник
2
awkэто также мощный инструмент, который не только разделяет текст, но и может соответствовать ему. +1 ... остальные использовали grepтам, где это ненужно и неточно.
0xC0000022L
так что теперь у меня есть список процессов зомби. как мне их убить?
Чови
@chovy: Это будет зависеть, но обычно включает в себя убийство или сигнализацию родителя. Другие ответы здесь идут к этому. Из цикла, показанного выше, вы можете найти родительский pid следующим образом:ps -p "$pid" -opid=,ppid=
Sorpigal
если я буду родитель, он не убьет все свои дочерние процессы? Я просто хочу убить один процесс зомби. Я знаю ppid.
Чови
1
Я предлагаю добавить ppid=в список опций, поэтому нет необходимости использовать отдельную команду для получения ppid.
Дин-И Чен
3

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

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

Из комментариев улучшенный:

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;

Осторожно, хотя: этот также убивает процесс.

Rinzwind
источник
все еще ничего не возвращает. Я думаю, что мой путь тоже не ошибся.
Пабло
Второй пример адски ненадежен, а первый бесполезно многословен (попробуйте ps axo pid=,stat= | awk '$2~/Z/ {print $1}'вместо этого).
Сорпигал
3

Меньше значит больше, хотя:

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

Это как, дать мне лес (дерево) всех пользовательских процессов в ориентированном на пользователя формате с неограниченной шириной для любого tty и показать его мне на половине экрана выше, где это соответствует случаю, когда 8-й столбец содержит Z, и почему бы не выделить всю строку.

Похоже, что ориентированный на пользователя формат означает, USER, PID, %CPU, %MEM, VSZ, RSS, TTY, STAT, START, TIME, COMMANDчто статус Зомби будет отображаться в 8-м столбце.

Вы можете добавить Nперед, pесли вы хотите, чтобы номера строк, и, Jесли вы хотите звездочку в матче. К сожалению, если вы используете, Gчтобы не выделить строку, звездочка не будет отображаться, хотя и Jсоздаст для нее место.

В итоге вы получаете что-то похожее на:

…
  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.*
…

Вы можете выполнить это с помощью (и он обнаружит, нравится ли вашему терминалу -U Unicode или -A Ascii):

pstree -psS <PID LIST>

ИЛИ просто, вы знаете, используйте стрелку вверх, lessчтобы следовать этому дереву / лесу через иерархию; это то, что я рекомендовал с подходом «Меньше значит больше».

dlamblin
источник
0

Я предлагаю вам эту команду:

ps aux | awk '"[Zz]" ~ $8 { printf("%s, PID = %d\n", $8, $2); }'
Пейчо Димитров
источник
Использование auxи извлечение строк из этого без необходимости ненадежно, когда вы можете использовать -oи запрашивать именно то, что вы хотите. Используйте ps ax -o pid=,stat= | awk '$2 ~ "[Zz]" { printf("%s, PID = %d\n", $2, $1); }'вместо этого.
Сорпигал
-1

Чтобы вывести список зомби процессов, попробуйте эту команду:

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

Возможно, вам придется изменить в $7зависимости от вашей операционной системы.

Это также вернет список их идентификаторов родительского процесса ( PPID).

Чтобы попытаться убить зомби (после проверки вышеуказанной команды), попробуйте:

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

Чтобы определить их родителей, попробуйте pstree, например:

$ 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
источник
Прибегать к удалению одного столбца из jформата для этого излишне сложно. Используйте, -oчтобы выбрать то, что вы хотите вместо этого.
Сорпигал
2
ps jне печатает все процессы в системе. В нем перечислены только текущие пользовательские процедуры (в стиле заданий BSD), поэтому он может пропустить процессы зомби.
Ариэльф