Qual é a diferença entre o start-stop-daemon e a execução com o &?

18

Estou configurando um serviço em /etc/init.d. Eu estou olhando vários scripts lá, alguns são implementados com start-stop-daemon ... e alguns com /path/to/script & .

Todos eles salvam o pid em um arquivo e fazem algumas verificações.

Qual é a melhor prática, quais são as diferenças, o que é importante saber aqui ...? (em geral)

No meu caso particular, eu tenho um servidor http localhost simples e leve em java que uma aplicação vai chamar uma vez a cada hora e apenas dá um número aleatório estúpido (sem mais detalhes aqui, eu só quero dizer que não usa o sistema de arquivos ou threads ou qualquer coisa complicada no caso deste assunto na minha pergunta)

Obrigado

    
por Thomas 28.10.2013 / 16:21

1 resposta

27

Um job em background (ou seja, iniciado com &) ainda tem stdin, stdout e stderr conectados ao terminal em que foi iniciado. Pode de repente gravar (por exemplo, mensagens de erro) no terminal ("perturbar" o trabalho em primeiro plano) ou pausar esperando pela entrada do teclado (você deve primeiro colocá-lo em primeiro plano). Você pode, obviamente, redirecionar stdout e stderr para um arquivo ou para / dev / null para evitar que o job em background grave no terminal.

Um trabalho em segundo plano também pode ser colocado em primeiro plano - por exemplo. a tarefa atual em primeiro plano é interrompida e o comando fg (primeiro plano) é usado para colocar uma tarefa em segundo plano em primeiro plano. Um trabalho em segundo plano também pode ser alcançado por sinais do terminal - por exemplo. SIGHUP quando você fecha o terminal, que geralmente termina (a maioria) programas iniciados no terminal.

Um daemon - como aqueles iniciados automaticamente pelo init.d, mas que também podem ser iniciados manualmente a partir de um terminal - por outro lado, é executado desconectado de qualquer terminal. Mesmo que tenha sido iniciado manualmente a partir de um terminal, um daemon será desconectado do terminal, por isso não pode gravar (stdout, stderr) nem ler (stdin) ele. Também é "imune" a sinais enviados "automaticamente" pelo terminal. (embora você possa enviar sinais para ele usando kill -signal pid ).

"Plano de fundo" e "primeiro plano" referem-se ao status do processo para algum terminal - se o processo atualmente está controlando o terminal ou não. Como os daemons não estão conectados a um terminal (mas foram desconectados em todos os sentidos), pode-se dizer que ele não está sendo executado em segundo plano. Os daemons são apenas processess em execução sem estarem associados a um terminal - nem na frente nem no fundo.

Se você usa ps com as opções que mostram qual terminal um processo usa, você verá que ambos os trabalhos preliminares e secundários estão associados a um terminal (por exemplo, tty2). Daemons, por outro lado, têm um "?" neste campo.

Os daemons geralmente se comportam como tal, mesmo que sejam iniciados manualmente. Criando um daemon de você mesmo, é um pouco de trabalho - há alguns truques envolvidos para desconectá-lo totalmente do terminal. Você deve criar seu próprio usuário / grupo para executar como. Você deve normalmente usar / tmp, / var / tmp ou / var / run se quiser criar arquivos - normalmente não deve ter direitos em nenhum outro lugar. Como ele não pode relatar erros para um terminal, você deve gravá-lo em um arquivo de log (por exemplo, seu próprio arquivo de log em / var / log). Os daemons devem fazer uma entrada em / var / run com seu PID atual e devem verificar se outra instância já está sendo executada. Deve respeitar bloqueios (/ var / lock) para arquivos ou dispositivos, quando aplicável. Ele deve responder ao SIGHUP recarregando seus arquivos de configuração e usando configurações atualizadas.

Outro ponto é como a maioria dos daemons funcionam. Um daemon geralmente é um único executável que pode ser executado em um dos dois modos distintos; dependendo se é o daemon original - o pai - iniciado na inicialização ou manualmente ... ou uma criança gerada por esse pai. O processo pai geralmente fica apenas aguardando algum evento - uma hora específica, o tempo passado, uma tentativa de se conectar a uma porta de rede específica ou o que quer que seja. Quando isso acontece, o pai cria um processo-filho idêntico a ele mesmo (usando a chamada de sistema fork ()) - e imediatamente volta a esperar por outro evento (e talvez gerando mais filhos). É o processo filho que realmente fará o trabalho - como sincronizar um disco, executar um comando (por exemplo, cron ) ou estabelecer uma conexão de rede (por exemplo, sshd ou ftpd ). A única diferença entre pai e filho é que eles têm PIDs diferentes e que o PPID (Pai-PID) do filho é o PID do processo pai - isso pode ser usado para determinar se o processo é pai ou filho. Portanto, o mesmo processo deve ser capaz de operar em dois modos - como o pai em espera (e desova) ou como filho trabalhador.

Embora não seja difícil escrever um daemon, também não é trivial - como você pode ver, existem alguns "truques" que você deve conhecer primeiro. Em geral, acho que escrever um daemon exigiria muito esforço por muito pouco ganho em comparação com outras alternativas:

Usar nohup ou disown em um trabalho de segundo plano geralmente é uma alternativa boa o suficiente, pois mantém o processo ativo mesmo se o terminal fechar. Geralmente, é uma boa idéia redirecionar stdout e stderr para um arquivo ou para / dev / null. Para programas mais interativos, screen é uma boa maneira de colocar algo "fora" até que você precise. at , batch e crontab também vale a pena para ser considerado.

    
por 28.10.2013 / 17:10