Bagaimana cara menemukan proses 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:~$ 

Bagaimana menemukan proses zombie itu?

Pablo
sumber
mengapa Anda tidak membuka monitor sistem dan mencari proses zombie?
dlin
8
Bagaimana melakukannya di server no-X tanpa kepala?
SabreWolfy
2
Mengejutkan bahwa tidak ada jawaban di bawah ini yang benar-benar mengatakan bahwa tidak ada proses zombie dalam sistem berdasarkan output di atas. Jika memang ada, ps auxwww | grep 'Z'perintah seharusnya menunjukkan proses dalam Zkeadaan. Pepatah "informasi sistem" => There is 1 zombie process.tampaknya merupakan bug. Entah itu, atau ada informasi yang hilang dalam pertanyaan.
arielf

Jawaban:

126

Untuk membunuh zombie (proses) Anda harus membunuh proses induknya (sama seperti zombie asli!), Tetapi pertanyaannya adalah bagaimana menemukannya.

Temukan zombie (Pertanyaan menjawab bagian ini):

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

Yang Anda dapatkan adalah Zombies dan yang lainnya dengan Z di dalamnya, jadi Anda juga akan mendapatkan 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

Temukan orang tua zombie:

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

Akan memberimu:

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

Dalam hal ini Anda tidak ingin membunuh proses induk itu dan Anda seharusnya cukup senang dengan satu zombie, tetapi membunuh proses induk langsung 5145 harus menyingkirkannya.

Sumber daya tambahan di askubuntu:

Duncanmoo
sumber
1
Hasil yang Anda tunjukkan dalam jawaban Anda adalah perintah grep itu sendiri, bukan proses zombie. Ini adalah salah interpretasi yang sama seperti yang dilakukan Pablo dalam jawabannya. Jawaban oleh Rinzwind di bawah ini sebenarnya mencari proses zombie dan daftar mereka. Pilihan lain bisa jadi untuk "mati"
FvD
pstree -H your_desired_pid -p
Greg M. Krsak
Terima kasih Greg untuk menambah diskusi, tetapi harap ingat ini adalah situs bantuan, hanya menempelkan perintah tanpa menjelaskan apa pun tidak membantu kebanyakan orang yang datang ke sini mencari bantuan.
Duncanmoo
1
Ini jawaban yang bagus! Itu masih berlaku hari ini! Saya dapat menemukan proses zombie saya dan membunuh proses induknya tanpa masalah. Terima kasih!
Terrance
1
jika Anda belum menginstal pstree, ps wauxflakukan hal yang sama
JDS
35

Meskipun pertanyaan ini sudah tua, saya pikir semua orang pantas mendapat jawaban yang lebih andal:

ps axo pid=,stat=

Ini akan memancarkan dua kolom dibatasi-spasi, yang pertama adalah PID dan yang kedua adalah negara.

Saya tidak berpikir bahkan GNU psmenyediakan cara untuk memfilter menurut negara secara langsung, tetapi Anda dapat melakukannya dengan andalawk

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

Anda sekarang memiliki daftar PID yang merupakan zombie. Karena Anda tahu statusnya, tidak perlu lagi menampilkannya, sehingga dapat disaring.

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

Memberikan daftar PID zombie yang dibatasi-baris baru.

Anda sekarang dapat beroperasi pada daftar ini dengan loop shell sederhana

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

ps adalah alat yang ampuh dan Anda tidak perlu melakukan sesuatu yang rumit untuk mendapatkan informasi proses dari itu.

