%3F%20Executar%20como%20processo%20em%20segundo%20plano.png)
Quais são as etapas para desvincular o processo do terminal? Para isso encontrei a página de manual dedaemon()
Na descrição, eles mencionaram
Se nochdir for zero, daemon() altera o diretório de trabalho atual do processo para o diretório raiz ("/"); caso contrário, o diretório de trabalho atual permanecerá inalterado.
Se noclose for zero, daemon() redireciona a entrada padrão, a saída padrão e o erro padrão para /dev/null; caso contrário, nenhuma alteração será feita nesses descritores de arquivo.
Na verdade, eu estava tentando fazer meu código python rodar como daemon. encontrei tcollector
o códigoaqui. Nesse código também eles estão seguindo os mesmos passos da descrição de daemon()
. Então, minha pergunta é: por que deveríamos seguir essas etapas (wrtdaemonize()
em tcollector
) como
por que mudar dir
para /
, umask
para 022
e depois ligar os.setsid()
, etc.
Responder1
Na verdade, há mais do que você citou, mas acho que essa página de manual poderia ser mais clara.
Se nochdir for zero,
daemon()
altera o diretório de trabalho atual do processo para o diretório raiz (/
)
A suposição aqui é que o programa é iniciado a partir de uma linha de comando do administrador e a ideia é desassociar o daemon do que o administrador estava fazendo no momento. Alterar o diretório de trabalho para /
evita que o daemon mantenha um ponto de montagem ocupado. Por exemplo, se o diretório de trabalho fosse /home/admin
e algum tempo depois você quisesse desmontar /home
, o daemon impediria isso.
Se noclose for zero,
daemon()
redireciona a entrada padrão, a saída padrão e o erro padrão para/dev/null
;
Isso evita que o daemon confunda os usuários escrevendo mensagens de erro perdidas ou semelhantes em seus terminais. O que o daemon provavelmente deveria fazer é abrir algum arquivo de log (configurado) e escrever lá tudo o que deseja comunicar ao exterior.
(Essa função se bifurca e, se fork(2) for bem-sucedido, o pai chama _exit(2), para que erros adicionais sejam vistos apenas pelo filho.)
Novamente, para desassociar-se da sessão do shell do administrador, o programa principal retorna imediatamente e a outra parte permanece em segundo plano, portanto não há necessidade de solicitar explicitamente que o programa seja iniciado em segundo plano (por exemplo ./daemon &
)
Agora, o que a página de manual não diz explicitamente, mas implica aqui (em BUGS):
A implementação da biblioteca GNU C desta função foi retirada do BSD e não emprega a técnica de bifurcação dupla (ou seja, fork(2), setsid(2), fork(2)) que é necessária para garantir que o processo daemon resultante não é um líder de sessão. Em vez disso, o daemon resultante é um líder de sessão.
daemon()
também ligasetsid()
para se libertar da sessãoterminal de controlee, portanto, dos sinais enviados pelo terminal. Mas, como diz a citação, isso deixa a possibilidade de que, se abrir um dispositivo terminal, ele possa acidentalmente obtê-lo como um terminal de controle. Para evitar isso, alguns programas chamam fork()
, depois setsid()
do filho e depois bifurcam novamente, saindo de ambos os pais para que o processo resultante não seja um líder de sessão (o do meio é/era) e não possa obter um terminal de controle. O programa Python ao qual você se refere faz exatamente isso.
Alterar o umask
não parece estar relacionado à daemonização. Talvez esse programa tenha uma necessidade especial.