Cron é o agendador de tarefas mais antigo e mais amplamente implantado na computação - o cron Unix original lançado em 1975 e sua sintaxe de expressão foi herdada essencialmente inalterada por todos os sistemas de agendamento modernos, de crontabs Unix a Kubernetes CronJobs e agendadores de nuvem em AWS, GCP e Azure. Apesar dessa onipresença, as expressões cron são notoriamente propensas a erros quando escritas à mão, e um único caractere errado pode transformar um trabalho diário em um trabalho que ocorre uma vez por hora e desativa um sistema de produção. As seções abaixo explicam a estrutura de 5 campos, os caracteres especiais que a estendem e as dicas práticas que surpreendem até mesmo engenheiros experientes.

A estrutura de 5 campos e o que cada um significa

Uma expressão cron padrão possui exatamente 5 campos separados por espaço em uma ordem fixa: minuto, hora, dia do mês, mês, dia da semana. Cada campo aceita um número dentro de seu intervalo válido (minuto 0–59, hora 0–23, dia do mês 1–31, mês 1–12, dia da semana 0–6 com 0 = domingo), um curinga `*` significando qualquer valor ou qualquer uma das sintaxes especiais descritas na próxima seção. Os campos seguem um padrão cronológico de ampliação: minuto é o mais preciso, dia da semana é o mais geral para padrões semanais. Um detalhe complicado é o campo do dia da semana: historicamente diferentes variantes do Unix discordavam sobre se domingo era 0 ou 7, e o padrão moderno aceita ambos para compatibilidade. Os campos de mês e dia da semana também aceitam abreviações de três letras (`JAN`-`DEC`, `SUN`-`SAT`), que não diferenciam maiúsculas de minúsculas e geralmente são mais legíveis do que valores numéricos. Quando o dia do mês e o dia da semana são especificados, a maioria das implementações do cron usa a lógica OR (o trabalho é executado quando um deles corresponde), não a lógica AND (ambas as correspondências são necessárias). Esta é uma das fontes mais comuns de confusão — `0 0 15 * FRI` funciona à meia-noite do dia 15 de cada mês E todas as sextas-feiras, não apenas nas sextas-feiras que caem no dia 15.

Caracteres especiais: etapa, intervalo, lista e curingas

Quatro caracteres especiais estendem a sintaxe básica do cron e atendem à maioria das necessidades de agendamento do mundo real. O asterisco `*` é o curinga de todos os valores: `* * * * *` é acionado a cada minuto de cada hora de cada dia. A barra `/` introduz valores de etapa: `*/15` no campo dos minutos é acionado nos minutos 0, 15, 30, 45 — a cada 15 minutos. As etapas podem ser combinadas com intervalos: `9-17/2` dispara nas horas 9, 11, 13, 15, 17. O hífen `-` introduz intervalos: `9-17` abrange das 9h às 17h, inclusive no campo de hora. A vírgula `,` introduz listas: `1,3,5` no campo do dia da semana significa segunda, quarta, sexta. Eles se combinam livremente - `0 9,12,17 * * 1-5` dispara às 9h, meio-dia e 17h durante a semana. Algumas implementações do cron adicionam recursos especiais além desses princípios básicos. Quartz (usado por muitas bibliotecas de agendamento Java) adiciona `L` (último dia do mês/semana), `W` (dia da semana mais próximo) e `#` (enésima ocorrência de um dia em um mês). Jenkins adiciona `H` para valores hash que distribuem programações idênticas ao longo do tempo para evitar efeitos de rebanho trovejante. Esta ferramenta tem como alvo o formato padrão de 5 campos usado pelo Unix crontab, AWS EventBridge, GCP Cloud Scheduler, Azure Logic Apps e bibliotecas de agendamento mais populares, como node-cron e python-crontab.

Dicas práticas que pegam até engenheiros experientes

Várias pegadinhas do cron causam repetidamente incidentes de produção, mesmo para equipes que usam o cron todos os dias. Primeiro, manipulação de fuso horário: as expressões cron são executadas no fuso horário local do sistema por padrão, o que significa que as transições de horário de verão em março e novembro podem fazer com que os trabalhos pulem um dia ou sejam executados duas vezes, dependendo da direção da transição. Sempre configure cron jobs para execução em UTC sempre que possível ou teste explicitamente os fins de semana de transição do horário de verão antes de implantar programações urgentes. Em segundo lugar, a lógica OR do dia do mês versus dia da semana discutida acima captura os engenheiros esperando a lógica AND. Se você deseja que um trabalho seja executado apenas nas sextas-feiras que caem no dia 15, você não pode expressar isso no cron padrão - você precisa usar a lógica AND no código do aplicativo após o trabalho ser acionado. Terceiro, casos extremos de anos bissextos: `0 0 29 2 *` é executado apenas em 29 de fevereiro, o que acontece uma vez a cada 4 anos. Testar isso uma vez e ver que parece não funcionar é fácil. Quarto, `@reboot` e outros especiais como `@daily` ou `@hourly` são suportados por muitas implementações, mas não são portáveis ​​— os agendadores de nuvem geralmente não os aceitam. Sempre use o formulário explícito de 5 campos para portabilidade. Quinto, trabalhos de longa duração podem se sobrepor: se um trabalho for executado a cada 5 minutos, mas levar 7 minutos para ser executado, duas instâncias serão executadas simultaneamente. Use um arquivo de bloqueio (`flock` no Linux) ou use a coordenação em nível de aplicativo para evitar isso.