desenv-web-rp.com

Maneira "adequada" de executar o script Shell como um daemon

Estou escrevendo um script Shell que gostaria de executar como um daemon na inicialização - sem usar ferramentas externas como daemontools ou daemonize.


HOWTO de gravação de daemon do Linux

De acordo com o HOWTO de gravação de daemon do Linux , um apropriado daemon possui as seguintes características:

  • bifurca-se do processo pai
  • fecha todos descritores de arquivos (ou seja, stdin, stdout, stderr)
  • abre logs para gravação (se configurado)
  • altera o diretório ativo para um diretório persistente (geralmente /)
  • redefine a máscara do modo de arquivo (umask)
  • cria um único ID da sessão (SID)

daemonize Introdução

O daemonize Introdução vai além, declarando que um daemon típico também:

  • desassocia-se do seu terminal de controle (se houver) e ignora todos os sinais do terminal
  • desassocia do seu grupo de processos
  • manipula SIGCLD

Como eu faria tudo isso em um script sh, dash ou bash apenas com ferramentas comuns do Linux?

O script deve ser capaz de executar o maior número possível de distribuições sem software adicional, embora Debian seja nosso foco principal.


NOTA: Eu sei que há muitas respostas na rede StackExchange rede recomendando o uso de Nohup ou setsid, mas nenhum desses métodos atende a todos os requisitos acima.


EDIT: A página de manual daemon (7) também fornece alguns indicadores, embora pareça haver algumas diferenças entre os estilos mais antigos SysV daemons e mais recentes systemd ones. Como a compatibilidade com uma variedade de distribuições é importante, verifique se a resposta esclarece todas as diferenças.


25
user339676

Usando systemd , você poderá executar um script como um daemon criando uma unidade simples. Existem muitas opções diferentes que você pode adicionar, mas isso é o mais simples possível.

Digamos que você tenha um script /usr/bin/mydaemon.

#!/bin/sh

while true; do
  date;
  sleep 60;
done

Você cria uma unidade /etc/systemd/system/mydaemon.service.

[Unit]
Description=My daemon

[Service]
ExecStart=/usr/bin/mydaemon
Restart=on-failure

[Install]
WantedBy=multi-user.target 

Para iniciar o demônio você corre

systemctl start mydaemon.service 

Para iniciar na inicialização, habilite-o

systemctl enable mydaemon.service

Se em um sistema baseado em sistema, que hoje é a maioria das distribuições Linux, essa não é realmente uma ferramenta externa. O negativo seria que, embora não funcione em todos os lugares.

21
johnramsden

Provavelmente estou perdendo alguma coisa aqui; por que exatamente Nohup não é apropriado? É claro que não basta sozinho, mas complementá-lo parece simples.

#!/bin/bash

if [ "$1" = "DAEMON" ]; then
    # is this necessary? Add other signals at will (TTIN TTOU INT STOP TSTP)
    trap '' INT
    cd /tmp
    shift
    ### daemonized section ######
    for i in $( seq 1 10 ); do
        date
        sleep 5
    done
    #### end of daemonized section ####
    exit 0
fi

export PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin
umask 022
# You can add Nice and ionice before Nohup but they might not be installed
Nohup setsid $0 DAEMON $* 2>/var/log/mydaemon.err >/var/log/mydaemon.log &

Tanto quanto eu posso ver:

  • a saída é redirecionada adequadamente (use/dev/null, se necessário)
  • o umask é herdado
  • stdin morre no final do script pai, no entanto
  • o script daemon.sh é reparado em init (ou systemd)

Tenho uma forte sensação de que estou perdendo o óbvio. Voto a favor, mas por favor me diga o que é :-)

7
LSerni

O comando Linux screen contido na maioria das distros pode daemonize um script Shell. Eu o uso frequentemente. Aqui está um exemplo rápido para iniciar, listar e sair de uma sessão de tela desanexada ...

# screen -dmS Session_Name  bash -c "while true; do date; sleep 60; done"

# screen -ls
There are screens on:
        8534.Session_Name       (04/04/2018 08:46:27 PM)        (Detached)

# screen -S Session_Name -X quit
4
S.Haran