问题描述
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;
尽管如此:这一个也杀死了这个过程。
参考资料