Cron e agendamento de tarefas: crontab, anacron e systemd timers
1. Introdução ao agendamento de tarefas no Linux
O agendamento de tarefas é um dos pilares da administração de sistemas Linux. Ele permite automatizar processos repetitivos sem intervenção manual, garantindo que backups, rotações de log, atualizações e outros jobs críticos sejam executados no momento certo. As tarefas podem ser recorrentes (executadas em intervalos fixos) ou únicas (executadas uma única vez em data/hora específica).
Historicamente, o cron clássico surgiu no Unix System V e foi amplamente adotado. O Vixie cron tornou-se o padrão no Linux por décadas. Para sistemas que não ficam ligados 24 horas por dia, surgiu o anacron, que executa tarefas perdidas assim que o sistema é religado. Mais recentemente, o systemd trouxe os timers, uma alternativa integrada e mais flexível que substitui o cron em muitas distribuições modernas.
Cenários comuns incluem: backup noturno de bancos de dados, rotação semanal de logs do Apache, atualização automática de pacotes de segurança e limpeza de arquivos temporários.
2. Cron e crontab: o clássico agendador
O cron é um daemon que lê arquivos de configuração chamados crontabs e executa comandos nos horários especificados. A sintaxe clássica de um crontab é composta por cinco campos de tempo, seguidos pelo comando:
minuto hora dia mês dia_semana comando
- minuto: 0-59
- hora: 0-23
- dia: 1-31
- mês: 1-12
- dia_semana: 0-7 (0 e 7 = domingo)
Exemplo prático: executar um script de backup todos os dias às 2h30 da manhã:
30 2 * * * /usr/local/bin/backup.sh
Para gerenciar crontabs do usuário atual, use:
crontab -e # editar crontab
crontab -l # listar tarefas
crontab -r # remover crontab
Arquivos globais ficam em /etc/crontab e /etc/cron.d/. Exemplo de /etc/crontab:
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=admin@exemplo.com
# Executar às 3h15 de segunda a sexta
15 3 * * 1-5 root /usr/sbin/logrotate
Variáveis de ambiente como MAILTO (para onde enviar erros) e PATH (caminho de busca) são essenciais. Redirecione saída para logs:
0 4 * * * /opt/scripts/cleanup.sh >> /var/log/cleanup.log 2>&1
3. Anacron: agendamento para sistemas que não ficam ligados 24/7
O anacron resolve um problema clássico do cron: se o sistema estiver desligado no horário agendado, a tarefa simplesmente não executa. O anacron armazena o timestamp da última execução e, ao ser iniciado, verifica se há jobs pendentes. Se sim, executa-os com um atraso configurável.
A configuração fica em /etc/anacrontab. A sintaxe é:
período atraso identificador comando
- período: em dias (1 = diário, 7 = semanal, 30 = mensal)
- atraso: minutos de espera antes de executar (evita sobrecarga na inicialização)
- identificador: nome único para o job (usado em logs)
- comando: o que executar
Exemplo típico:
# formato: período atraso identificador comando
1 5 cron.daily run-parts /etc/cron.daily
7 10 cron.weekly run-parts /etc/cron.weekly
30 15 cron.monthly run-parts /etc/cron.monthly
O anacron é ideal para desktops e notebooks que são ligados e desligados com frequência, garantindo que tarefas diárias sejam executadas mesmo após dias de inatividade.
4. Systemd timers: a alternativa moderna e integrada
Os systemd timers são unidades do systemd que disparam serviços em momentos específicos. Cada timer requer um arquivo .timer e um arquivo .service correspondente. Eles oferecem maior controle, dependências entre unidades e logs centralizados via journald.
Estrutura básica de um timer (/etc/systemd/system/backup.timer):
[Unit]
Description=Timer de backup diário
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
O serviço correspondente (/etc/systemd/system/backup.service):
[Unit]
Description=Executa backup do sistema
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
Expressões de calendário permitem alta flexibilidade:
OnCalendar=Mon..Fri 02:00:00 # Seg a Sex às 2h
OnCalendar=*-*-* 00,12:00:00 # A cada 12 horas
OnCalendar=*-01-01 00:00:00 # Todo ano novo
Outros gatilhos úteis:
OnBootSec=5min # 5 minutos após a inicialização
OnUnitActiveSec=1h # 1 hora após a última ativação do serviço
Gerenciamento com systemctl:
systemctl enable backup.timer # ativar na inicialização
systemctl start backup.timer # iniciar imediatamente
systemctl list-timers # listar todos os timers ativos
systemctl status backup.timer # verificar status
5. Comparação prática entre cron, anacron e systemd timers
| Característica | Cron | Anacron | Systemd Timer |
|---|---|---|---|
| Precisão | Segundos | Minutos | Segundos |
| Execução perdida | Ignora | Recupera | Com Persistent=true |
| Dependências | Nativas | Nativas | Completas (via systemd) |
| Logs | /var/log/cron | /var/log/cron | journalctl |
| Complexidade | Baixa | Baixa | Média |
Casos de uso recomendados:
- Cron: tarefas simples e previsíveis em servidores 24/7 (ex: backup noturno, rotação de logs).
- Anacron: máquinas com uptime intermitente (ex: notebook pessoal, desktop em casa).
- Systemd timers: serviços complexos que exigem dependências, containers ou monitoramento avançado.
Exemplo de migração de cron para systemd timer:
Crontab original:
0 3 * * * /usr/bin/docker-compose -f /opt/app/docker-compose.yml down && /usr/bin/docker-compose -f /opt/app/docker-compose.yml up -d
Timer equivalente (/etc/systemd/system/app-restart.timer):
[Unit]
Description=Reinicia aplicação diariamente às 3h
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
[Install]
WantedBy=timers.target
Serviço (/etc/systemd/system/app-restart.service):
[Unit]
Description=Reinicia containers Docker da aplicação
Requires=docker.service
After=docker.service
[Service]
Type=oneshot
ExecStart=/usr/bin/docker-compose -f /opt/app/docker-compose.yml down
ExecStart=/usr/bin/docker-compose -f /opt/app/docker-compose.yml up -d
6. Boas práticas e resolução de problemas comuns
Verificação de logs:
- Cron:
tail -f /var/log/cronougrep CRON /var/log/syslog - Systemd:
journalctl -u backup.timeroujournalctl -u backup.service
Segurança:
- Nunca edite crontabs de outros usuários sem permissão
- Prefira executar tarefas com usuários não-root sempre que possível
- Use variáveis de ambiente com cuidado; evite expor senhas em comandos
Tratamento de falhas:
Para evitar execuções sobrepostas, use flock no cron:
*/5 * * * * /usr/bin/flock -n /tmp/meu_job.lock /usr/local/bin/meu_script.sh
No systemd, use LockPersonality=true ou crie arquivos de lock manualmente no serviço.
Notificações de falha podem ser configuradas com MAILTO no cron ou OnFailure=email-notify@localhost no systemd (com serviço de e-mail configurado).
7. Considerações finais e dicas avançadas
Em ambientes com containers, o cron pode ser executado dentro do próprio container ou via timer do host. O systemd-run permite criar timers temporários sem arquivos:
systemd-run --on-calendar='*-*-* 00:00:00' /usr/bin/meu_script.sh
Para tarefas únicas, o comando at ainda é útil:
echo "/usr/bin/reboot" | at 23:59 today
Dica avançada: combine systemd timers com systemd-analyze verify para validar a sintaxe antes de ativar:
systemd-analyze verify /etc/systemd/system/backup.timer
A escolha entre cron, anacron e systemd timers depende do seu cenário: servidores estáveis se beneficiam da simplicidade do cron; máquinas intermitentes precisam do anacron; e serviços modernos ganham com a integração e flexibilidade dos timers do systemd.
Referências
- man 5 crontab — Documentação oficial da sintaxe do crontab, incluindo todos os campos e variáveis de ambiente.
- man 8 anacron — Página de manual do anacron com detalhes sobre configuração e funcionamento.
- man 5 systemd.timer — Especificação completa dos arquivos .timer do systemd, incluindo expressões OnCalendar.
- Arch Linux Wiki: systemd/Timers — Guia prático e comparativo entre cron e systemd timers, com exemplos avançados.
- Red Hat: Using systemd as a better cron — Artigo técnico da Red Hat sobre migração de cron para systemd timers, com casos de uso reais.
- Debian Wiki: Cron — Documentação oficial do Debian sobre configuração e gerenciamento do cron.
- FreeBSD Handbook: Cron — Referência histórica sobre o cron no FreeBSD, útil para entender a origem e variações.