systemd Timer vs cron: Escolhendo o Agendador Certo

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

Proximas leituras