Portanto, o problema que você está vendo aqui é porque quando Type=forking
está em uso, o arquivo pid deve ser criado (com o pid correto) antes que o processo pai saia.
Se você criar o pidfile do filho, ele irá correr com a saída do pai e, em alguns (muitos?) casos, o primeiro erro será visto.
Se você criar o pidfile escrevendo $$
antes de iniciar o filho, ele terá o pid do pai, que será encerrado, para que você veja o outro erro.
Uma maneira de fazer isso corretamente é escrever o pidfile do pai, logo antes de sair. Nesse caso, escreva $!
(e não $$
), que retorna o pid do último processo gerado em segundo plano.
Por exemplo:
#!/bin/bash
# Run the following code in background:
(
while keep_running; do
do_something
done
) &
# Write pid of the child to the pidfile:
echo "$!" >/run/daemon.pid
exit
Isso deve funcionar corretamente ... CONTUDO , há uma maneira muito melhor de conseguir isso! Leia em ...
Na verdade, o ponto inteiro do systemd é para daemonizar processos e executá-los em segundo plano para você ... Ao tentar fazer isso sozinho, você está apenas evitando que o systemd faça isso por você. O que está tornando a sua vida muito mais difícil ao mesmo tempo ...
Em vez de usar Type=forking
, basta escrever seu script de shell para executar em primeiro plano e configurar o serviço para usar Type=simple
. Você não precisa de nenhum pidfiles então.
Atualize seu /root/bin/daemon.sh
para simplesmente fazer isso:
#!/bin/bash
# Run the following code in foreground:
while keep_running; do
do_something
done
(NOTA: Talvez daemon.sh
não seja o melhor nome para ele neste momento ... Desde que isso implicaria que ele é executado em segundo plano. Talvez nomeie algo mais apropriado, relacionado ao que ele realmente faz.)
Em seguida, atualize o arquivo .service
para usar Type=simple
(que, na verdade, seria usado por padrão aqui, então você pode até omiti-lo.)
[Service]
Type=simple
ExecStart=/root/bin/daemon.sh
ExecReload=/bin/kill -1 -- $MAINPID
ExecStop=/bin/kill -- $MAINPID
TimeoutStopSec=5
KillMode=process
BTW, você provavelmente pode derrubar ExecStop=
, já que matar o processo com um sinal também é o comportamento padrão ...
O Type=forking
do systemd está realmente lá apenas para programas legados que só funcionam dessa maneira e não podem ser facilmente corrigidos para trabalhar em primeiro plano ... É hacky e ineficiente. O ponto principal do systemd (e algumas de suas alternativas, predecessores) é fazer o bifurcação e a daemonização em si e deixar os serviços se preocuparem em fazer o que precisam fazer! : -)
Espero que você ache isto útil ... E eu realmente espero que você escolha deixar o systemd fazer o trabalho pesado para você! É muito mais eficiente assim.