¿Cómo encontrar el proceso 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:~$ 

¿Cómo encontrar ese proceso zombie?

Pablo
fuente
¿Por qué no abres el monitor del sistema y buscas el proceso zombie?
dlin
8
¿Cómo hacer eso en un servidor sin cabeza sin X?
SabreWolfy
2
Sorprendente que no haya una respuesta a continuación en realidad dice que no hay un proceso zombie en el sistema basado en el resultado anterior. Si realmente hubo uno, el ps auxwww | grep 'Z'comando debería haber mostrado un proceso en un Zestado. El dicho "información del sistema" => There is 1 zombie process.parece ser un error. O eso, o falta información en la pregunta.
arielf

Respuestas:

126

Para matar a un zombie (proceso) debes matar su proceso padre (¡como los zombies reales!), Pero la pregunta era cómo encontrarlo.

Encuentra el zombie (la pregunta respondió esta parte):

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

Lo que obtienes son zombis y cualquier otra cosa con una Z, por lo que también obtendrás el 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

Encuentra el padre del zombie:

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

Te regalaré:

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

En este caso, no quieres matar ese proceso padre y deberías estar bastante contento con un zombie, pero matar el proceso padre inmediato 5145 debería deshacerte de él.

Recursos adicionales en askubuntu:

Duncanmoo
fuente
1
El resultado que muestra en su respuesta es el comando grep en sí, no el proceso zombie. Es la misma mala interpretación que Pablo hizo en su respuesta. La respuesta de Rinzwind a continuación en realidad busca el proceso zombie y los enumera. Otra opción podría ser grep para "difunto"
FvD
pstree -H your_desired_pid -p
Greg M. Krsak
Gracias Greg por agregar a la discusión, pero recuerda que este es un sitio de ayuda, solo pegar un comando sin explicar nada no es útil para la mayoría de las personas que vienen aquí en busca de ayuda.
Duncanmoo
1
¡Esta es una respuesta genial! ¡Todavía es válido hoy! Pude encontrar mi proceso zombie y matar su proceso padre sin ningún problema. ¡Gracias!
Terrance
1
si no tiene instalado pstree, ps wauxfhace lo mismo
JDS
35

Aunque esta pregunta es antigua, pensé que todos merecían una respuesta más confiable:

ps axo pid=,stat=

Esto emitirá dos columnas delimitadas por espacios en blanco, la primera de las cuales es un PID y la segunda es su estado.

No creo que incluso GNU psproporcione una forma de filtrar por estado directamente, pero puede hacerlo de manera confiable conawk

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

Ahora tiene una lista de PID que son zombies. Como conoce el estado, ya no es necesario mostrarlo, por lo que puede filtrarse.

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

Dando una lista delimitada de nueva línea de PID zombies.

Ahora puede operar en esta lista con un simple bucle de shell

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

ps es una herramienta poderosa y no necesita hacer nada complicado para obtener información del proceso.

(Significado de los diferentes estados del proceso aquí: https://unix.stackexchange.com/a/18477/121634 )

Sorpigal
fuente
2
awkTambién es una herramienta poderosa que no solo divide el texto, sino que también puede combinarlo. +1 ... los otros lo usaron grepdonde es innecesario e impreciso.
0xC0000022L
así que ahora que tengo una lista de procesos zombies. ¿Cómo los mato?
chovy
@chovy: dependerá, pero generalmente implica matar o señalar al padre. Otras respuestas aquí van a eso. Desde el bucle que se muestra arriba, puede encontrar el padre pidiendo así:ps -p "$pid" -opid=,ppid=
Sorpigal
si lo hago, ¿no matará todos sus procesos hijos? Solo quiero matar el proceso de un zombie. Conozco el ppid.
chovy
1
Sugiero agregar ppid=a la lista de opciones, por lo que no es necesario usar un comando separado para obtener ppid.
Ding-Yi Chen
3

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

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

De los comentarios uno mejorado:

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;

Pero cuidado: este también mata el proceso.

Rinzwind
fuente
Todavía no devuelve nada. Creo que mi camino tampoco estuvo mal.
Pablo
El segundo ejemplo es infernalmente poco confiable y el primero es innecesariamente detallado (intente en su ps axo pid=,stat= | awk '$2~/Z/ {print $1}'lugar).
Sorpigal
3

Sin embargo, menos es más:

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

Es decir, dame un bosque (árbol) de todos los procesos de los usuarios en un formato orientado al usuario con ancho ilimitado en cualquier tty y muéstramelo en la mitad de la pantalla arriba, donde coincide con el caso de que la octava columna contenga una Z, y ¿Por qué no resaltar toda la línea?

El formato orientado al usuario parece significar: USER, PID, %CPU, %MEM, VSZ, RSS, TTY, STAT, START, TIME, COMMANDpor lo tanto, el estado de Zombie aparecerá en la octava columna.

Puede agregar un Nantes del psi desea números de línea y un Jsi desea un asterisco en el partido. Lamentablemente, si Gno resaltas la línea que el asterisco no mostrará, aunque Jcrea espacio para ello.

Terminas obteniendo algo que se parece a:

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

Usted podría seguir esto con (y va a detectar si su terminal le gusta -U Unicode o -A ASCII):

pstree -psS <PID LIST>

O simplemente, ya sabes, usa la flecha lesshacia arriba para seguir ese árbol / bosque a través de la jerarquía; que es lo que estaba recomendando con el enfoque "Menos es más".

dlamblin
fuente
0

Te sugiero este comando:

ps aux | awk '"[Zz]" ~ $8 { printf("%s, PID = %d\n", $8, $2); }'
Peycho Dimitrov
fuente
Usar auxy combinar cadenas es innecesariamente poco confiable cuando puede usar -oy solicitar exactamente lo que desea. Usar en su ps ax -o pid=,stat= | awk '$2 ~ "[Zz]" { printf("%s, PID = %d\n", $2, $1); }'lugar.
Sorpigal
-1

Para enumerar zombis de proceso, prueba este comando:

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

Es posible que deba cambiar $7según su sistema operativo.

Esto también devolverá la lista de sus identificadores de proceso padre ( PPID).

Para intentar matar a los zombies (después de probar el comando anterior), intente:

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

Para identificar a sus padres, intente con pstree, como:

$ 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
fuente
Recurrir a quitar una columna del jformato para esto es innecesariamente complicado. Use -opara seleccionar lo que desea en su lugar.
Sorpigal
2
ps jno imprime todos los procesos en el sistema. Solo enumera los procesos de usuario actuales (en el estilo de trabajos BSD), por lo que puede perder procesos zombie.
arielf