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: 06 de agosto de 2026
Durante décadas, o cron foi a ferramenta tradicional para executar tarefas automaticamente em horários determinados no Linux. Ele continua útil, simples e amplamente disponível, mas as distribuições modernas oferecem outra possibilidade: os timers do systemd. Com eles, uma tarefa agendada passa a ser administrada da mesma maneira que os demais serviços do sistema, com registros centralizados, dependências, controle de recursos, tratamento de falhas e comandos padronizados de gerenciamento.
Substituir uma entrada do cron por um timer exige a criação de duas unidades. A primeira descreve o serviço que será executado. A segunda determina quando esse serviço deverá ser acionado. Essa separação pode parecer mais trabalhosa no começo, porém torna a configuração mais legível, verificável e fácil de diagnosticar.
Uma entrada do cron é compacta e eficiente, mas nem sempre oferece informações suficientes quando algo dá errado. O ambiente disponível para o comando pode ser diferente daquele encontrado no terminal, mensagens de erro podem passar despercebidas e o computador pode estar desligado no momento programado.
Os timers do systemd oferecem algumas vantagens importantes:
journalctl;
O systemd não torna o cron obsoleto em todas as situações. Para tarefas simples, uma única linha no crontab pode continuar sendo a solução mais conveniente. Os timers tornam-se especialmente interessantes quando a tarefa precisa de registros detalhados, controle de falhas, dependências ou maior integração com o restante do sistema.
Um timer geralmente está associado a um serviço de mesmo nome. Considere os arquivos relatorio-disco.service e relatorio-disco.timer.
Quando o timer relatorio-disco.timer chega ao horário programado, o systemd procura e inicia automaticamente o serviço relatorio-disco.service.
O arquivo .service responde à pergunta: O que deverá ser executado?
O arquivo .timer responde: Quando deverá ser executado?
Essa divisão permite testar o serviço manualmente antes de ativar o agendamento.
Nosso exemplo executará o comando df -h todos os dias às 8 horas. A saída será guardada automaticamente no journal do systemd, dispensando a criação e o gerenciamento manual de um arquivo de log.
Crie o arquivo:
$ sudo systemctl edit --force --full relatorio-disco.service
Insira o seguinte conteúdo:
[Unit] Description=Gera um relatório sobre a utilização dos discos [Service] Type=oneshot ExecStart=/usr/bin/df -h
Salve o arquivo e feche o editor.
A opção Type=oneshot indica que o comando realiza uma tarefa e termina. Esse tipo é apropriado para backups, relatórios, atualizações, sincronizações e outras operações de curta duração.
É recomendável informar o caminho completo do programa em ExecStart. Podemos descobrir esse caminho com:
command -v df
Em muitas distribuições, o resultado será /usr/bin/df, mas vale a pena verificar.
Antes de criar o agendamento, execute o serviço manualmente:
$ sudo systemctl start relatorio-disco.service
Consulte seu estado:
$ systemctl status relatorio-disco.service
Como o serviço executa uma única tarefa e termina, é normal que seu estado seja exibido como inactive (dead) depois da conclusão. O importante é verificar se a execução foi concluída com sucesso.
Para consultar a saída produzida pelo comando:
$ journalctl -u relatorio-disco.service
Para mostrar somente os registros da execução mais recente:
$ journalctl -u relatorio-disco.service -n 20
Podemos ainda acompanhar uma execução em tempo real:
$ journalctl -fu relatorio-disco.service
Em outro terminal, execute:
$ sudo systemctl start relatorio-disco.service
Agora crie a unidade que determinará o horário:
$ sudo systemctl edit --force --full relatorio-disco.timer
Insira:
[Unit] Description=Executa diariamente o relatório de utilização dos discos [Timer] OnCalendar=*-*-* 08:00:00 Persistent=true [Install] WantedBy=timers.target
A expressão:
OnCalendar=*-*-* 08:00:00
significa que o serviço deverá ser executado todos os anos, em todos os meses e em todos os dias, às 8 horas.
A diretiva:
Persistent=true
faz com que o systemd verifique se alguma execução foi perdida enquanto o computador estava desligado. Se isso tiver ocorrido, o serviço será iniciado depois que o sistema voltar a funcionar.
Esse comportamento é particularmente útil em computadores pessoais. Se uma tarefa estiver programada para as 8 horas, mas o computador for ligado somente às 10 horas, ela ainda poderá ser executada. Em uma configuração convencional do cron, a execução normalmente seria simplesmente perdida.
Depois de criar ou alterar unidades, peça ao systemd que releia suas configurações:
$ sudo systemctl daemon-reload
Ative o timer e faça com que ele seja iniciado imediatamente:
$ sudo systemctl enable --now relatorio-disco.timer
Observe que ativamos o arquivo .timer, e não o .service. O serviço será iniciado automaticamente quando o timer chegar ao horário determinado.
Consulte o estado:
$ systemctl status relatorio-disco.timer
Para verificar todos os timers ativos:
$ systemctl list-timers
Para mostrar também os timers inativos:
$ systemctl list-timers --all
A listagem informa quando cada timer foi executado pela última vez e quando ocorrerá a próxima execução.
Expressões de calendário podem ser testadas com systemd-analyze calendar. Para verificar o horário utilizado no exemplo:
$ systemd-analyze calendar '*-*-* 08:00:00'
O comando apresenta a interpretação da expressão e a próxima ocorrência calculada.
Também é possível solicitar várias ocorrências futuras:
$ systemd-analyze calendar --iterations=5 '*-*-* 08:00:00'
Essa verificação ajuda a evitar erros de configuração, principalmente em expressões semanais ou mensais.
Uma tarefa diária às 8 horas seria representada no cron desta forma:
0 8 * * * /usr/bin/df -h
No timer, usamos:
OnCalendar=*-*-* 08:00:00
Algumas conversões comuns são mostradas a seguir:
| Frequência | Cron | systemd timer |
|---|---|---|
| Todos os dias às 8h | 0 8 * * * |
OnCalendar=*-*-* 08:00:00 |
| Todos os dias à meia-noite | 0 0 * * * |
OnCalendar=daily |
| A cada hora | 0 * * * * |
OnCalendar=hourly |
| Segunda-feira às 9h | 0 9 * * 1 |
OnCalendar=Mon *-*-* 09:00:00 |
| De segunda a sexta às 18h | 0 18 * * 1-5 |
OnCalendar=Mon..Fri *-*-* 18:00:00 |
| Primeiro dia do mês às 7h | 0 7 1 * * |
OnCalendar=*-*-01 07:00:00 |
| Domingos às 3h30 | 30 3 * * 0 |
OnCalendar=Sun *-*-* 03:30:00 |
| A cada 15 minutos | */15 * * * * |
OnCalendar=*:0/15 |
As palavras hourly, daily, weekly, monthly, quarterly, semiannually e yearly podem ser utilizadas como atalhos em várias configurações.
Antes de empregar qualquer expressão, teste-a:
$ systemd-analyze calendar 'Mon..Fri *-*-* 18:00:00'
Nem todo agendamento precisa estar ligado a um horário específico. Podemos executar uma tarefa determinado tempo depois da inicialização do computador:
[Timer] OnBootSec=10min
Nesse caso, o serviço será iniciado dez minutos depois do boot.
Também podemos criar uma execução periódica:
[Timer] OnBootSec=5min OnUnitActiveSec=1h
Essa configuração inicia a tarefa cinco minutos depois do boot e repete sua execução uma hora depois de cada ativação anterior.
Algumas diretivas importantes são:
| Diretiva | Significado |
|---|---|
OnBootSec= |
Tempo transcorrido desde a inicialização |
OnStartupSec= |
Tempo transcorrido desde o início do gerenciador systemd |
OnActiveSec= |
Tempo desde a ativação do próprio timer |
OnUnitActiveSec= |
Tempo desde a última ativação da unidade |
OnUnitInactiveSec= |
Tempo desde que a unidade ficou inativa |
OnCalendar= |
Horário definido pelo calendário |
As diretivas podem ser combinadas. Se mais de uma condição for especificada, o timer será acionado sempre que qualquer uma delas for satisfeita.
Em servidores, pode ser inconveniente que centenas de máquinas iniciem uma atualização ou sincronização exatamente no mesmo segundo. A diretiva RandomizedDelaySec adiciona um atraso aleatório:
[Timer] OnCalendar=hourly RandomizedDelaySec=10min
A tarefa será executada uma vez por hora, mas poderá sofrer um atraso aleatório de até dez minutos. Isso ajuda a distribuir a carga sobre servidores, repositórios e redes.
Para uma tarefa local que precise começar em um horário exato, essa diretiva pode ser omitida.
Serviços instalados em /etc/systemd/system são administrados pelo systemd do sistema e normalmente são executados como root. Quando a tarefa não precisa de privilégios administrativos, podemos indicar outro usuário:
[Service] Type=oneshot User=rubens Group=rubens ExecStart=/usr/local/bin/minha-tarefa
Também podemos definir o diretório de trabalho:
WorkingDirectory=/home/rubens
E variáveis de ambiente:
Environment="MODO=producao" Environment="IDIOMA=pt_BR"
Os nomes de usuário, diretórios e programas devem ser adaptados ao sistema utilizado.
Também é possível criar timers que pertencem ao próprio usuário. Nesse caso, não é necessário modificar /etc/systemd/system nem utilizar sudo.
Crie os arquivos dentro de ~/.config/systemd/user/
Por exemplo:
~/.config/systemd/user/relatorio-disco.service ~/.config/systemd/user/relatorio-disco.timer
Depois de salvá-los, execute:
$ systemctl --user daemon-reload systemctl --user enable --now relatorio-disco.timer
Para consultar os timers do usuário:
$ systemctl --user list-timers
E para examinar os registros:
$ journalctl --user -u relatorio-disco.service
Por padrão, os serviços do usuário normalmente funcionam enquanto sua sessão está ativa. Para permitir que permaneçam disponíveis sem uma sessão aberta, um administrador pode habilitar o chamado *linger*:
$ sudo loginctl enable-linger rubens
Esse recurso deve ser ativado apenas quando houver necessidade de manter serviços do usuário funcionando depois do logout.
Os principais comandos utilizados para administrar o timer são:
$ sudo systemctl start relatorio-disco.timer $ sudo systemctl stop relatorio-disco.timer $ sudo systemctl restart relatorio-disco.timer $ sudo systemctl enable relatorio-disco.timer $ sudo systemctl disable relatorio-disco.timer $ sudo systemctl enable --now relatorio-disco.timer
Para executar imediatamente a tarefa, sem esperar pelo timer:
$ sudo systemctl start relatorio-disco.service
Para verificar a configuração dos arquivos:
$ systemd-analyze verify /etc/systemd/system/relatorio-disco.service $ systemd-analyze verify /etc/systemd/system/relatorio-disco.timer
Para mostrar o conteúdo que o systemd efetivamente carregou:
$ systemctl cat relatorio-disco.service systemctl cat relatorio-disco.timer
Primeiro, desative e interrompa o timer:
$ sudo systemctl disable --now relatorio-disco.timer
Remova as duas unidades:
$ sudo rm /etc/systemd/system/relatorio-disco.timer $ sudo rm /etc/systemd/system/relatorio-disco.service
Finalmente, atualize o systemd:
$ sudo systemctl daemon-reload $ sudo systemctl reset-failed
Antes de remover qualquer arquivo, confirme os caminhos e os nomes das unidades com systemctl cat.
Consulte o timer:
$ systemctl status relatorio-disco.timer
Depois, examine o serviço:
$ systemctl status relatorio-disco.service $ journalctl -u relatorio-disco.service
O timer apenas determina quando a unidade será acionada. Os detalhes de uma falha estarão geralmente associados ao serviço.
Serviços systemd não recebem necessariamente o mesmo ambiente da sessão interativa. Utilize caminhos completos para programas e arquivos:
ExecStart=/usr/local/bin/meu-script
Defina explicitamente o diretório de trabalho e as variáveis necessárias.
Recarregue as unidades:
$ sudo systemctl daemon-reload
Depois, verifique o arquivo:
$ systemd-analyze verify /etc/systemd/system/relatorio-disco.timer
Para um serviço Type=oneshot, isso geralmente é normal. Ele executa a tarefa e termina. Consulte o código de saída e os registros para confirmar o resultado:
$ systemctl status relatorio-disco.service $ journalctl -u relatorio-disco.service
Não existe necessidade de converter imediatamente todas as entradas do crontab. O cron continua adequado para tarefas pequenas, estáveis e simples. Os timers do systemd são particularmente vantajosos quando queremos observar as execuções, guardar registros, aplicar limites, controlar dependências ou recuperar tarefas perdidas durante o desligamento da máquina.
A melhor forma de aprender é começar com uma tarefa pouco crítica, criar o serviço, testá-lo manualmente e somente depois ativar o timer. Essa ordem facilita o diagnóstico porque separa dois problemas diferentes: a execução da tarefa e seu agendamento.
Os timers representam uma abordagem moderna para uma necessidade antiga. Eles integram as tarefas periódicas ao sistema de gerenciamento de serviços do Linux e oferecem ao administrador ferramentas muito mais completas para saber o que foi executado, quando foi executado e por que uma operação eventualmente falhou.
A sintaxe completa das unidades e das expressões de calendário pode ser consultada nas páginas oficiais de systemd.timer e systemd.time.