Numa distro moderna, use um timer do systemd para qualquer coisa que você administra e guarde o cron para jobs de uma linha e servidores que você mesmo não configurou. Timers logam cada execução no journal, podem recuperar agendamentos perdidos com a máquina desligada e dependem dos mesmos unit files que todo o resto do sistema. O cron vence na brevidade — uma linha de crontab -e ganha de dois unit files — e ainda é o único agendador com presença garantida em containers mínimos e máquinas Unix exóticas. A pegadinha: o cron falha em silêncio. Se seu job erra às 3 da manhã, o cron manda um e-mail para uma caixa local que ninguém lê, enquanto o timer te dá journalctl -u mytimer.service com o output completo. Abaixo: as diferenças reais, como testar cada um, por que um timer pode não disparar e uma tabela de decisão.
Qual é a diferença entre cron e um timer do systemd?
O cron é um daemon que lê uma tabela de linhas — cinco campos de tempo e um comando — e roda cada comando quando o relógio bate. Esse é o modelo inteiro. Ele não tem conceito de job como objeto: sem unidade, sem status, sem dependências, sem log próprio.
Um timer do systemd é um unit file (foo.timer) que dispara outro unit file (foo.service) quando o agendamento bate. O job é um objeto de primeira classe, com start, status, logs e rastreio de falha como qualquer serviço. O agendamento é por calendário (estilo cron) ou monotônico (OnBootSec=15min, que mudanças de relógio não confundem).
As consequências práticas:
- Logging: timers logam stdout/stderr no journal por unidade; o cron, no máximo, manda e-mail para o usuário local.
- Execuções perdidas: um timer com
Persistent=trueroda uma vez no boot se perdeu o horário; o cron simplesmente pula. - Dependências: timers podem esperar
network-online.targetou pontos de montagem; o cron exige retry caseiro no script. - Sintaxe: cron é uma linha; timer são dois arquivos. Esse é todo o custo da troca.
Qual sintaxe de agendamento é mais fácil — crontab ou OnCalendar?
Os cinco campos do cron são o incumbente compacto: */15 * * * * é a cada 15 minutos, e a maioria dos admins lê isso dormindo. O OnCalendar= do systemd é mais verboso, mas estritamente mais expressivo, e o systemd-analyze calendar te diz as próximas execuções antes de você salvar — o cron não tem dry-run equivalente.
# Cron: todo dia às 03:30
30 3 * * * /usr/local/bin/backup.sh
# systemd: o mesmo agendamento, verificável antes de salvar
systemd-analyze calendar "*-*-* 03:30:00"
# -> Next elapse: Fri 2026-09-11 03:30:00 ... O OnCalendar expressa coisas que o cron genuinamente não sabe escrever limpo: Mon..Fri *-*-* 09..17:00:00 (dias úteis, horário comercial), ou *:0/15 com RandomizedDelaySec=10m para impedir mil máquinas de martelarem um servidor no mesmo instante.
Como testar um timer do systemd sem esperar?
Três comandos respondem tudo. Liste o que está agendado e quando dispara de novo, rode o job na mão exatamente como o timer faria, depois leia os logs:
systemctl list-timers --all # todos os timers, próxima + última execução
sudo systemctl start backup.service # dispara o job agora, a mesma unidade que o timer
journalctl -u backup.service -f # acompanhe o output ao vivo Note a separação: systemctl start backup.timer arma o agendamento; o serviço é o job. Se o list-timers mostra seu timer, o systemctl status backup.service está verde e o journal mostra seu output, a cadeia inteira funciona.
Como rodar um job do cron manualmente?
Jobs do cron rodam com um ambiente esvaziado, e é por isso que “funciona no meu shell, falha no cron” é um gênero de bug. Para reproduzir o cron com fé, rode o comando via sh com o mesmo ambiente que o cron usaria:
crontab -l # confirme a linha exata
env -i SHELL=/bin/sh PATH=/usr/bin:/bin sh -c '/usr/local/bin/backup.sh'
grep CRON /var/log/syslog | tail # será que o cron disparou? (Debian/Ubuntu)
journalctl -u cron -n 20 # o mesmo, em distros systemd Aquela linha do env -i é o teste manual honesto: um ambiente nu com o PATH default do cron. A maioria das falhas silenciosas do cron é um PATH nu ou um % sem aspas no comando (o cron trata % como newline), e ambos aparecem na hora desse jeito.
Por que meu timer do systemd não dispara?
Quatro causas cobrem quase todo caso, na ordem de verificação:
- Nomes do serviço e do timer não batem.
foo.timerdisparafoo.service— umOnFailureerrado na digitação ou uma unidade renomeada faz o timer “rodar” para o nada.systemctl cat foo.timermostra exatamente o que ele mira. - O timer foi editado mas não recarregado. Depois de mudar um unit file:
sudo systemctl daemon-reload && sudo systemctl restart foo.timer. Sem isso, seu novo agendamento não está vivo. Persistent=truesem a semântica deOnCalendarque você espera — ou você está olhando osystemctl status foo.timer(sempre mostra active, mesmo ocioso) em vez dolist-timers.- O serviço que ele dispara está falhando instantaneamente, então o timer parece morto.
journalctl -u foo.service --since -1hmostra o crash que olist-timersesconde.
E quando for olhar os logs, o journalctl cheat sheet cobre os filtros (-u, --since, -f) que tornam isso rápido.
Cron vs timers do systemd: a tabela de decisão
| cron | timer do systemd | |
|---|---|---|
| Setup | uma linha de crontab | dois unit files |
| Logging | e-mail local, geralmente não lido | journal, por unidade |
| Execução perdida (máquina off) | pulada | roda uma vez com Persistent=true |
| Dependências / ordenação | nenhuma — DIY no script | dependências completas de unidade |
| Atraso aleatório | DIY com $RANDOM | RandomizedDelaySec= |
| Testar/dry-run do agendamento | não | systemd-analyze calendar |
| Existe em todo lugar | sim — containers, BSDs, embedded | precisa de systemd (PID 1) |
| Jobs de usuário sem root | crontab -e | unidades systemd --user |
Regras de bolso: entregar um job na sua própria máquina com systemd → timer. Lembrete pessoal rápido ou uma máquina que você não montou → cron. Qualquer coisa com dependências, retries ou necessidade de saber se rodou de fato → timer, sempre. Um padrão comum é um timer rodando um job de manutenção — digamos, um backup com rsync noturno — em que Persistent=true garante que o backup acontece mesmo se a máquina estava dormindo no minuto agendado, coisa que o cron simplesmente não oferece.
— mrsaynothing
Get the next one by email
One email per post. No spam, no algorithms.
what is this?llama.cpp vs Ollama: qual rodar em 2026?
Gostou dos artigos? É assim que eu construo profissionalmente. me contrate