我真正想要实现的目标是:
我正在尝试让自定义守护进程在使用 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 &
->守护进程
#!/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 Linux 文件提供的函数init.d/functions
(参见此处:http://gist.github.com/ljwagerfield/ab4aed16878dd9a8241b14bc1501392f).
答案1
trap
仅当脚本运行时,该命令才有效。
通常的做法是,当守护进程被分叉时,它会将其 PID 写入一个文件。然后,init 脚本要么使用该文件来确定要终止哪个进程,要么调用启动器脚本来终止该进程。
首先:
启动器.sh:
/path/to/daemon.sh &
echo "$!" > /var/run/xyz.pid
一个简单而又有点幼稚的版本/etc/init.d/xyz
:
# ... pull in functions or sysconfig files ...
start() {
# ... do whatever is needed to set things up to start ...
/path/to/launcher.sh
}
stop() {
# ... do whatever is needed to set things up to stop ...
kill `cat /var/run/xyz.pid`
}
# ... other functions ...
非简单启动脚本将取决于您正在运行的 Linux 版本;我建议查看其他示例以/etc/init.d
了解它们是如何做到这一点的。
答案2
我不明白为什么要用两个脚本来做这件事。你能直接调用daemon.sh &
你的 init 脚本吗?或者你可以使用命令daemon
。
NAME
daemon - turns other processes into daemons
SYNOPSIS
usage: daemon [options] [--] [cmd arg...]
如果您需要使用 trap,也许您可以使用它来daemon.sh
干净地关闭。很难说这些是您的真正脚本还是只是示例。
部分问题在于launcher.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 *** script keeps running ***
./daemon.sh &
# It exits here
echo "Exiting... bye!"