Aprenda a agendar tarefas no Linux com crontab e com systemd timers: sintaxe, exemplos, logs, flock e como escolher a melhor opção para cada caso.

Para que serve

Backups, limpeza de arquivos temporários, renovação de certificados e relatórios precisam rodar sozinhos, em horários definidos. Para agendar tarefas no Linux, há duas formas principais: o cron, clássico e simples, e os timers do systemd, que trazem log integrado, execução de tarefas perdidas e controle de recursos. Este artigo mostra as duas e quando usar cada uma.

Pré-requisitos

  • Acesso root ou a um usuário com sudo.
  • O script que você quer agendar já testado manualmente.
  • Fuso horário do servidor correto (timedatectl); o agendamento segue o horário do sistema.

Opção 1: cron

1. Editar o crontab

Se o comando crontab não existir, instale com apt install cron. Para editar as tarefas do usuário atual:

crontab -e

Cada linha tem cinco campos de tempo seguidos do comando:

# min  hora  dia-mês  mês  dia-semana  comando
  30   2     *        *    *           /usr/local/bin/backup.sh
  */15 *     *        *    *           /usr/local/bin/verifica-site.sh
  0    6     *        *    1-5         /usr/local/bin/relatorio.sh

Leitura: backup todo dia às 02:30; verificação a cada 15 minutos; relatório às 06:00 de segunda a sexta (0 ou 7 é domingo). Também existem atalhos como @daily, @weekly e @reboot.

2. Cuidados que evitam 90% dos problemas

  • Ambiente reduzido: o cron roda com um PATH mínimo. Use caminhos completos para comandos e arquivos, ou defina no topo do crontab:
    PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
  • Guarde a saída: sem redirecionamento, a saída é enviada por e-mail local e normalmente se perde. Redirecione para um log:
    30 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
  • Evite execuções sobrepostas: se a tarefa pode demorar mais que o intervalo, use o flock:
    */15 * * * * flock -n /run/lock/verifica.lock /usr/local/bin/verifica-site.sh
  • O caractere % tem significado especial no crontab (quebra de linha). Escape como \%, por exemplo em date +\%F.

3. Tarefas do sistema

Para tarefas instaladas por você como administrador, prefira um arquivo em /etc/cron.d/. Nesse formato existe um campo extra com o usuário que executa:

# /etc/cron.d/backup
30 2 * * * root /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

O nome do arquivo não pode ter ponto, e o arquivo deve terminar com uma linha em branco.

Opção 2: systemd timers

Um timer é composto de dois arquivos: um .service, que diz o que rodar, e um .timer, que diz quando.

1. Criar o serviço

# /etc/systemd/system/backup.service
[Unit]
Description=Backup diário

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
Nice=10
IOSchedulingClass=idle

2. Criar o timer

# /etc/systemd/system/backup.timer
[Unit]
Description=Agenda o backup diário

[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true
RandomizedDelaySec=10min

[Install]
WantedBy=timers.target
  • OnCalendar aceita expressões como daily, Mon..Fri 06:00 ou *:0/15 (a cada 15 minutos).
  • Persistent=true faz a tarefa rodar assim que o servidor ligar, se ela foi perdida enquanto ele estava desligado.
  • RandomizedDelaySec espalha o início, útil quando vários servidores enviam backup para o mesmo destino.

Valide a expressão antes de ativar:

systemd-analyze calendar "Mon..Fri 06:00"

3. Ativar

systemctl daemon-reload
systemctl enable --now backup.timer

Ative o timer, não o serviço. Para rodar a tarefa na hora, como teste: systemctl start backup.service.

Cron ou systemd timer: qual usar para agendar tarefas no Linux?

SituaçãoRecomendação
Tarefa simples, uma linhacron
Precisa de log centralizado e status da última execuçãosystemd timer
Servidor pode estar desligado no horáriosystemd timer com Persistent=true
Quer limitar CPU, memória ou E/S da tarefasystemd timer (CPUQuota=, MemoryMax=)

Como saber se funcionou

  • cron: crontab -l lista as tarefas; as execuções aparecem em journalctl -u cron --since today. Confira também o log que você definiu.
  • timer: systemctl list-timers mostra a próxima e a última execução; o resultado fica em journalctl -u backup.service e systemctl status backup.service.

Problemas comuns

  • Funciona no terminal, mas não no cron: quase sempre é PATH ou variável de ambiente ausente. Use caminhos completos e teste com env -i /bin/sh -c '/usr/local/bin/backup.sh'.
  • Rodou no horário errado: confira o fuso com timedatectl. Depois de trocar o fuso, reinicie o cron (systemctl restart cron).
  • Script sem permissão: chmod +x no script e confirme a primeira linha (#!/bin/bash).
  • Timer não aparece em list-timers: faltou daemon-reload ou enable no arquivo .timer.

Se a tarefa agendada for um backup, veja também o artigo «Backup com restic: como enviar backups criptografados para Backblaze B2, Wasabi ou Amazon S3». Para receber aviso quando algo falhar, veja «Como receber alertas do servidor no Telegram, e-mail ou WhatsApp».

Perguntas frequentes

Como ver as tarefas agendadas no cron?

Rode crontab -l para o usuário atual e crontab -l -u usuario para outro usuário. As tarefas do sistema ficam em /etc/crontab e em /etc/cron.d/; os timers aparecem em systemctl list-timers.

Como agendar uma tarefa a cada 5 minutos?

No cron, use */5 * * * * /caminho/do/script.sh. Em um timer do systemd, use OnCalendar=*:0/5.

Por que o script funciona no terminal, mas não no cron?

O cron roda com um ambiente mínimo, sem o seu PATH e suas variáveis. Use caminhos completos no script e redirecione a saída para um log para ver o erro.

O cron executa a tarefa perdida se o servidor estava desligado?

Não. Se isso for importante, use um timer do systemd com Persistent=true, que roda a tarefa assim que o servidor volta.

Leitura complementar

Precisa de ajuda?

Se uma tarefa agendada não executa e você não encontra o motivo nos logs, abra um ticket com o conteúdo do agendamento e a saída de journalctl correspondente.

Esta resposta lhe foi útil? 0 Usuários acharam útil (0 Votos)

Leia também