問題描述
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)
在這種情況下,你不想殺死父進程,並且你應該對一個僵屍非常滿意,但是殺死直接父進程5145應該消除它。
askubuntu上的其他資源:
次佳解決思路
盡管這個問題很老,但我認為每個人都應該得到一個更可靠的答案:
ps axo pid=,stat=
這將發出兩個whitespace-delimited列,其中第一個是PID,第二個是它的狀態。
我不認為即使GNU ps
提供了一種直接按狀態過濾的方法,但是您可以使用awk
ps axo pid=,stat= | awk '$2~/^Z/ { print }'
你現在是一個僵屍的PID列表。由於您知道該狀態,因此不再需要顯示它,以便可以將其過濾掉。
ps axo pid=,stat= | awk '$2~/^Z/ { print $1 }'
提供newline-delimited僵屍PID列表。
您現在可以使用簡單的shell循環在此列表上進行操作
for pid in $(ps axo pid=,stat= | awk '$2~/^Z/ { print $1 }') ; do
echo "$pid" # do something interesting here
done
ps
是一個功能強大的工具,您無需做任何複雜的工作即可獲取流程信息。
第三種解決思路
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;
盡管如此:這一個也殺死了這個過程。
參考資料