Como construir expressões cron

· 9 min de leitura

As expressões cron são a forma padrão de definir horários recorrentes em Linux, plataformas na nuvem, pipelines CI/CD e agendadores de tarefas. A sintaxe é compacta mas pouco intuitiva: construir um gerador cron visual mostra-lhe exatamente quando a sua tarefa será executada, apanha erros comuns antes do deploy e elimina a adivinhação da parte mais propensa a erros da automação. Uma vez compreendidos os cinco campos, os caracteres especiais e as armadilhas mais comuns, pode especificar qualquer horário recorrente com confiança.

Uma breve história do cron

O primeiro cron veio de Brian Kernighan na versão 7 do Unix, por volta de 1979. Relia a sua configuração a cada minuto e executava o que estivesse pendente. Paul Vixie reescreveu-o em 1987 para o que hoje se chama Vixie cron, a versão que a maioria das distribuições Linux ainda usa. O Vixie cron acrescentou crontabs por utilizador, variáveis de ambiente, a palavra-chave @reboot e várias funcionalidades de conforto que tornaram o formato utilizável para não-administradores.

A sintaxe de 5 campos quase não mudou em mais de quarenta anos. Amazon EventBridge, Google Cloud Scheduler, Kubernetes CronJob, GitHub Actions, GitLab CI, Jenkins, Airflow, n8n e dezenas de outros sistemas consomem o mesmo formato compacto com apenas pequenas extensões. Essa estabilidade é a razão pela qual cron vale a pena aprender uma vez e nunca mais ter de reaprender. A competência transfere-se para todo o lado onde a automação corre por relógio.

Sintaxe cron

Uma expressão cron padrão tem 5 campos, separados por espaços. Cada campo controla uma fatia de tempo, e uma tarefa corre sempre que todos os campos correspondem ao momento atual.

┌───────────── minuto (0-59)
│ ┌───────────── hora (0-23)
│ │ ┌───────────── dia do mês (1-31)
│ │ │ ┌───────────── mês (1-12, ou JAN-DEC)
│ │ │ │ ┌───────────── dia da semana (0-6, Dom=0, ou SUN-SAT)
│ │ │ │ │
* * * * *

Os campos são combinados com E para hora, minuto e mês, mas dia-do-mês e dia-da-semana são combinados com OU no Vixie cron. Isto significa que 0 12 1 * 1 dispara no dia 1 de cada mês E em todas as segundas-feiras ao meio-dia, não apenas nas segundas-feiras que calham no dia 1. Esta armadilha apanha quase toda a gente da primeira vez.

Horários cron comuns

Os padrões a que vai recorrer com mais frequência:

HorárioExpressãoSignificado
Cada minuto* * * * *Corre a cada 60 segundos
Cada 5 minutos*/5 * * * *Em :00, :05, :10, :15...
Cada 15 minutos*/15 * * * *Em :00, :15, :30, :45
Cada hora0 * * * *No início de cada hora
Cada 2 horas0 */2 * * *Em 00:00, 02:00, 04:00...
Diariamente à meia-noite0 0 * * *Uma vez por dia às 00:00
Diariamente às 9h0 9 * * *Uma vez por dia às 09:00
Duas vezes por dia0 9,21 * * *Às 09:00 e 21:00
Toda segunda às 8h0 8 * * 1Semanal, à segunda
Dias úteis às 18h0 18 * * 1-5De segunda a sexta
Dia 1 de cada mês0 0 1 * *Mensal, à meia-noite do dia 1
Cada trimestre0 0 1 */3 *1 jan, 1 abr, 1 jul, 1 out
Cada manhã útil0 7 * * 1-507:00 segunda-sexta
Domingo ao meio-dia0 12 * * 0Semanal, ao domingo

Muitos sistemas também aceitam aliases abreviados que expandem para a expressão de 5 campos equivalente: @yearly, @monthly, @weekly, @daily, @hourly e @reboot. São concisos mas não universais, por isso verifique a sua plataforma antes de confiar neles.

Como construir uma expressão cron

  1. Escolha a granularidade: precisa de cada minuto, cada hora, uma vez por dia, uma vez por semana ou uma vez por mês? Comece pelo ajuste mais grosseiro que cobre a sua necessidade.
  2. Use os controlos visuais: selecione valores de minuto, hora, dia, mês e dia da semana nos dropdowns. Ou comece com uma predefinição como "cada hora" ou "diário à meia-noite" e ajuste.
  3. Pré-visualize as próximas execuções: o gerador mostra os próximos 5 horários de execução, o que lhe permite confirmar que o horário dispara quando espera.
  4. Confirme o fuso horário: a pré-visualização deve corresponder ao fuso do servidor ou agendador que vai correr a tarefa, não à sua hora local.
  5. Copie a expressão e cole na sua crontab, YAML do GitHub Actions, regra do AWS EventBridge ou qualquer agendador que use.
  6. Teste primeiro com um intervalo curto antes de fixar o horário final. Um rápido */5 * * * * prova que a tarefa dispara; assim que vir duas ou três execuções, mude para a expressão real.

Caracteres e operadores especiais

O cron suporta um conjunto pequeno mas poderoso de operadores dentro de qualquer campo.

CaractereSignificadoExemplo
*Qualquer valor* * * * * = cada minuto
*/nCada n*/15 * * * * = cada 15 min
,Vários valores discretos0 8,12,18 * * * = 8h, meio-dia, 18h
-Intervalo inclusivo0 9-17 * * * = cada hora 9h-17h
n-m/kIntervalo com passo0 9-17/2 * * * = 9, 11, 13, 15, 17
?Sem valor específico (só Quartz)0 0 ? * MON (agendadores Java)
LÚltimo (AWS, Quartz)L em DoM = último dia do mês
WDia útil mais próximo (AWS, Quartz)15W = dia útil mais próximo do dia 15
#Enésimo dia da semana (AWS, Quartz)MON#2 = segunda segunda-feira do mês
@hourlyAtalhoO mesmo que 0 * * * *

