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

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 2012a@SERVER:~$ ps auxwww | grep 'Z'USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMANDusera     13572  0.0  0.0   7628   992 pts/2    S+   19:40   0:00 grep --color=auto Za@SERVER:~$ 

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

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

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

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

То, что вы получаете, - это зомби и все остальное с Z в нем, так что вы также получите grep:

USER       PID     %CPU %MEM  VSZ    RSS TTY      STAT START   TIME COMMANDusera      13572   0.0  0.0   7628   992 pts/2    S+   19:40   0:00 grep --color=auto Zusera      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:

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

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 }'

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

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

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

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

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

Хотя меньше значит больше:

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 следовать за этим деревом / лесом по иерархии; это то, что я рекомендовал с подходом "Меньше значит больше".

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;

Однако будьте осторожны: это тоже убивает процесс.

Обычно я нахожу их на своем сервере с помощью

ps aux | grep 'defunct'

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

ps aux | awk '"[Zz]" ~ $8 { printf("%s, PID = %d\n", $8, $2); }'

почему мы не сообщаем "ps", какую информацию мы хотим получить? давайте попробуем:

read zSTAT zPPID zPID zSTAT zCMD <<< $(ps -xao stat,ppid,pid,cmd|awk '$1=="Z" {print $1" "$2" "$3" "$4}')[[ ! -z ${zPPID} ]] && echo "Zombie found! PID: "${zPID}" ("${zCMD}"), Parent to kill: "${zPPID}

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

проверка того, убит зомби или нет, может быть быстрее, если мы проверим только один параметр:

zombie=$(ps -xao pid|awk '$1=="'${zPID}'" {print $1}')[[ ! -z ${zombie} ]] && sudo kill -KILL ${zPPID}

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

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 -sgsystemd(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)

Как это сделать на безголовом сервере no-X?

Удивительно, что ни в одном из приведенных ниже ответов на самом деле не говорится, что в системе нет процесса зомби, основанного на приведенных выше выходных данных. Если бы он действительно был, команда ps auxwww | grep 'Z" должна была показать процесс в состоянии Z. В "системной информации" говорится => Существует 1 зомби-процесс.` похоже, это ошибка. Либо это, либо в вопросе отсутствует информация.

почему бы вам не открыть системный монитор и не поискать процесс зомби?