(Arti dari berbagai proses di sini - https://unix.stackexchange.com/a/18477/121634 )

Sorpigal
sumber
2
awkjuga merupakan alat yang ampuh yang tidak hanya membagi teks tetapi juga dapat mencocokkannya. +1 ... yang lain digunakan di greptempat yang tidak perlu dan tidak tepat.
0xC0000022L
jadi sekarang saya punya daftar proses zombie. bagaimana saya membunuh mereka?
chovy
@ chovy: Itu akan tergantung, tetapi umumnya melibatkan pembunuhan atau pensinyalan orangtua. Jawaban lain di sini masuk ke sana. Dari dalam loop yang ditunjukkan di atas, Anda dapat menemukan pid induk seperti ini:ps -p "$pid" -opid=,ppid=
Sorpigal
jika saya mau orangtua tidak akan membunuh semua proses anaknya? Saya hanya ingin membunuh satu proses zombie. Saya tahu ppid.
chovy
1
Saya menyarankan untuk menambahkan ppid=ke daftar opsi, jadi tidak perlu menggunakan perintah terpisah untuk mendapatkan ppid.
Ding-Yi Chen
3

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

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

Dari komentar yang lebih baik:

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;

Hati-hati: yang ini juga membunuh prosesnya.

Rinzwind
sumber
masih tidak menghasilkan apa-apa. Saya pikir cara saya juga tidak salah.
Pablo
Contoh ke-2 sangat tidak dapat diandalkan dan yang pertama tidak perlu diucapkan (coba ps axo pid=,stat= | awk '$2~/Z/ {print $1}'saja).
Sorpigal
3

Kurang lebih lebih:

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

Itu seperti, beri saya hutan (pohon) dari semua proses pengguna dalam format yang berorientasi pengguna dengan lebar tak terbatas pada setiap tty dan tunjukkan kepada saya di setengah layar di atas di mana itu cocok dengan kasus bahwa kolom ke-8 berisi Z, dan mengapa tidak menyorot seluruh baris.

Format berorientasi pengguna tampaknya berarti: USER, PID, %CPU, %MEM, VSZ, RSS, TTY, STAT, START, TIME, COMMANDsehingga status Zombie akan muncul di kolom ke-8.

Anda dapat memasukkan tanda Nsebelum pjika Anda ingin nomor baris, dan Jjika Anda ingin tanda bintang di pertandingan. Sayangnya jika Anda menggunakan Guntuk tidak menyorot garis yang tidak akan ditampilkan asterisk, meskipun Jmenciptakan ruang untuk itu.

Anda akhirnya mendapatkan sesuatu yang terlihat seperti:

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

Anda dapat menindaklanjuti ini dengan (dan itu akan mendeteksi jika terminal Anda suka -U Unicode atau -A Ascii):

pstree -psS <PID LIST>

ATAU hanya, Anda tahu, gunakan panah atas lessuntuk mengikuti pohon / hutan itu melalui hierarki; itulah yang saya rekomendasikan dengan pendekatan "Less is more".

dlamblin
sumber
0

Saya menyarankan Anda perintah ini:

ps aux | awk '"[Zz]" ~ $8 { printf("%s, PID = %d\n", $8, $2); }'
Peycho Dimitrov
sumber
Menggunakan auxdan mengeluarkan string dari itu tidak dapat diandalkan ketika Anda dapat menggunakan -odan meminta apa yang Anda inginkan. Gunakan ps ax -o pid=,stat= | awk '$2 ~ "[Zz]" { printf("%s, PID = %d\n", $2, $1); }'sebagai gantinya.
Sorpigal
-1

Untuk membuat daftar zombie proses, coba perintah ini:

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

Anda mungkin perlu berubah $7tergantung pada sistem operasi Anda.

Ini juga akan mengembalikan daftar id proses induknya ( PPID).

Untuk mencoba membunuh zombie (setelah menguji perintah di atas), coba:

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

Untuk mengidentifikasi orang tua mereka, cobalah dengan pstree, seperti:

$ 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
sumber
Memilih untuk mengeluarkan satu kolom dari jformat untuk ini tidak perlu rumit. Gunakan -ountuk memilih apa yang Anda inginkan.
Sorpigal
2
ps jtidak mencetak semua proses dalam sistem. Itu hanya mencantumkan procs pengguna saat ini (dalam gaya pekerjaan BSD) sehingga dapat melewatkan proses zombie.
arielf