Come trovare il processo di zombi?


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

Come trovare quel processo di zombi?


perché non apri il monitor di sistema e cerchi il processo di zombi?
dlin,

8
Come farlo su un server no-X senza testa?
SabreWolfy,

2
Sorprendente che nessuna risposta qui sotto in realtà affermi che non vi è alcun processo di zombi nel sistema basato sull'output di cui sopra. Se ce n'era davvero uno, il ps auxwww | grep 'Z'comando avrebbe dovuto mostrare un processo in uno Zstato. Il detto "informazioni di sistema" => There is 1 zombie process.sembra essere un bug. O quello, o ci sono informazioni mancanti nella domanda.
Ari

Risposte:


126

Per uccidere uno zombi (processo) devi uccidere il suo processo genitore (proprio come i veri zombi!), Ma la domanda era come trovarlo.

Trova lo zombi (La domanda ha risposto a questa parte):

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

Quello che ottieni sono gli zombi e qualsiasi altra cosa con una Z, quindi otterrai anche il 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

Trova il genitore dello zombi:

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

Ti darà:

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

In questo caso non vuoi uccidere quel processo genitore e dovresti essere abbastanza felice con uno zombi, ma uccidendo il processo genitore immediato 5145 dovresti sbarazzartene.

Risorse aggiuntive su askubuntu:


1
Il risultato che mostri nella tua risposta è il comando grep stesso, non il processo di zombi. È la stessa interpretazione errata di Pablo nella sua risposta. La risposta di Rinzwind di seguito in realtà cerca il processo di zombi e li elenca. Un'altra opzione potrebbe essere quella di chiedere "defunto"
FvD

pstree -H your_desired_pid -p
Greg M. Krsak

Grazie Greg per aver aggiunto alla discussione, ma ricorda che questo è un sito di aiuto, semplicemente incollare un comando senza spiegare nulla non è utile per la maggior parte delle persone che vengono qui in cerca di aiuto.
Duncanmoo,

1
Questa è un'ottima risposta! È ancora valido oggi! Sono stato in grado di trovare il mio processo di zombi e uccidere il suo processo genitore senza problemi. Grazie!
Terrance

1
se non hai installato pstree, ps wauxffa la stessa cosa
JDS

35

Anche se questa domanda è vecchia, pensavo che tutti meritassero una risposta più affidabile:

ps axo pid=,stat=

Questo emetterà due colonne delimitate da spazi bianchi, il primo dei quali è un PID e il secondo è il suo stato.

Non penso che nemmeno GNU psoffra un modo per filtrare direttamente per stato, ma puoi farlo in modo affidabileawk

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

Ora hai un elenco di PID che sono zombi. Dato che conosci lo stato non è più necessario visualizzarlo, in modo che possa essere filtrato.

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

Fornire un elenco delimitato da nuova riga di PID di zombi.

Ora puoi operare su questo elenco con un semplice loop di shell

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

ps è uno strumento potente e non è necessario fare nulla di complicato per ricavarne informazioni di processo.

(Significato dei diversi stati del processo qui - https://unix.stackexchange.com/a/18477/121634 )


2
awkè anche un potente strumento che non solo divide il testo ma può anche abbinarlo. +1 ... gli altri hanno usato grepdove non è necessario e impreciso.
0xC0000022L

così ora che ho un elenco di processi di zombi. come li uccido?
amorevole

@chovy: dipenderà, ma generalmente comporta l'uccisione o la segnalazione al genitore. Altre risposte qui vanno a quello. Dall'interno mostrato sopra puoi trovare il pid genitore in questo modo:ps -p "$pid" -opid=,ppid=
Sorpigal

se lo farò il genitore non ucciderà tutti i suoi processi figlio? Voglio solo uccidere il processo di uno zombi. Conosco il ppid.
amorevole

1
Suggerisco di aggiungere ppid=all'elenco delle opzioni, quindi non è necessario utilizzare un comando separato per ottenere ppid.
Ding-Yi Chen il

3

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

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

Dai commenti uno migliorato:

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;

Attenzione però: anche questo uccide il processo.


non restituisce ancora nulla. Penso che anche la mia strada non fosse sbagliata.
Pablo

Il secondo esempio è incredibilmente inaffidabile e il primo è inutilmente prolisso (prova ps axo pid=,stat= | awk '$2~/Z/ {print $1}'invece).
Sorpigal,

3

Meno è di più però:

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

È come, dammi una foresta (albero) di tutti i processi degli utenti in un formato orientato all'utente con larghezza illimitata su qualsiasi tty e mostramelo a metà schermo sopra dove corrisponde al caso in cui l'ottava colonna contenga una Z, e perché non evidenziare l'intera linea.

Il formato orientato all'utente sembra significare: USER, PID, %CPU, %MEM, VSZ, RSS, TTY, STAT, START, TIME, COMMANDquindi lo stato di Zombie apparirà nell'ottava colonna.

Puoi inserire un Nprima del pse vuoi numeri di riga e un Jse vuoi un asterisco alla partita. Purtroppo se si utilizza Gper non evidenziare la linea che l'asterisco non mostrerà, anche se Jcrea spazio per esso.

Alla fine ottieni qualcosa che assomiglia 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.*
…

Si potrebbe seguire questa con (e si metterà a rilevare se il terminale piace -U Unicode o -A Ascii):

pstree -psS <PID LIST>

O semplicemente, sai, usa la freccia in su lessper seguire quell'albero / foresta attraverso la gerarchia; che è quello che stavo raccomandando con l'approccio "Less is more".


0

Ti suggerisco questo comando:

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

L'uso auxe la fusione delle stringhe non è inutilmente affidabile quando è possibile utilizzare -oe richiedere esattamente ciò che si desidera. Usa ps ax -o pid=,stat= | awk '$2 ~ "[Zz]" { printf("%s, PID = %d\n", $2, $1); }'invece.
Sorpigal,

-1

Per elencare gli zombi di processo, prova questo comando:

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

Potrebbe essere necessario cambiare a $7seconda del sistema operativo in uso.

Questo restituirà anche l'elenco dei loro ID processo parent ( PPID).

Per provare a uccidere gli zombi (dopo aver testato il comando sopra), prova:

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

Per identificare i loro genitori, prova con pstree, come:

$ 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)

Ricorrere a rimuovere una colonna dal jformato per questo è inutilmente complicato. Utilizzare invece -oper selezionare ciò che si desidera.
Sorpigal,

2
ps jnon stampa tutti i processi nel sistema. Elenca solo i proc correnti dell'utente (nello stile dei lavori BSD) in modo da poter perdere i processi zombi.
Ari
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.