如何找到僵尸进程?
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'
你得到的是Zombies和其他任何带有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=
这将发出两个以空格分隔的列,第一列是PID,第二列是其状态。
我不认为即使GNU ps
提供了一种直接按状态过滤的方法,但你可以用awk
可靠地做到这一点
ps axo pid=,stat= | awk '$2~/^Z/ { print }'
你现在是一个僵尸的PID列表。 由于您知道状态,因此不再需要显示它,因此可以将其过滤掉。
ps axo pid=,stat= | awk '$2~/^Z/ { print $1 }'
给出一个以换行符分隔的僵尸PID列表。
您现在可以使用简单的shell循环操作此列表
for pid in $(ps axo pid=,stat= | awk '$2~/^Z/ { print $1 }') ; do echo "$pid" # do something interesting here done
ps
是一个function强大的工具,您无需执行任何复杂的操作即可获取流程信息。
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;
但是要小心:这个也会杀死这个过程。
少即是多:
ps afuwwx | less +u -p'^(\S+\s+){7}Z.*'
就像,给我一个用户导向格式的森林(树),在任何tty上都有无限宽度,并在上面的半个屏幕显示给我,它与第8列包含Z的情况相符,并且为什么不突出整条线。
面向用户的格式似乎意味着: USER, PID, %CPU, %MEM, VSZ, RSS, TTY, STAT, START, TIME, COMMAND
因此Zombie状态将显示在第8列中。
如果你想要行号,可以在p
之前输入N
,如果你想在匹配时使用星号,则可以输入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 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.* …
您可以跟进(并且它将检测您的终端是否喜欢-U Unicode或-A Ascii):
pstree -psS
或者,你知道,使用less
的向上箭头来跟随层次结构中的树/林; 这就是我推荐的“少即是多”的方法。
我建议你这个命令:
ps aux | awk '"[Zz]" ~ $8 { printf("%s, PID = %d\n", $8, $2); }'
要列出进程僵尸,请尝试以下命令:
ps j | awk '$7 ~ "Z"'
您可能需要更改$7
具体取决于您的操作系统。
这也将返回其父进程ID( PPID
)的列表。
要尝试杀死僵尸(在测试上面的命令之后),请尝试:
kill -9 $(ps j | awk 'NR>1 && $7 ~ "Z" {print $2}')
要识别他们的父母,请尝试使用pstree
,例如:
$ 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)