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:~$
そのゾンビプロセスを見つける方法は?
ゾンビ(プロセス)を殺すには、その親プロセス(本当のゾンビのように!)を殺さなければなりませんが、問題はそれを見つける方法でした。
ゾンビを見つける(質問はこのパートに答えました):
a@SERVER:~$ ps aux | grep 'Z'
あなたが得るものはゾンビとその中に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)
この場合、その親プロセスを強制終了したくないため、1つのゾンビに非常に満足している必要がありますが、直接の親プロセス5145を強制終了すると削除されます。
Askubuntuに関する追加リソース:
この質問は古いものですが、誰もがより信頼できる答えに値すると思いました。
ps axo pid=,stat=
これにより、空白で区切られた2つの列が生成されます。最初の列はPIDで、2番目の列はその状態です。
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
は強力なツールであり、プロセス情報を取得するために複雑なことをする必要はありません。
しかし、少ないほど多い:
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.*
…
couldをフォローアップします(そして、端末が-U Unicodeまたは-A Asciiを好むかどうかを検出します):
pstree -psS <PID LIST>
または、ご存知のとおり、less
の上矢印を使用して、階層内でそのツリー/フォレストをたどります。これは、「より少ない」アプローチで推奨していたことです。
ps aux | awk '{ print $8 " " $2 }' | grep -w Z
From: 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 | awk '"[Zz]" ~ $8 { printf("%s, PID = %d\n", $8, $2); }'