Como continuar um script depois que ele reinicializar a máquina?

16

Estou escrevendo um script de shell no bash. Em algum ponto do script, ele detecta que a máquina precisa ser reinicializada antes de continuar. Emite:

sudo reboot

Quando a máquina volta a funcionar, há mais trabalho que esse script precisa fazer. Como faço para configurar algo para continuar fazendo o trabalho neste script?

Estou assumindo que há algum lugar em que posso escrever um script de shell de forma que ele seja executado na próxima reinicialização. Onde é esse lugar? Eu vejo que o cron tem uma diretiva @reboot. Eu também sei que serviços como o Apache são iniciados no boot por upstart. Algum deles seria um mecanismo apropriado? Se sim, como isso seria desencadeado?

Este script só precisa ser executado uma vez, não a cada reinicialização. Por isso, terá que ir a algum lugar que apenas seja executado na próxima reinicialização ou ser capaz de ser removido assim que for executado.

Esta pergunta pergunta sobre como salvar seu aplicativo Estado para após a reinicialização. Meu script não tem muito estado, então eu posso gerenciar isso. Eu só preciso saber como fazer com que esse script acione algo para ser executado após a próxima reinicialização.

Minha versão específica é o Ubuntu Linux 14.04. O script original é iniciado na linha de comando por um administrador do sistema (em oposição à execução do cron).

    
por Stephen Ostermiller 18.07.2014 / 15:22

1 resposta

15

Em um sistema, a única coisa que é realmente persistente é um arquivo. Isso é muito bonito o que você deve usar. Aqui está uma solução usando um script init.d.

Vamos considerar o seguinte script (simples), /etc/init.d/myupdate :

#! /bin/sh

### BEGIN INIT INFO
# Provides:          myupdate
### END INIT INFO

PATH=/sbin:/bin:/usr/sbin:/usr/bin

case "$1" in
    start)
        /path/to/update/script
        ;;
    stop|restart|reload)
        ;;
esac

Se você ativá-lo com update-rc.d myupdate defaults , a ação start será executada na inicialização. Agora, quando seu script de atualização pede uma reinicialização:

touch /var/run/rebooting-for-updates
sudo reboot

Com esta solução, você pode dividir seu script de atualização em duas partes:

before_reboot(){
    # Do stuff
}

after_reboot(){
    # Do stuff
}

if [ -f /var/run/rebooting-for-updates ]; then
    after_reboot
    rm /var/run/rebooting-for-updates
    update-rc.d myupdate remove
else
    before_reboot
    touch /var/run/rebooting-for-updates
    update-rc.d myupdate defaults
    sudo reboot
fi

Ele executará a seção before_reboot code, criará um arquivo em /var/run e reinicializará. Na inicialização, o script será chamado novamente, mas como o arquivo existe, after_reboot será chamado em vez de before_reboot .

Observe que update-rc.d requer privilégios de root.

Sem usar um arquivo (de comentário de Stephen Ostermiller ):

Se você estiver familiarizado com o utilitário getopts , convém usar opções em vez de arquivos. No script de inicialização, chame o script com:

/path/to/update/script -r

E no seu script, verifique as opções em vez de arquivos. Chame seu script uma vez sem a opção, e o init.d o chamará novamente na inicialização, desta vez com -r .

# Set AFTER_REBOOT according to options (-r).

if [ "x$AFTER_REBOOT" = "xyes" ]; then
    # After reboot
else
    # Before reboot
fi

Você encontrará mais informações sobre a opção aqui (apenas para opções curtas) . Também editei meu script com chamadas para update-rc.d para manter esse trabalho único (de outro comentário).

    
por 18.07.2014 / 15:42