Crontab no Linux: como agendar tarefas automaticamente

Backup que devia rodar todo dia às 3h da manhã, mas só roda quando alguém lembra de executar o script na mão. Log que cresce sem rotação até derrubar o disco. Certificado que vence porque ninguém automatizou a renovação. Todo esses problemas têm a mesma causa: tarefa que deveria ser automática continua dependendo de humano lembrar. O crontab existe desde os primeiros Unix justamente pra isso — e a maioria dos sysadmins usa só uma fração do que ele oferece.
O que é o cron e pra que ele serve
O cron é um daemon que roda em segundo plano em praticamente toda distribuição Linux e fica checando, minuto a minuto, se algum agendamento bate com o horário atual. O crontab ("cron table") é o arquivo de texto onde você lista esses agendamentos — um por linha, cada um dizendo quando rodar e o que rodar. Não precisa instalar nada: cron e crontab já vêm em Debian, Ubuntu, RHEL, Alpine e praticamente qualquer imagem de servidor.
Pra editar o crontab do usuário atual:
crontab -ePra listar o que já está agendado (faça isso antes de qualquer mudança — adivinhar o que está rodando é como as coisas quebram de madrugada):
crontab -lA sintaxe dos 5 campos
Toda linha do crontab segue o mesmo formato: cinco campos de tempo, depois o comando.
# ┌───────────── minuto (0-59)
# │ ┌───────────── hora (0-23)
# │ │ ┌───────────── dia do mês (1-31)
# │ │ │ ┌───────────── mês (1-12)
# │ │ │ │ ┌───────────── dia da semana (0-6, 0 = domingo)
# │ │ │ │ │
* * * * * comando-a-executarQuatro caracteres especiais cobrem 90% dos casos:
- Asterisco (
*): "qualquer valor".* * * * *roda todo minuto. - Barra (
/): define intervalo.*/15no campo de minuto roda a cada 15 minutos. - Vírgula (
,): lista de valores.1,15no campo de dia roda no dia 1 e no dia 15. - Hífen (
-): intervalo.1-5no campo de dia da semana cobre segunda a sexta.
Como rodar um script todo dia às 3h da manhã?
Use 0 3 * * * seguido do caminho completo do script. O zero no campo de minuto e o 3 no campo de hora travam o horário; os três asteriscos restantes dizem "todo dia, todo mês, qualquer dia da semana".
0 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1Exemplos práticos pra colar e adaptar
# Backup diário às 3h, log de saída e erro no mesmo arquivo
0 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
# Limpeza de log a cada domingo às 4h
0 4 * * 0 find /var/log/app -name "*.log" -mtime +30 -delete
# Renovação de certificado Let's Encrypt, duas vezes por dia (recomendação oficial)
0 0,12 * * * certbot renew --quiet
# Sincronização a cada 15 minutos, só em dias de semana
*/15 * * * 1-5 /usr/local/bin/sync-dados.sh
# Reiniciar um serviço todo primeiro dia do mês à meia-noite
0 0 1 * * systemctl restart app-staleTambém existem atalhos pra não escrever os 5 campos na mão: @reboot (uma vez, no boot do sistema), @daily (equivale a 0 0 * * *), @weekly, @monthly e @hourly. São úteis pra agendamentos óbvios onde a legibilidade importa mais que a precisão.
Os 3 erros que mais quebram cron job em produção
Funciona perfeito quando você testa rodando o script direto no terminal, e falha silenciosamente quando o cron dispara. Quase sempre é um destes três problemas:
- PATH incompleto: o cron roda com um ambiente mínimo, sem o
PATHdo seu shell interativo. Script que chamapython,nodeouawssem caminho completo falha com "comando não encontrado". Solução: use caminho absoluto (/usr/bin/python3) ou definaPATH=no topo do crontab. - Sem redirecionamento de saída: por padrão o cron tenta mandar stdout/stderr por e-mail local — que na maioria dos servidores não está configurado, então a saída simplesmente desaparece. Sempre redirecione com
>> arquivo.log 2>&1pra ter rastro do que aconteceu. - Variáveis de ambiente do shell não carregam:
.bashrc,.profilee variáveis exportadas na sessão interativa não existem no ambiente do cron. Se o script depende de uma variável, exporte-a explicitamente dentro do próprio script ou no crontab.
Quando trocar crontab por systemd timer
Crontab ou systemd timer: qual usar?
Pra agendamento simples em qualquer Linux, cron continua suficiente. Pra jobs críticos que precisam de log centralizado, dependências entre serviços ou recuperação de execução perdida, systemd timer é a opção mais robusta nas distros que já rodam systemd (Ubuntu, Debian, RHEL, Fedora).
O systemd timer separa o agendamento em dois arquivos: uma unit .service (o que rodar) e uma unit .timer (quando rodar). Exemplo equivalente ao backup das 3h:
# /etc/systemd/system/backup.service
[Unit]
Description=Backup diário
[Service]
ExecStart=/usr/local/bin/backup.sh
# /etc/systemd/system/backup.timer
[Unit]
Description=Agenda do backup diário
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
[Install]
WantedBy=timers.targetsudo systemctl enable --now backup.timerA vantagem prática do Persistent=true: se o servidor estava desligado às 3h, o timer dispara o job assim que o systemd volta a rodar — coisa que o cron tradicional não faz. Os logs também ficam centralizados no journal (journalctl -u backup.service), sem depender de redirecionamento manual. Em troca, dá mais trabalho pra escrever (dois arquivos em vez de uma linha) — por isso cron ainda vence em scripts pontuais e ambientes mais simples.
Segurança: cron como root é poder de root
Job agendado em crontab -e dentro de uma sessão root, ou colocado direto em /etc/cron.d/, executa com privilégio total — sem prompt de senha, sem log de quem rodou o comando manualmente. É um vetor clássico de persistência depois de um comprometimento inicial: um atacante com acesso de escrita em qualquer diretório de cron consegue rodar código periodicamente sem precisar manter uma sessão aberta. Se você já aplicou as mudanças de hardening de SSH no servidor, vale o mesmo cuidado aqui: audite crontab -l como root periodicamente, restrinja quem pode editar cron via /etc/cron.allow, e nunca rode como root um job que poderia rodar com um usuário de serviço dedicado.
O equivalente no mundo Windows é o Task Scheduler, e o princípio de auditoria é o mesmo: se você administra ambiente misto, o post sobre como auditar logs de segurança no Windows com PowerShell cobre a outra ponta dessa rotina. E se o seu ambiente Windows ainda depende de Windows PowerShell 5.1 pra rodar esses scripts agendados, já documentamos o que muda na migração pro PowerShell 7.6 LTS.
Cron não é glamouroso, mas é provavelmente a ferramenta que mais silenciosamente sustenta infraestrutura em produção — backup, rotação de log, renovação de certificado, sincronização de dados. Audite o que está rodando no seu servidor agora com crontab -l e ls /etc/cron.d/: se encontrar algo que ninguém lembra de ter agendado, essa é a hora de investigar antes de assumir que é só uma tarefa esquecida.




Comentários