Por que meu aplicativo morre sem nohup?

3

Eu tenho um sistema simples (rodando no Debian) que funciona invocando um script de /etc/init.d/rc.local

Na parte inferior de rc.local, chamo myScript.sh, que configura algumas coisas e, em seguida, inicia um binário como este:

./myBinary > /dev/null 2>&1 &

Funciona bem por um tempo, mas depois de algum tempo myBinary sai. No entanto, se eu modificar o script para fazer isso:

nohup ./myBinary > /dev/null 2>&1 &

Funciona bem (testei por aproximadamente 8 horas).

Do meu entendimento SIGHUP é enviado quando o terminal que controla o processo é fechado, e nohup faz com que esse sinal seja ignorado.

Parece que meu software está sendo enviado para o SIGHUP, mas não entendo o porquê. Alguém pode explicar?

Editar: aqui está o script real

#!/bin/bash
clear
/home/pi/hdmi-switcher/hdmi-switcher version
/home/pi/hdmi-switcher/update.sh
printf "Starting switching daemon..."
cd /home/pi/hdmi-switcher
./hdmi-switcher > /dev/null 2>&1 &
printf "\tOK\n"
printf "Starting video... "
sleep 5
printf "\tOK\n"
omxplayer --loop --no-osd -b -o both /home/pi/hdmi-switcher/video.mp4 > /dev/null 2>&1
clear

A coisa que morre é hdmi-switcher . O omxplayer não tem problemas.

    
por Cameron Ball 17.04.2015 / 08:13

1 resposta

2

Se você chamar o binário em /etc/rc.local , observe que rc.local é chamado como /bin/sh -e . -e significa que o script sai imediatamente se algum comando não testado falhar nele. Você chama o binário em segundo plano e outro comando no script pode sair com um código de saída que não é 0. Isso faz com que seu binário seja suspenso.

Um comando não testado de acordo com a página do manual:

The exit status of a command is considered to be explicitly tested if the command is used to control an if, elif, while, or until; or if the command is the left hand operand of an “&&” or “||” operator.

$ command                   # untested
$ command || echo failed    # tested
$ if [ command ]; then...   # tested, also while and until loops
$ [ command ] && echo ...   # tested

Além disso, o arquivo rc.local é o lugar errado para tal coisa, você não deve mais usá-lo, está obsoleto. Em vez disso, você deve usar o mecanismo de configuração de inicialização do sistema. Desde que você usa o Debian, é o estilo SysV-init. Para fazer isso de maneira limpa, crie um script em /etc/init.d/ que aceite pelo menos start e stop como argumento para iniciar e parar seu binário / daemon / tarefa. Para começar, há um script esqueleto, que você pode usar como modelo em /etc/init.d/skeleton para escrever esse script.

    
por 17.04.2015 / 08:31