De acordo com as Leis 12.965/2014 e 13.709/2018, que regulam o uso da Internet e o tratamento de dados pessoais no Brasil, ao me inscrever na newsletter do portal DICAS-L, autorizo o envio de notificações por e-mail ou outros meios e declaro estar ciente e concordar com seus Termos de Uso e Política de Privacidade.
Colaboração: Rubens Queiroz de Almeida
Data de Publicação: 10 de outubro de 2026
Em muitas distribuições Linux, o systemd é o primeiro processo iniciado pelo kernel. Ele recebe o identificador de processo 1, organiza a inicialização do sistema e administra serviços, dispositivos, pontos de montagem, temporizadores e outros recursos.
Quando instalamos programas como Apache, Nginx, PostgreSQL ou SSH, normalmente encontramos serviços que podem ser controlados com comandos como:
$ sudo systemctl start nginx $ sudo systemctl stop nginx $ sudo systemctl restart nginx
Também podemos criar nossos próprios serviços. Isso é útil para iniciar automaticamente um programa, manter uma aplicação em segundo plano, reiniciá-la em caso de falha e centralizar suas mensagens no journal do sistema.
Neste tutorial criaremos um serviço simples que executará continuamente um script e registrará uma mensagem a cada 30 segundos.
O systemd trabalha com objetos chamados unidades. Cada unidade é descrita por um arquivo de configuração cuja extensão identifica sua finalidade.
Alguns tipos comuns são:
| Extensão | Finalidade |
|---|---|
.service |
Executar e administrar um serviço |
.socket |
Representar um socket de comunicação |
.timer |
Programar a execução de uma unidade |
.mount |
Administrar um ponto de montagem |
.path |
Monitorar arquivos ou diretórios |
.target |
Agrupar unidades e representar estados do sistema |
Neste artigo trabalharemos com uma unidade do tipo service.
Os serviços criados pelo administrador normalmente são armazenados em /etc/systemd/system/.
Os arquivos fornecidos pelos pacotes da distribuição costumam ficar abaixo de /usr/lib/systemd/system/ ou /lib/systemd/system/, dependendo da distribuição. Como /etc/systemd/system/ possui prioridade administrativa, é o local apropriado para nossos próprios serviços e personalizações.
Nosso primeiro serviço executará um pequeno script chamado meu-servico.sh. Ele escreverá uma mensagem com a data e a hora e aguardará 30 segundos antes de repetir a operação.
Crie o arquivo:
$ sudo nano /usr/local/bin/meu-servico.sh'''
Insira o seguinte conteúdo:
#!/bin/sh
while true
do
echo "Meu serviço está ativo: $(date)"
sleep 30
done
Salve o arquivo e torne-o executável:
$ sudo chmod 755 /usr/local/bin/meu-servico.sh
Antes de criar o serviço, execute o script manualmente:
$ /usr/local/bin/meu-servico.sh
Uma nova mensagem deverá aparecer a cada 30 segundos:
Meu serviço está ativo: Thu Oct 8 20:45:00 -03 2026
Meu serviço está ativo: Thu Oct 8 20:45:30 -03 2026
Pressione Ctrl+C para interromper o teste.
Executar o programa manualmente antes de colocá-lo sob o controle do systemd é uma boa prática. Dessa forma, podemos separar problemas existentes no programa daqueles causados pela configuração do serviço.
É possível executar o script como root, mas ele não precisa de privilégios administrativos. Criaremos um usuário de sistema exclusivo:
$ sudo useradd \
--system \
--no-create-home \
--shell /usr/sbin/nologin \
meu-servico
Esse usuário não terá um diretório pessoal nem poderá iniciar uma sessão interativa. Sua única finalidade será executar nosso serviço.
Confirme sua criação:
$ getent passwd meu-servico
Em algumas distribuições, o comando equivalente para criar uma conta de sistema pode ser diferente. O importante é que o usuário exista antes que o serviço seja iniciado.
Agora criaremos a unidade:
$ sudo nano /etc/systemd/system/meu-servico.service
Insira:
[Unit] Description=Meu primeiro serviço systemd After=network.target [Service] Type=simple ExecStart=/usr/local/bin/meu-servico.sh User=meu-servico Group=meu-servico Restart=on-failure RestartSec=5s [Install] WantedBy=multi-user.target
O arquivo está dividido em três seções: [Unit], [Service] e [Install].
A seção [Unit] contém informações gerais e relacionamentos com outras unidades:
[Unit] Description=Meu primeiro serviço systemd After=network.target
A diretiva Description apresenta uma descrição legível do serviço. Ela aparecerá em comandos como:
$ systemctl status meu-servico
A diretiva
After=network.target
define uma relação de ordem. Ela informa que nosso serviço deverá ser iniciado depois que o alvo network.target for alcançado.
Isso não significa necessariamente que a conexão com a Internet estará disponível. Para um programa que realmente dependa da rede completamente configurada, poderá ser necessário utilizar network-online.target e também garantir que o gerenciador de rede ofereça o serviço de espera correspondente.
Nosso script não depende da rede. A diretiva foi incluída apenas para demonstrar como a ordem de inicialização pode ser declarada e poderia ser removida neste exemplo.
A seção [Service] descreve como o programa será executado:
[Service] Type=simple ExecStart=/usr/local/bin/meu-servico.sh User=meu-servico Group=meu-servico Restart=on-failure RestartSec=5s
A configuração:
Type=simple
indica que o processo iniciado por ExecStart será o processo principal do serviço. Esse é o tipo padrão quando Type e determinadas formas especiais de ativação não são declarados.
A linha mais importante é:
ExecStart=/usr/local/bin/meu-servico.sh
Ela informa o programa que o systemd deverá executar. É recomendável utilizar um caminho absoluto e evitar depender de recursos específicos de um shell interativo.
As diretivas:
User=meu-servico Group=meu-servico
determinam a conta utilizada para executar o processo. Se elas fossem omitidas em um serviço do sistema, o processo seria iniciado como root.
A configuração:
Restart=on-failure
faz com que o serviço seja reiniciado quando o processo terminar devido a uma falha. Um encerramento normal não provocará a reinicialização.
O intervalo antes de uma nova tentativa será de cinco segundos:
RestartSec=5s
Usar on-failure costuma ser uma escolha adequada para serviços de longa duração, pois recupera o processo após uma falha sem reiniciá-lo quando ele é encerrado normalmente por decisão do administrador.
A última seção determina como a unidade será ligada à inicialização do sistema:
[Install] WantedBy=multi-user.target
O multi-user.target representa um sistema preparado para executar vários serviços e sessões de usuários, normalmente sem depender de uma interface gráfica.
A diretiva WantedBy é utilizada pelo comando systemctl enable. Ela faz com que sejam criados os vínculos necessários para incluir o serviço na inicialização associada ao alvo indicado. Habilitar um serviço e iniciá-lo são operações diferentes.
Antes de iniciar o serviço, podemos procurar erros no arquivo da unidade:
$ sudo systemd-analyze verify \
/etc/systemd/system/meu-servico.service
Se nenhum problema for encontrado, o comando poderá não apresentar mensagem alguma.
O verify consegue detectar diretivas desconhecidas, dependências ausentes e alguns erros relacionados aos comandos configurados. Ainda assim, ele não substitui o teste real do serviço.
Depois de criar ou modificar uma unidade, precisamos solicitar que o systemd releia os arquivos:
$ sudo systemctl daemon-reload
Esse comando recarrega a configuração do gerenciador. Ele não inicia nem reinicia automaticamente nosso serviço.
Agora podemos iniciá-lo:
$ sudo systemctl start meu-servico.service
A extensão pode ser omitida:
$ sudo systemctl start meu-servico
Consulte o estado:
$ systemctl status meu-servico
A saída deverá ser semelhante a:
meu-servico.service - Meu primeiro serviço systemd
Loaded: loaded
Active: active (running)
Main PID: 12345
A indicação:
active (running)
mostra que o processo está em execução.
Também podemos fazer uma verificação adequada para scripts:
$ systemctl is-active meu-servico
Se estiver funcionando, a resposta será active.
Para verificar se ele está habilitado para a inicialização:
$ systemctl is-enabled meu-servico
Como ainda apenas iniciamos o serviço, a resposta provavelmente será disabled.
Nosso script escreve suas mensagens na saída padrão. Por padrão, a saída dos serviços é integrada ao journal, o sistema de registros do systemd.
Para consultar as mensagens do serviço:
$ sudo journalctl --unit=meu-servico
A opção pode ser abreviada:
$ sudo journalctl -u meu-servico
Para mostrar apenas as mensagens da inicialização atual:
$ sudo journalctl -u meu-servico -b
Para acompanhar novas mensagens em tempo real:
$ sudo journalctl -u meu-servico -f
Pressione Ctrl+C para encerrar o acompanhamento. Isso interrompe apenas o journalctl; o serviço continuará funcionando.
Também podemos limitar a quantidade de linhas:
$ sudo journalctl -u meu-servico -n 20
Uma vantagem dessa integração é que o programa não precisa criar e administrar seu próprio arquivo de log. Cada linha escrita em sua saída poderá ser associada à unidade correspondente.
Para fazer com que o serviço seja iniciado automaticamente:
$ sudo systemctl enable meu-servico
Esse comando habilita a unidade, mas não é necessário aguardar a próxima reinicialização para colocá-la em funcionamento. Podemos habilitar e iniciar em uma única operação:
$ sudo systemctl enable --now meu-servico
Como o serviço já está em execução, o --now apenas garante que ele continue ativo.
Confirme:
$ systemctl is-enabled meu-servico $ systemctl is-active meu-servico
As respostas esperadas são:
enabled active
A administração cotidiana pode ser feita com os seguintes comandos:
$ sudo systemctl start meu-servico $ sudo systemctl stop meu-servico $ sudo systemctl restart meu-servico
Para interromper o serviço:
$ sudo systemctl stop meu-servico
Confira:
$ systemctl status meu-servico
O serviço deverá aparecer como inativo.
Inicie-o novamente:
$ sudo systemctl start meu-servico
O comando restart interrompe e inicia novamente o serviço:
$ sudo systemctl restart meu-servico
Ele é particularmente útil depois de modificarmos o programa executado.
Suponha que mudemos o intervalo de reinicialização:
RestartSec=10s
Depois de salvar o arquivo, será necessário executar:
$ sudo systemctl daemon-reload $ sudo systemctl restart meu-servico
O primeiro comando faz o systemd reler a definição da unidade. O segundo reinicia o processo para que a nova configuração seja aplicada.
Podemos examinar exatamente qual arquivo está sendo usado:
$ systemctl cat meu-servico
E consultar propriedades calculadas pelo systemd:
$ systemctl show meu-servico
Para mostrar apenas algumas propriedades:
$ systemctl show meu-servico \
--property=User,Group,MainPID,ActiveState,SubState
Nosso serviço possui:
Restart=on-failure
Para observar esse comportamento, descubra o identificador do processo principal:
$ systemctl show meu-servico --property=MainPID
A saída será semelhante a:
MainPID=12345
Encerre abruptamente esse processo, substituindo o número pelo PID apresentado em seu sistema:
$ sudo kill -KILL 12345
Depois de alguns segundos, consulte novamente:
$ systemctl status meu-servico
O serviço deverá estar em execução com outro PID. O journal mostrará o encerramento e a tentativa de recuperação:
$ sudo journalctl -u meu-servico -n 30
Esse teste demonstra que o systemd não é apenas um mecanismo de inicialização. Ele também acompanha o processo e pode tomar providências quando ocorre uma falha.
Um erro comum é criar um script que funciona no terminal, mas falha quando executado como serviço. Isso acontece porque um serviço não recebe necessariamente o mesmo ambiente da sessão interativa.
Ele poderá ter diferenças em itens como:
PATH;
Se o programa precisar de um diretório específico, declare-o explicitamente:
WorkingDirectory=/diretorio/da/aplicacao
Se precisar de uma variável de ambiente:
Environment="MODO=producao"
Também podemos usar um arquivo externo:
EnvironmentFile=/etc/meu-servico.conf
Senhas e outros segredos exigem cuidados adicionais. Um arquivo referenciado por EnvironmentFile não deve ser considerado automaticamente um cofre seguro apenas porque está fora da unidade.
O systemd oferece diversas diretivas que podem reduzir o acesso concedido ao serviço. Em nosso exemplo simples, podemos acrescentar:
[Service] NoNewPrivileges=yes PrivateTmp=yes ProtectSystem=strict ProtectHome=yes
| Diretiva | Função |
|---|---|
NoNewPrivileges=yes |
impede que o processo e seus descendentes obtenham novos privilégios por meio de mecanismos como executáveis setuid. |
PrivateTmp=yes |
fornece ao serviço uma visão privada dos diretórios temporários. |
ProtectSystem=strict |
torna grande parte do sistema de arquivos disponível apenas para leitura dentro do ambiente do serviço. |
ProtectHome=yes |
impede o acesso normal aos diretórios pessoais. |
Essas opções precisam ser escolhidas de acordo com a aplicação. Um programa que precise gravar em determinado local poderá deixar de funcionar se suas permissões forem restringidas indiscriminadamente.
Uma forma de examinar a exposição de segurança da unidade é:
$ systemd-analyze security meu-servico
A análise apresenta recomendações, mas a pontuação não deve ser interpretada isoladamente. A configuração adequada depende da função real do serviço.
Execute:
$ sudo systemctl daemon-reload $ sudo systemctl restart meu-servico
O daemon-reload atualiza a definição conhecida pelo systemd, enquanto o restart recria o processo.
Consulte o estado completo:
$ systemctl status meu-servico --no-pager --full
Depois, examine o journal:
$ sudo journalctl -u meu-servico -b --no-pager
Verifique também o arquivo da unidade:
$ sudo systemd-analyze verify \
/etc/systemd/system/meu-servico.service
Use caminhos absolutos em ExecStart e confirme sua localização:
$ command -v nome-do-programa
Também verifique se o arquivo existe e possui permissão de execução:
$ ls -l /usr/local/bin/meu-servico.sh
Confirme qual usuário executa o serviço:
$ systemctl show meu-servico --property=User,Group
Depois, examine as permissões do programa e dos diretórios acessados por ele:
$ namei -l /usr/local/bin/meu-servico.sh
O usuário precisa conseguir atravessar os diretórios do caminho e executar o arquivo. Se o programa gravar dados, também precisará de permissão no diretório correspondente.
Verifique se ele está habilitado:
$ systemctl is-enabled meu-servico
Examine os registros da inicialização atual:
$ sudo journalctl -u meu-servico -b
Se o programa depender de rede, discos ou outros serviços, reveja as dependências e a ordem declaradas na seção [Unit].
Consulte:
$ systemctl status meu-servico $ sudo journalctl -u meu-servico -n 50
Depois de várias falhas em pouco tempo, o systemd poderá limitar novas tentativas. Após corrigir o problema, limpe o estado de falha:
$ sudo systemctl reset-failed meu-servico $ sudo systemctl start meu-servico
Para impedir a inicialização automática e interromper o serviço imediatamente:
$ sudo systemctl disable --now meu-servico
Confirme:
$ systemctl is-enabled meu-servico $ systemctl is-active meu-servico
Para removê-lo definitivamente, apague o arquivo da unidade e o script:
$ sudo rm /etc/systemd/system/meu-servico.service $ sudo rm /usr/local/bin/meu-servico.sh
Depois, atualize o systemd:
$ sudo systemctl daemon-reload $ sudo systemctl reset-failed
Se o usuário de sistema não for mais necessário:
$ sudo userdel meu-servico
Antes de remover arquivos ou usuários de um serviço real, verifique se eles não estão sendo utilizados por outras unidades ou aplicações.
| Objetivo | Comando |
|---|---|
| Recarregar as unidades | sudo systemctl daemon-reload |
| Iniciar o serviço | sudo systemctl start meu-servico |
| Parar o serviço | sudo systemctl stop meu-servico |
| Reiniciar o serviço | sudo systemctl restart meu-servico |
| Ver o estado | systemctl status meu-servico |
| Consultar os registros | sudo journalctl -u meu-servico |
| Acompanhar os registros | sudo journalctl -u meu-servico -f |
| Habilitar na inicialização | sudo systemctl enable meu-servico |
| Habilitar e iniciar | sudo systemctl enable --now meu-servico |
| Desabilitar e parar | sudo systemctl disable --now meu-servico |
| Ver o arquivo carregado | systemctl cat meu-servico |
| Validar a unidade | sudo systemd-analyze verify ARQUIVO |
| Analisar a segurança | systemd-analyze security meu-servico |
| Limpar o estado de falha | sudo systemctl reset-failed meu-servico |
Criar um serviço systemd consiste em preparar o programa que será executado, escrever um arquivo de unidade e informar ao systemd quando e em quais condições o processo deverá funcionar.
Neste primeiro exemplo, criamos um script contínuo, configuramos um usuário exclusivo, registramos uma unidade em /etc/systemd/system/, iniciamos o processo, consultamos suas mensagens e habilitamos sua execução durante a inicialização do Linux.
A partir dessa estrutura, podemos administrar servidores web, aplicações próprias, agentes de monitoramento, scripts de automação e diversos outros programas. O systemd oferece um ponto central para iniciar, interromper, acompanhar e proteger esses processos.
O próximo passo pode ser substituir o script de demonstração por uma aplicação real ou aprender a criar uma unidade .timer, capaz de executar tarefas programadas sem depender diretamente do cron.