如何找到僵尸进程?

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)