O que realmente estou tentando alcançar:
Estou tentando fazer um daemon personalizado funcionar em um sistema que usa o SysVinit. Já tenho o /etc/init.d/xyz
script bootstrapper, que chama meu daemon, mas não o coloca automaticamente em segundo plano. Isso é semelhante a como serviços como nginx
se comportam: os fundos binários em si - ou seja, não é responsabilidade do /etc/init.d/nginx
script daemonizar o processo, portanto, se você executar /opt/nginx/sbin/nginx
diretamente, também experimentará a execução daemonizada/em segundo plano.
O problema
Meu problema é que, usando meu método atual, o daemon não termina com o processo pai (que é o que é encerrado quando você chama service xyz stop
).
Estou usando um launcher.sh
script pai que executa um daemon.sh &
script. No entanto, quando eu mato launcher.sh
o daemon.sh
continue a ser executado, apesar dos meus melhores esforços com trap
(ele simplesmente nunca é chamado):
-> 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
Para correr e matar:
./launcher.sh
<get PID for launcher>
kill -TERM 123 # PID of launcher.sh... which _is_ still running and has its own PID.
Resultado: daemon.sh
ainda em execução e a shutdown
função nunca é chamada - confirmei isso antes colocando um echo here
no corpo da função.
Alguma ideia?
EDIT: O launcher.sh
script está sendo executado usando daemon launcher.sh
, onde daemon
está uma função fornecida pelo arquivo do Amazon Linux init.d/functions
(veja aqui: http://gist.github.com/ljwagerfield/ab4aed16878dd9a8241b14bc1501392 f).
O
trap
comando só funciona enquanto o script estiver em execução.A maneira como isso normalmente é feito é que, quando o daemon é bifurcado, ele grava seu PID em um arquivo. O script de inicialização então usa esse arquivo para determinar qual processo matar ou chama seu script de inicialização para matar o processo.
Para a primeira instância:
launcher.sh:
Uma versão simples e um tanto ingênua de
/etc/init.d/xyz
:Um script de inicialização não ingênuo dependerá de qual versão do Linux você está executando; Eu sugeriria olhar para outros exemplos
/etc/init.d
para ver como eles fazem isso.Não faz sentido para mim por que você deseja que dois scripts façam isso. Você pode simplesmente chamar
daemon.sh &
seu script de inicialização? Ou talvez você possa usar odaemon
comando.Se você precisar usar trap, talvez possa usá-lo
daemon.sh
para um desligamento limpo. É difícil dizer se esses são seus scripts reais ou apenas exemplos.Parte do problema
launcher.sh
é que ele sai ... não há nada para mantê-lo funcionando, então você não pode matá-lo - ele já se foi. Não estou apenas dizendo isso, na verdade testei seu script para ter certeza antes de responder. Veja meus comentários adicionados ao seu script.