O Vixie cron clássico só suporta as primeiras cinco linhas. Os operadores avançados (L, W, #, ?) vêm do Quartz, a biblioteca de agendamento Java, e foram adotados pelo AWS EventBridge e por alguns outros agendadores cloud. Não são portáveis, por isso não os misture com código que tem de correr numa caixa Linux genérica.

Cron em diferentes plataformas

O cron é uma família de sintaxes relacionadas, não um padrão único. Saber que dialeto fala o seu agendador poupa horas de depuração.

PlataformaCamposNotas
Vixie cron (Linux)5O clássico. */n, intervalos, listas, sem operadores avançados
BSD cron5Como Vixie mas com ligeiras diferenças de ambiente
crontab.guru5Analisador web que reflete a semântica Vixie
GitHub Actions5Sintaxe Vixie, corre em UTC, resolução mínima de 5 minutos
GitLab CI5Sintaxe Vixie, corre no fuso da instância
AWS EventBridge6Acrescenta ano. Dia da semana usa 1-7 (Dom=1), suporta L/W/#
Google Cloud Scheduler5Sintaxe Vixie mais configuração de fuso
Kubernetes CronJob5Sintaxe Vixie com atalhos @
Quartz (Java)6 ou 7Acrescenta segundos no início e ano opcional
Timers do systemdFormato OnCalendarNão é cron, mas resolve o mesmo problema com sintaxe mais clara

Se escrever um horário que tenha de correr em mais do que uma plataforma, fique pelo subconjunto conservador de 5 campos que todos os sistemas entendem. Use L, W ou # só quando souber que o destino os suporta.

Armadilhas comuns

Alternativas ao cron

Para algumas cargas a resolução grosseira ao minuto do cron e a ausência de contabilidade começam a doer. As melhorias mais comuns:

FerramentaForçaQuando escolher
Timers do systemdSintaxe OnCalendar clara, persistente entre reinícios, integra com unitsJá usa systemd e quer logging mais rico
AnacronRecupera execuções perdidas após suspensãoPortáteis ou máquinas que não estão sempre ligadas
Airflow / DagsterDependências DAG, retentativas, observabilidadePipelines de dados multi-passo
TemporalWorkflows com estado, garantias exatamente-uma-vezOrquestração de longa duração entre serviços
AWS EventBridgeGerido, integra com Lambda, S3, SQSTudo o que é cloud-nativo na AWS
GitHub ActionsGratuito para repositórios públicos, corre em runners hospedadosTarefas agendadas adjacentes ao CI
funções serverless com triggers cronSem servidor para manterTarefas leves que cabem num Lambda

O cron continua a ser a resposta certa para a grande maioria das tarefas recorrentes pontuais. As outras ferramentas brilham quando precisa de estado, retentativas, dependências ou coordenação entre máquinas.

Privacidade e o gerador cron

O gerador de expressões cron corre inteiramente no seu browser. O horário que constrói, a pré-visualização das próximas execuções e a expressão copiada nunca tocam os nossos servidores. Não há registo de que expressões foram geradas, nem telemetria sobre que predefinições são populares, nem maneira de alguém reconstruir o horário em que estava a trabalhar. Expressões cron não são dados pessoais à primeira vista, mas o horário de uma tarefa (uma exportação noturna de base de dados, uma execução semanal de faturação, uma sincronização horária com um parceiro) pode revelar muito sobre como um negócio opera. Manter essa informação do lado do cliente evita vazar acidentalmente padrões de infraestrutura a terceiros. Para uma tarefa tão rotineira como escolher um horário, o nível de privacidade por defeito deve corresponder à sensibilidade do que esses horários representam.

Perguntas frequentes

Qual é o formato da expressão cron?

Uma expressão cron padrão tem 5 campos separados por espaços, representando minuto (0-59), hora (0-23), dia do mês (1-31), mês (1-12) e dia da semana (0-6, onde 0 é domingo). Um asterisco (*) significa "cada" valor nesse campo.

O que significa */5 em cron?

A sintaxe */5 significa "a cada 5º". No campo de minuto, */5 significa a cada 5 minutos (0, 5, 10, 15...). No campo de hora, */5 significa a cada 5 horas. Funciona em qualquer campo.

As expressões cron são iguais em todas as plataformas?

O formato de 5 campos é padrão em Linux cron, AWS EventBridge, GitHub Actions e na maioria dos sistemas de agendamento. Algumas plataformas adicionam um sexto campo para segundos ou ano. Verifique a documentação da sua plataforma.

Como agendo algo para o último dia de cada mês?

O cron padrão não tem uma palavra-chave "último dia". Use uma solução alternativa como executar diariamente e verificar a data no seu script, ou use extensões específicas da plataforma (AWS EventBridge suporta L para "último").

Why did my cron job not run at the expected time?

The most common cause is timezone confusion. Server cron usually runs in UTC, not your local time. Other causes include the server being asleep at the scheduled minute, the user crontab not being installed, or PATH/environment differences between your shell and cron's stripped-down environment.

What is the difference between 0 in the day-of-week field and 7?

Both 0 and 7 represent Sunday in classic Vixie cron, which uses 0-6 plus an alias for 7. Some implementations (notably AWS EventBridge) use 1-7 with Sunday as 7 and Monday as 1, so always check your platform's documentation before assuming.