用于查找僵尸进程的 Bash 脚本?

can*_*atz 3 command-line bash scripts process zombie

所以最近我注意到我有一个进程会随机崩溃并变成一个 PPID 为 1 (init) 的僵尸。有人告诉我,解决此问题的唯一方法是重新启动 PC(或将 SIGCHLD 发送到 init,据我所知,这是....冒险/无用。)

本质上,我想要做的是编写一个 bash 脚本,该脚本将只查找僵尸进程,如果有,则重新启动 PC。

目前,我使用这个脚本来监控进程本身:

 ps auxw | grep ethminer | grep -v grep > /dev/null

 if [ $? != 0 ]
 then
    sudo reboot
 fi
Run Code Online (Sandbox Code Playgroud)

现在,当 ethminer 正在运行或未运行时,此脚本似乎可以正常工作;如果在进程表中没有看到 ethminer,它将重新启动机器,如果没有看到它,它什么也不做。

然而,(从我公认的松散理解)因为当进程变成僵尸时没有退出代码if [ $? != 0 ]不会得到任何输入,因此不会做任何事情。

无论如何我可以修复/修改这个脚本,让它做我想做的事吗?还是我在这里偏离了轨道?

谢谢!

hee*_*ayl 5

reboot当它们是僵尸进程时,您不必这样做。原因如下:

  • 当进程完成时,进程变成僵尸进程,但它的父进程没有调用wait(2)它的返回码

  • 除了内核进程表中的一个条目外,僵尸不占用任何物理或虚拟资源

  • 一旦父调用wait(2),僵尸将被正确收割,进程表条目将被删除

  • 如果僵尸变成孤儿,即如果它的父母死了,那么init(PID 1) 将继承该进程并通过调用获得它wait(2)

如您所见,wait(2)调用 并收割僵尸只是时间问题。如果你有很多僵尸随着时间的推移,认为这是一个编程缺陷,你应该考虑修复(或要求修复)代码而不是rebooting,这是绝对不必要的,不应该这样做。


要找到僵尸进程,获取STATE进程的 ,如果是Z,则该进程是僵尸进程:

ps -eo pid,ppid,state,cmd | awk '$3=="Z"'
Run Code Online (Sandbox Code Playgroud)

在这里,我只采用了选择性字段,即 PID、PPID、STATE 和 COMMAND。