Чего я на самом деле пытаюсь достичь:
Я ' m пытается заставить настраиваемого демона работать в системе, использующей SysVinit. У меня уже есть сценарий bootstrapper /etc/init.d/xyz
, который вызывает мой демон, но не переводит его автоматически в фоновый режим. Это похоже на то, как ведут себя такие службы, как nginx
: сам двоичный фон - то есть скрипт /etc/init.d/nginx
не отвечает за демонизацию процесса, поэтому, если вы запустили / opt / nginx / sbin / nginx
напрямую, вы также испытаете демонизированное / фоновое выполнение.
Проблема
Моя проблема в том, что при использовании моего текущего метода демон не завершается с родительский процесс (который завершается, когда вы вызываете service xyz stop
).
Я использую родительскую программу запуска. sh
сценарий, запускающий сценарий daemon.sh &
. Однако, когда я убиваю launcher.sh
, daemon.sh
продолжает работать, несмотря на все мои усилия с trap
(он просто никогда не вызывается):
-> 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
./daemon.sh &
-> 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
все еще работает и выключение Функция
никогда не вызывается - я уже подтвердил это ранее, поместив эхо здесь
в тело функции.
Есть идеи?
РЕДАКТИРОВАТЬ: Программа запуска . Сценарий sh
запускается с использованием daemon launcher.sh
, где daemon
- функция, предоставляемая файлом Amazon Linux init.d / functions
(см. здесь : http://gist.github.com/ljwagerfield/ab4aed16878dd9a8241b14bc1501392 f).
Команда trap
работает только до тех пор, пока выполняется сценарий.
Обычно это делается так, что когда демон отключается, он пишет его PID в файл. Затем сценарий инициализации либо использует этот файл, чтобы определить, какой процесс убить, либо вызывает ваш сценарий запуска, чтобы убить процесс.
Для первого экземпляра:
launcher.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
, чтобы увидеть, как они это делают.
Мне непонятно, зачем вам нужны два скрипта для этого. Вы можете просто вызвать daemon.sh и
в своем сценарии инициализации? Или, возможно, вы можете использовать команду 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!"