Manual

do

Maker

.

com

Como criar serviço no Raspberry

Como criar serviço no Raspberry

Criar serviço no Raspberry

É o mesmo processo para sistemas Linux que utilizem o systemd, mas de qualquer modo, não é sabido por todos os makers e certamente em algum momento você quererá que um programa (seu ou do sistema) inicialize sozinho. Mas antes de mostrar como colocar um serviço no systemd, gostaria de falar do systemV, que foi o sistema utilizado para inicialização de serviço durante muitos, muitos anos antes mesmo do Linux existir.

Saudoso sysV

Antigamente (mas nem tanto) absolutamente todos os sistemas Linux utilizavam o tradicional sysV, onde os scripts de inicialização de serviços eram os que você encontra em /etc/init.d. A diferença do upstart é que o simples e saudoso sysV executava toda a inicialização em série, ou seja, conforme o número do serviço com link em /etc/rcX.d. Para efeito de exclarecimento, dentro desse diretório você tinha (e ainda tem, mas o funcionamento é diferente) os links simbólicos para os serviços do nível de execução.

Não era apenas um link simbólico qualquer, haveria de ser a ordem de inicialização e a ordem de finalização. A finalização deveria ser feita no runlevel 0 e no runlevel 6 (shutdown e reboot), ou em qualquer outro nível selecionado em que o serviço não devesse ser inicializado. O runlevel de manutenção era o runlevel 2 e o runlevel padrão gráfico era o 5. Atualmente, o runlevel padrão para Ubuntu, Mint e afins é o runlevel 2 (que pode ser observado através do comando "runlevel" em qualquer terminal), portanto os serviços desse runlevel ficam em /etc/rc2.d e suas finalizações em /etc/rc0.d e /etc/rc6.d.

Para fazer o serviço em /etc/init.d utilizando o sysV o formato deve ser algo como:

#! /bin/sh
### BEGIN INIT INFO
# Provides:          scriptOuPrograma
# Required-Start:    $all
# Required-Stop:     seForOcasoDeAlgumFinalizarPrimeiro  
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: executa meu programa
### END INIT INFO


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

. /lib/init/vars.sh
. /lib/lsb/init-functions

do_start() {
        echo "executou em $(date)" >/tmp/meuScript
}

case "$1" in
    start)
        do_start
        ;;
    restart|reload|force-reload)
        echo "nao tem restart"
        ;;
    stop)
        echo "nao tem stop"
        ;;
    *)
        echo "Usage: $0 start|stop" >&2
        exit 3
        ;;
esac

Após escrito, o script deve ficar alocado em /etc/init.d. Dá-se permissão de execução:

chmod 0750 /etc/init.d/seuScriptDoSystemV

E inclui-se ele na inicialização. Antigamente existia o ntsysv para incluir o serviço através de um menu em ncurses. Para esse script em sistemas que ainda funcionem assim, você pode utilizar o update-rc.d:

update-rc.d seuScriptDeInicializacao defaults

Criar serviço utilizando o systemd

Bem, alguns dias antes desse post tive que incluir um serviço no Raspbian e por um acaso não funcionou utilizando o método descrito anteriormente, porque agora ele utiliza o systemd. Para criar um serviço com o systemd é simples e tem lá suas vantagens.

O systemd tem algumas características peculiares. Ele não desprende do script que chama, portanto deve-se criar o script A para chamar o script B. Suponhamos scriptCaller.sh e script.sh.

Pid do script.sh

O processo necessita ter um arquivo de pid para que possa ser controlado. O lugar ideal é /var/run, mas por falta de permissão como usuário comum, você pode preparar previamente um diretório com permissão de escrita:

sudo mkdir /var/run/script
chown usuario.grupo /var/run/script
chmod 0770 /var/run/script
scriptCaller.sh
#!/bin/sh
./etc/init.d/script.sh &
echo $$ > /var/run/script/script.pid

O script será o programa principal, que faz o que desejar. Monte-o como o exemplo do systemV lá em cima. Por fim, configuramos o systemd para gerenciar o script. Vou mostrar o exemplo real que utilizei no Raspberry Pi:

[Unit]
Documentation=man:systemd-sysv-generator(8)
Description=LSB: USCA Manager
Before=runlevel3.target runlevel5.target shutdown.target 
After=network-online.target remote-fs.target network-online.target
Wants=network-online.target
Conflicts=shutdown.target

[Service]
Type=forking
TimeoutSec=5min
KillMode=process
PIDFile=/var/run/usca/uscaMonitor.pid
GuessMainPID=no
ExecStart=/root/root/manager.py

[Install]
WantedBy=multi-user.target

A linha "Description=LSB" apenas faz uma descrição do processo.

A linha "Before=" indica os níveis de execução previos e "After" indica após quais processos inicializados ele deve ser executado.

A linha "Wants" imputa a obrigação de inicialização prévia da rede e "Conflicts", hum...

Na sessão "[Service]" estão as características padrão da inicialização, onde indica-se principalmente o pid e o script ou programa a executar. Por fim, o modo de instalação do serviço.

Habilitar o serviço

Acabaram-se as configurações, agora basta habilitar o serviço com 2 comandos:

#recarrega o daemon
systemctl daemon-reload
#ativa o serviço
systemct enable scriptCaller.sh

O processo é bastante interessante e realmente trouxe vantagens sobre o sysV. E mesmo que não trouxesse, não resta outra opção que não seja se adaptar, afinal, o sistema continuará a evoluir, inclusive em sua estrutura. Além disso, o systemd tem outros recursos, leia o manual se tiver interesse, esse artigo apenas auxilia a por rapidamente um script para inicializar em seu sistema, mas você pode obter outras vantagens estudando um pouco mais.

Inscreva-se no nosso canal Manual do Maker Brasil no YouTube.

Nome do Autor

Djames Suhanko

Autor do blog "Do bit Ao Byte / Manual do Maker".

Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.