我偶然发现了这个帖子:
https://stackoverflow.com/questions/356722/killing-a-defunct-process-on-unix-system
“您已经终止了该进程,但是死进程不会从进程表中消失,直到其父进程执行称为“收割”的任务(本质上是调用 wait(3) 让该进程读取其退出状态)。尚未收割的死进程称为“僵尸进程”。
这是我的已停止的进程:
ps aux | grep ruby
1000 11958 16.3 0.0 0 0 pts/3 Z Jul11 1065:28 [ruby] <defunct>
它应该做的事情如下:
RAILS_ENV=production bundle exec ruby lib/daemons/db_service_ctl start%
它基本上运行 Rails 守护进程。我想重新启动它,所以我试图杀死它,但它拒绝死掉,现在我有一个已停止运行的进程。
这是它的父进程:
ps -f 11958
UID PID PPID C STIME TTY STAT TIME CMD
1000 11958 11957 16 Jul11 pts/3 Z 1065:28 [ruby] <defunct>
父进程是 11957。proc 命令行如下所示:
/proc/11957 $ cat cmdline
/bin/sh./script/db_service.sh%
这看起来就像我作为守护进程执行的相同的 shell 脚本!
那么这怎么可能是父进程呢?
答案1
简单来说——ruby 进程的父脚本db.service.sh
启动了一个可执行文件(PID 为 11958)。当您从脚本启动程序时,它是一个新进程,父进程是调用它的脚本。考虑这个脚本:
#!/bin/bash
cat
当你以 方式启动它时test.sh
,你会看到 bash 是父级,而 cat 是子级:
xxx 4087 10976 0 08:29 pts/2 00:00:00 /bin/bash ./test.sh
xxx 4088 4087 0 08:29 pts/2 00:00:00 cat