如何找到僵尸进程?

Pab*_*blo 137 process zombie

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:~$ 
Run Code Online (Sandbox Code Playgroud)

如何找到那个僵尸进程?

Dun*_*moo 165

要杀死僵尸(进程),您必须杀死其父进程(就像真正的僵尸!),但问题是如何找到它。

找到僵尸(问题回答了这一部分):

a@SERVER:~$ ps aux | grep 'Z'
Run Code Online (Sandbox Code Playgroud)

你得到的是 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
Run Code Online (Sandbox Code Playgroud)

找到僵尸的父母:

a@SERVER:~$ pstree -p -s 93572
Run Code Online (Sandbox Code Playgroud)

会给你:

init(1)---cnid_metad(1311)---cnid_dbd(5145)
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您不想杀死该父进程,您应该对一个僵尸进程感到非常满意,但是杀死直接父进程 5145 应该可以摆脱它。

关于 askubuntu 的其他资源:

  • 您在答案中显示的结果是 grep 命令本身,而不是僵尸进程。这与巴勃罗在他的回答中所做的错误解释相同。下面 Rinzwind 的答案实际上是在寻找僵尸进程并列出它们。另一种选择可能是 grep 为“已不存在” (3认同)
  • 如果你没有安装 pstree,`ps wauxf` 会做同样的事情 (2认同)
  • 我会添加“-w”标志。如“grep -w Z”中所示,仅匹配单词 Z 并避免混乱。 (2认同)

小智 47

尽管这个问题很老,但我认为每个人都应该得到一个更可靠的答案:

ps axo pid=,stat=
Run Code Online (Sandbox Code Playgroud)

这将发出两个以空格分隔的列,第一个是 PID,第二个是它的状态。

我认为即使 GNU 也没有ps提供一种直接按状态过滤的方法,但是您可以可靠地使用awk

ps axo pid=,stat= | awk '$2~/^Z/ { print }'
Run Code Online (Sandbox Code Playgroud)

您现在有一个僵尸 PID 列表。由于您知道状态,因此不再需要显示它,因此可以将其过滤掉。

ps axo pid=,stat= | awk '$2~/^Z/ { print $1 }'
Run Code Online (Sandbox Code Playgroud)

给出一个以换行符分隔的僵尸 PID 列表。

您现在可以使用一个简单的 shell 循环对这个列表进行操作

for pid in $(ps axo pid=,stat= | awk '$2~/^Z/ { print $1 }') ; do
    echo "$pid" # do something interesting here
done
Run Code Online (Sandbox Code Playgroud)

ps 是一个强大的工具,您无需执行任何复杂的操作即可从中获取过程信息。

(此处不同进程状态的含义 - https://unix.stackexchange.com/a/18477/121634

  • `awk` 也是一个强大的工具,它不仅可以拆分文本,还可以匹配它。+1 ...其他人在不必要且不精确的地方使用了`grep`。 (2认同)

dla*_*lin 7

少即是多:

ps afuwwx | less +u -p'^(\S+\s+){7}Z.*'
Run Code Online (Sandbox Code Playgroud)

这就像,给我一个面向用户格式的所有用户进程的森林(树),在任何 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.*
…
Run Code Online (Sandbox Code Playgroud)

可以跟进(它会检测您的终端是否喜欢 -U Unicode 或 -A Ascii):

pstree -psS <PID LIST>
Run Code Online (Sandbox Code Playgroud)

或者只是,你知道,使用向上箭头在less层次结构中跟随那棵树/森林;这就是我推荐的“少即是多”的方法。


小智 5

我通常在我的服务器上找到它们

ps aux | grep 'defunct'
Run Code Online (Sandbox Code Playgroud)