尽管进程仍在运行,但父 bash 脚本未收到“陷阱”

尽管进程仍在运行,但父 bash 脚本未收到“陷阱”

我真正想要实现的目标是:

我正在尝试让自定义守护进程在使用 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/ab4aed16878dd9a8241b14bc1501392‌​f).

答案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!"

相关内容