systemd Timer vs cron: Escolhendo o Agendador Certo
Qual voce deve usar?
Use systemd timer como padrao para novas cargas de trabalho. Os logs se integram com journalctl, dependencias entre servicos podem ser aplicadas, e execucoes perdidas sao capturadas na proxima inicializacao. Mantenha o cron ao manter tarefas existentes ou quando um agendamento de uma linha e tudo que voce precisa.
Tabela de Decisao Rapida
| Cenario | Recomendado |
|---|---|
| Nova tarefa periodica | systemd timer |
| Logs centralizados via journalctl | systemd timer |
| Depende de outro servico | systemd timer |
| Gatilho relativo a inicializacao | systemd timer |
| Mantendo tarefas cron existentes | Manter cron |
| Uma linha simples em um agendamento | cron |
O que e cron?
cron e o agendador de tarefas tradicional do UNIX. Uma unica linha no crontab define quando e o que executar, usando cinco campos: minuto, hora, dia-do-mes, mes e dia-da-semana.
Sintaxe do crontab
min hora dom mes dsm comando
# Todo dia as 3:00 da manha 0 3 * * * /home/user/scripts/backup.sh # A cada 5 minutos */5 * * * * /usr/local/bin/collect-logs.sh # Toda segunda-feira as 9:00 da manha 0 9 * * 1 /usr/local/bin/send-report.sh
Comandos do crontab
# Abrir o editor para o usuario atual crontab -e # Listar tarefas atuais crontab -l # Remover todas as tarefas (use com cautela) crontab -r
cron envia a saida por email para o usuario local por padrao. Em ambientes sem um daemon de email, a saida acumula em /var/spool/mail. Adicione MAILTO="" no topo do seu crontab para suprimir isso.
O que e systemd timer?
Um systemd timer consiste em dois arquivos de unidade: um arquivo .timer (o agendamento) e um arquivo .service (o comando a executar). Ambos sao gerenciados pelo systemd, entao logs, dependencias e verificacoes de status passam pela mesma interface.
Exemplo Minimo: Executar a Cada 5 Minutos
/etc/systemd/system/collect-logs.service
[Unit]
Description=Collect system logs
[Service]
Type=oneshot
ExecStart=/usr/local/bin/collect-logs.sh
/etc/systemd/system/collect-logs.timer
[Unit]
Description=Run collect-logs every 5 minutes
[Timer]
OnCalendar=*:0/5
Persistent=true
[Install]
WantedBy=timers.target
Habilitando e Monitorando um Timer
# Recarregar arquivos de unidade apos qualquer alteracao sudo systemctl daemon-reload # Habilitar e iniciar o timer imediatamente sudo systemctl enable --now collect-logs.timer # Listar todos os timers ativos com proximos horarios de execucao systemctl list-timers # Verificar logs de execucao journalctl -u collect-logs.service
Por que o systemd Timer e melhor?
As duas vantagens principais sobre o cron sao logging centralizado e controle granular.
Logs vao para o journalctl
# Ultimas 50 entradas de log journalctl -u collect-logs.service -n 50 # Logs apenas de hoje journalctl -u collect-logs.service --since today # Apenas erros journalctl -u collect-logs.service -p err
A saida do cron vai para email ou um arquivo separado. A saida do systemd timer vai para o journal junto com todos os outros eventos do sistema, tornando a investigacao de incidentes muito mais rapida.
Dependencias de Servicos
[Unit]
Description=Database backup
Requires=postgresql.service
After=postgresql.service
A tarefa so executa se o PostgreSQL estiver ativo. O cron nao tem mecanismo equivalente - voce precisaria verificar dentro do script.
Gatilhos Relativos a Inicializacao
[Timer]
# 10 minutos apos a inicializacao
OnBootSec=10min
# Depois a cada hora
OnUnitActiveSec=1h
systemd timer suporta tanto agendamentos baseados em calendario (OnCalendar) quanto relativos (OnBootSec/OnUnitActiveSec). O cron nao suporta nenhum dos dois.
Capturando Execucoes Perdidas com Persistent=true
[Timer]
OnCalendar=daily
Persistent=true
Se a maquina estiver desligada no horario agendado, a tarefa executa na proxima inicializacao em vez de ser ignorada silenciosamente. O cron nao faz isso sem o anacron.
Como escrever OnCalendar?
OnCalendar usa o formato de timestamp proprio do systemd. Sempre valide com systemd-analyze calendar antes de habilitar um novo timer.
# Validar um agendamento e mostrar os proximos horarios de disparo systemd-analyze calendar "Mon *-*-* 03:00:00" # Padroes comuns OnCalendar=daily # 00:00 todo dia OnCalendar=hourly # 00:00 toda hora OnCalendar=weekly # Seg 00:00 toda semana OnCalendar=*:0/5 # a cada 5 minutos OnCalendar=Mon 03:00 # Seg 03:00 toda semana OnCalendar=*-*-* 03:00:00 # todo dia as 03:00 (mesmo que acima)
Execute systemd-analyze calendar antes de habilitar qualquer novo timer. Ele imprime os proximos dois horarios agendados, capturando erros de digitacao antes que causem falhas silenciosas.
Como migrar do cron para o systemd Timer?
Passo 1: Revisar tarefas existentes
crontab -l # 0 3 * * * /home/user/scripts/backup.sh
Passo 2: Criar o arquivo de servico
sudo nano /etc/systemd/system/backup.service
[Unit]
Description=Daily backup
[Service]
Type=oneshot
User=user
ExecStart=/home/user/scripts/backup.sh
Passo 3: Criar o arquivo de timer
sudo nano /etc/systemd/system/backup.timer
[Unit]
Description=Run backup daily at 3:00 AM
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
[Install]
WantedBy=timers.target
Passo 4: Habilitar e verificar
sudo systemctl daemon-reload sudo systemctl enable --now backup.timer # Confirmar que o timer esta registrado systemctl list-timers --all | grep backup # Verificar logs apos a primeira execucao journalctl -u backup.service --since today
Passo 5: Remover a tarefa do cron
crontab -e # Delete or comment out the migrated line
Confirme que o timer esta funcionando via systemctl list-timers e journalctl -u backup.service antes de remover a tarefa original do cron. Deixar ambos ativos causa execucao dupla.
Resumo da comparacao
| Recurso | cron | systemd timer |
|---|---|---|
| Complexidade de setup | Uma linha | Dois arquivos de unidade |
| Logging | Email ou arquivo | journalctl |
| Dependencias de servicos | Nao | Sim |
| Gatilho relativo a boot | Nao | Sim (OnBootSec) |
| Capturar exec. perdidas | Nao (precisa anacron) | Sim (Persistent=true) |
| Tarefas por usuario | crontab por usuario | Unidades de servico do usuario |
| Comando de inspecao | crontab -l |
systemctl list-timers |