Rodar um script no boot usando systemd

Publicado por Adalberto Mendes em 30/09/2012

[ Hits: 15.612 ]

 


Rodar um script no boot usando systemd



As distribuições GNU/Linux começaram a substituir o SysVinit pelo systemd, com a promessa de fazer o boot ser mais rápido e eficiente. Mas o systemd dificulta um pouco a tarefa de rodar alguns serviços na inicialização do sistema.

Estes dias, precisei instalar um firewall novo, baixei o Fedora 17 e fiz o de sempre, instalei o básico e fui colocando apenas os serviços necessários para a tarefa.

Logo percebi que o ntsysv não conseguia executar meu script no boot e nem o /etc/rc.local, existia mais...

A solução foi estudar um pouco o systemd, então, descobri o seguinte:

Meu arquivo com as regras de IPtables para ser iniciado no boot, fica em /etc/ini.d/firewall, e antigamente, iniciava ele colocando no /etc/rc.local a linha: . /etc/init.d/firewall start

No systemd, os arquivos de controle ficam em /etc/systemd/system, logo criei um arquivo:

# vi /etc/systemd/system/firewall.service

Com o seguinte conteúdo:

[Unit]
Description=Firewall

[Service]
Type=forking
ExecStart=/etc/init.d/firewall start
ExecStop=/etc/init.d/firewall start

[Install]
WantedBy=multi-user.target


Dei um:

# shutdown -r now

E funcionou... Melhor, às vezes funcionava e às vezes não...

Um dos objetivos do systemd é fazer o sistema inciar mais rápido, para isso, os diversos processos do S.O. não são iniciados um a um, mas em paralelo.

Em meu script, existe uma linha verificando se a placa de rede está ativa, se não estiver, ele aborta o processo, o que às vezes acontecia se houvesse qualquer atraso no DHCP.

A solução mais prática que encontrei, foi criar um atraso no script do firewall acrescentando a linha sleep 20, isto é, ele inicia a execução, mas pára nessa linha por 20 segundos, tempo suficiente para que o systemd levante as placas de rede.

Acredito que tenha outras soluções para o problema, mas de momento, é o que está funcionando...

Quem quiser saber mais sobre o sysmted:

Outras dicas deste autor
Nenhuma dica encontrada.
Leitura recomendada

Jogar saída de microfone local para host remoto

Timeout para terminais

Exibir notificações quando um comando é concluído (Ubuntu 18.04.1)

Tempo que o processo está aberto (uptime)

MultiTail - Comando tail em múltiplos arquivos no Linux

  

Comentários
[1] Comentário enviado por andersongg em 24/06/2014 - 10:07h

Saberia informar se ele rodaria um script em bash, adicionando-o na pasta "/etc/systemd/system", ou se daria para adicionar o comando que quero rodar nesse tipo de script que roda no systemd?

[2] Comentário enviado por mrpotato em 19/08/2014 - 16:13h

Para o script rodar no momento desejado tem que adicionar na seção [Unit] a configuração "After="
ex.: After=bar.service

Referencia:
http://www.freedesktop.org/software/systemd/man/systemd.unit.html

[3] Comentário enviado por ojidos em 15/04/2015 - 18:05h

Olá amigo,

Estou precisando colocar apenas um comando na inicialização antes que o serviço do hostapd.service inicie.

comando é : iw dev wlp4s0 set 4addr0 on

Preciso colocar esse comando para que minha interface de rede sem fio (wlp4s0) possa entrar na minha bridge (brctl)

Como ficaria?

Agradeço se puder ajudar.

Abraço.

[4] Comentário enviado por willnux em 12/07/2016 - 19:52h

Para o script ser executado com o systemd quando você quiser, (..parece bobagem, mas é isso rs) você tem que dar permissão de execução para o script:
$ sudo chmod +x /path do script/firewall

A permissão do script (firewall) deixe assim:
-rwxr-xr-x

...e do service (firewall.service) assim:
-rw-r--r--.

Lembrando que o "firewall.service" deve ser inicializado após o inicio de conexão com internet, então na Unit, coloque o After para isso:
After=network.target

Espero ter ajudo. :)

-------------------------------------
"Enjoy your life with Linux."
-------------------------------------

[5] Comentário enviado por lmaciel em 18/10/2017 - 17:54h

cara preciso fazer um script para compartilhar a internet, poderia me ajudar por esse seu esquema como fazer no debian 9

[6] Comentário enviado por frankallan em 16/10/2018 - 18:24h

Para garantir que o comando apenas suba após as interfaces de rede serem levantadas, basta acrescentar "After=network.target" no Unit. Ex:

[Unit]
Description=Firewall
After=network.target



Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts