O cron é um utilitário clássico do Linux que permite agendar a execução automática de comandos ou scripts em intervalos regulares. Ele é essencial para tarefas de manutenção, backups, monitoramento e automação em geral. Nesta aula, você aprenderá a configurar, testar e depurar agendamentos usando o crontab, além de entender como o ambiente é configurado e como os logs podem ajudar a acompanhar a execução.

O cron é um daemon que roda em segundo plano e verifica a cada minuto se há tarefas agendadas para executar. A configuração é feita em arquivos chamados crontab, que podem ser específicos de cada usuário ou do sistema. Vamos explorar a sintaxe, as variáveis de ambiente e as práticas recomendadas para criar agendamentos robustos.

crontab

O comando crontab é usado para criar, editar, listar e remover os agendamentos de um usuário. Cada usuário pode ter seu próprio crontab, e o sistema também possui crontabs globais em /etc/crontab e nos diretórios /etc/cron.d, /etc/cron.hourly, etc. Para editar o crontab do usuário atual, usa-se crontab -e, que abre o arquivo no editor padrão (definido pela variável EDITOR).

Para listar as tarefas agendadas, use crontab -l; para remover todas, use crontab -r. Ao editar, é importante lembrar que o cron não valida a sintaxe completamente; erros podem levar a tarefas que nunca executam ou que geram erros silenciosos. Portanto, é recomendável testar os comandos manualmente antes de agendá-los.

# Editar crontab do usuário atual
crontab -e

# Listar tarefas agendadas
crontab -l

# Remover todas as tarefas
crontab -r

Exemplo de um crontab simples:

# Executa o script de backup todos os dias às 2h da manhã
0 2 * * * /home/user/backup.sh

# Executa um comando a cada hora, no minuto 30
30 * * * * /usr/bin/df -h > /tmp/disk_usage.log

Sintaxe de agendamento

A sintaxe de uma linha no crontab é composta por cinco campos de tempo seguidos do comando a ser executado. Os campos são: minuto (0-59), hora (0-23), dia do mês (1-31), mês (1-12 ou nomes abreviados como jan, feb), e dia da semana (0-7, onde 0 e 7 representam domingo, ou nomes como sun, mon). O comando pode ser qualquer comando do shell, e é importante usar caminhos absolutos para evitar problemas com o PATH.

Além dos valores simples, é possível usar listas (ex.: 1,15,30), intervalos (ex.: 1-5), e passos (ex.: */5 para a cada 5 unidades). Também é possível combinar esses elementos, como */15 para a cada 15 minutos. O asterisco (*) significa "qualquer valor".

# Executa a cada minuto
* * * * * comando

# Executa a cada 5 minutos
*/5 * * * * comando

# Executa às 8h, 12h e 18h de segunda a sexta
0 8,12,18 * * 1-5 comando

# Executa no dia 1 de cada mês às 3h
0 3 1 * * comando

# Executa no último dia do mês (usando uma técnica com date)
0 0 28-31 * * [ "$(date -d tomorrow +%d)" = "01" ] && comando

É importante notar que o cron não interpreta variáveis de ambiente como $HOME ou $PATH da mesma forma que um shell interativo. Por isso, é comum definir variáveis no próprio crontab ou usar caminhos absolutos. Além disso, o cron envia a saída do comando por e-mail para o usuário, a menos que seja redirecionada para um arquivo ou para /dev/null.

Variáveis de ambiente em cron

O ambiente em que os comandos são executados pelo cron é muito limitado. Variáveis como PATH, HOME e SHELL são definidas com valores padrão que podem não incluir diretórios como /usr/local/bin. Para evitar erros, é recomendável definir explicitamente as variáveis necessárias no crontab. Você pode definir variáveis no início do arquivo crontab, antes das linhas de agendamento, no formato NOME=valor.

Por exemplo, se seu script usa um comando que está em /usr/local/bin, você pode adicionar PATH=/usr/local/bin:/usr/bin:/bin ao crontab. Também é possível definir a SHELL para o shell desejado (padrão é /bin/sh). Outra prática comum é colocar MAILTO= para desativar o envio de e-mails ou definir um endereço para receber as saídas.

