我实际上想要实现的目标:
我正在尝试让自定义守护程序在使用 SysVinit 的系统上运行。我已经有引导程序/etc/init.d/xyz
脚本,它调用我的守护程序,但它不会自动将它放在后台。这类似于服务的nginx
行为方式:二进制背景本身 - 即/etc/init.d/nginx
脚本不负责守护进程,因此如果您/opt/nginx/sbin/nginx
直接运行,您也会遇到守护进程/后台执行。
问题
我的问题是,使用我当前的方法,守护进程不会随父进程终止(当您调用 时会终止service xyz stop
)。
我正在使用launcher.sh
运行脚本的父daemon.sh &
脚本。然而,当我杀死继续运行时,尽管我尽了最大努力launcher.sh
(它根本不会被调用):daemon.sh
trap
-> 启动器.sh
#!/bin/bash
function shutdown {
# Get our process group id
PGID=$(ps -o pgid= $$ | grep -o [0-9]*)
echo THIS NEVER GETS CALLED!
# Kill process group in a new process group
setsid kill -- -$$
exit 0
}
trap "shutdown" SIGTERM
# Run daemon in background
./daemon.sh &
-> 守护进程.sh
#!/bin/bash
while true
do
sleep 1
done
运行和杀死:
./launcher.sh
<get PID for launcher>
kill -TERM 123 # PID of launcher.sh... which _is_ still running and has its own PID.
结果:daemon.sh
仍在运行并且shutdown
函数永远不会被调用 - 我之前已经通过echo here
在函数体中放置一个来确认这一点。
有任何想法吗?
编辑:脚本launcher.sh
正在使用 运行daemon launcher.sh
,其中daemon
是 Amazon Linuxinit.d/functions
文件提供的函数(参见此处: http: //gist.github.com/ljwagerfield/ab4aed16878dd9a8241b14bc1501392 f)。
该
trap
命令仅在脚本运行时才有效。通常这样做的方式是,当守护进程被分叉时,它将其 PID 写入文件。然后,init 脚本要么使用该文件来确定要终止的进程,要么调用您的启动器脚本来终止该进程。
对于第一种情况:
启动器.sh:
一个简单且有点幼稚的版本
/etc/init.d/xyz
:非天真的启动脚本将取决于您正在运行的 linux 版本;我建议查看其他示例,
/etc/init.d
看看他们是如何做到这一点的。为什么你想要两个脚本来做这件事对我来说没有意义。你可以只调用
daemon.sh &
你的初始化脚本吗?或者,也许您可以使用该daemon
命令。如果您需要使用陷阱,也许您可以使用它
daemon.sh
来彻底关闭。很难判断这些是您的真实脚本还是只是示例。问题的一部分
launcher.sh
是它退出了......没有任何东西让它运行,所以你不能杀死它 - 它已经消失了。我不只是这么说,我实际上测试了你的脚本以确保在我回答之前。请参阅我添加到您的脚本中的评论。