爱国者*_*爱国者 28 linux bash process
有人告诉我,当你在linux中杀死一个父进程时,孩子会死.
但我对此表示怀疑.所以我写了两个bash脚本,在哪里father.sh调用child.sh
这是我的脚本:

现在我跑bash father.sh,你可以检查一下ps -alf

然后,我杀了father.sh的kill -9 24588,我猜子进程应该被终止但不幸的是我错了.

谁有人解释为什么?
谢谢
fge*_*fge 41
不,当你单独杀死一个进程时,它不会杀死孩子.
如果希望给定组的所有进程都接收信号,则必须将信号发送到进程组
kill -9 -parentpid
Run Code Online (Sandbox Code Playgroud)
否则,孤儿将被链接到init,如您的第三个屏幕截图所示(孩子的PPID已变为1).
小智 5
-bash:kill:( - 123) - 没有这样的过程
在交互式Terminal.app会话中,当启用作业控制/监视模式时,前台进程组ID号和后台进程组ID号在设计上是不同的.换句话说,如果在启用作业控制的Terminal.app会话中对命令进行$!后台处理,则后台进程的pid实际上是一个新的进程组ID号(pgid).
但是,在没有启用作业控制的脚本中,情况可能并非如此!背景过程的pid可能不是一个新的pgid,而是一个普通的pid!这就是导致错误消息的原因-bash: kill: (-123) - No such process,试图杀死进程组但只为kill命令指定了正常的pid(而不是pgid).
# the following code works in Terminal.app because $! == $pgid
{
sleep 100 &
IFS=" " read -r pgid <<EOF
$(ps -p $! -o pgid=)
EOF
echo $$ $! $pgid
sleep 10
kill -HUP -- -$!
#kill -HUP -- -${pgid} # use in script
}
Run Code Online (Sandbox Code Playgroud)
一般杀死父母也会杀死孩子.
您在杀死父亲后看到孩子仍然活着的原因是因为孩子在选择处理SIGKILL事件后才会死亡.它不必立即处理它.您的脚本正在运行sleep()命令,该命令在睡眠完成之前不会被唤醒以处理任何事件.
为什么PPID#1?父母已经死亡,不再在流程表中.child.sh现在没有莫名其妙地链接到init.它根本没有正在运行的父级.说它链接到init会产生一种印象,即如果我们以某种方式离开init,那init就可以控制关闭进程.它还会造成一种印象,即杀死父母会使祖父母成为孩子的主人.两者都不是真的.该子进程仍然存在于进程表中并且正在运行,但在处理SIGKILL之前,不会处理基于其进程ID的新事件.这意味着孩子是一个前僵尸,行尸走肉,有被贴上标签的危险.
在进程组中杀戮是不同的,用于杀死兄弟姐妹,并由进程组#来杀死父进程.同样重要的是要注意"杀死一个进程"本身并不是"杀死",而是以人为方式,你希望这个进程被破坏,并且所有内存都返回,就好像从未有过一样.它只是将许多特定事件发送给它要处理的进程.如果该过程没有正确处理,那么一段时间后操作系统会出现并强行"清理".
它(杀戮)不会立即发生,因为孩子(甚至父母)可能已经写了一些东西到磁盘并等待I/O完成或做一些可能危及系统稳定性或文件完整性的其他关键任务.