# Define o PATH e o SHELL
PATH=/usr/local/bin:/usr/bin:/bin
SHELL=/bin/bash
MAILTO=admin@example.com

# Agendamento que usa um comando fora do PATH padrão
0 3 * * * /usr/local/bin/meuscript.sh

Além disso, se o seu script depende de outras variáveis de ambiente, você pode exportá-las no próprio script ou defini-las no crontab. Lembre-se de que o cron não carrega os arquivos de perfil do usuário, como ~/.bashrc ou ~/.profile. Portanto, qualquer configuração feita nesses arquivos não estará disponível nas tarefas agendadas.

Logs

Acompanhar os logs é fundamental para verificar se as tarefas agendadas estão executando corretamente. O cron registra eventos no syslog, geralmente em /var/log/syslog ou /var/log/cron, dependendo da distribuição. Você pode usar o comando grep para filtrar as entradas relacionadas ao cron. Por exemplo, grep CRON /var/log/syslog mostra as linhas de execução.

Além do log do sistema, é recomendável redirecionar a saída dos seus scripts para arquivos de log específicos. Isso permite que você monitore a execução sem depender do e-mail ou do syslog. Use >> para anexar ao arquivo e 2>&1 para incluir erros. Por exemplo: 0 2 * * * /home/user/backup.sh >> /var/log/backup.log 2>&1.

# Ver logs do cron no syslog
grep CRON /var/log/syslog

# Exemplo de redirecionamento em crontab
0 * * * * /usr/bin/df -h >> /var/log/disk_usage.log 2>&1

Outra ferramenta útil é o journalctl em sistemas que usam systemd: journalctl -u cron ou journalctl _COMM=cron. Esses logs mostram quando cada tarefa foi iniciada e se houve erros. Lembre-se de que o cron também envia e-mails com a saída dos comandos, a menos que você redirecione ou desative com MAILTO=.

Boas práticas

  • Use caminhos absolutos para comandos e scripts, evitando problemas com PATH.
  • Redirecione a saída para arquivos de log para facilitar a depuração.
  • Teste manualmente os comandos antes de agendá-los.
  • Defina variáveis de ambiente no crontab, se necessário.
  • Evite agendar tarefas com sobreposição se não forem idempotentes; use locks ou verifique se a tarefa anterior terminou.
  • Use nomes descritivos nos arquivos de log e nos próprios scripts.

Exercícios

  1. Qual comando é usado para editar o crontab do usuário atual? Explique a diferença entre crontab -e, -l e -r.

    ✓ Resposta: O comando é crontab -e para editar, crontab -l para listar e crontab -r para remover todas as tarefas. -e abre o arquivo no editor padrão, -l imprime as tarefas atuais na saída padrão, e -r remove o crontab do usuário.
  2. Escreva uma linha de crontab que execute o script /home/user/backup.sh todos os dias às 3h30 da manhã, redirecionando a saída para /var/log/backup.log.

    ✓ Resposta:
    30 3 * * * /home/user/backup.sh >> /var/log/backup.log 2>&1
  3. Explique o que significa a seguinte linha: */15 9-18 * * 1-5 /usr/bin/meu_comando.

    ✓ Resposta: Executa /usr/bin/meu_comando a cada 15 minutos, entre as 9h e 18h (inclusive), de segunda a sexta-feira (dias 1 a 5).
  4. Por que é importante definir variáveis de ambiente como PATH no crontab? Dê um exemplo de como fazer isso.

    ✓ Resposta: O cron usa um ambiente mínimo, com PATH padrão que pode não incluir diretórios como /usr/local/bin. Se um comando não for encontrado, a tarefa falhará. Para definir, adicione no início do crontab: PATH=/usr/local/bin:/usr/bin:/bin.
  5. Como você pode verificar se uma tarefa agendada foi executada? Cite duas formas.

    ✓ Resposta: 1) Verificar os logs do sistema com grep CRON /var/log/syslog ou journalctl -u cron. 2) Verificar o arquivo de log para onde a saída foi redirecionada, se configurado.

Referências