Expressões cron explicadas: campos, passos e fusos horários

Atualizado:

Cron é o agendador que roda comandos em horários fixos nos sistemas do tipo Unix, e seu formato de cinco campos se espalhou muito além dele: GitHub Actions, Kubernetes e muitos painéis de hospedagem usam a mesma notação. Uma linha como 30 2 * * 1 se lê “às 02:30 toda segunda-feira”. Quase tudo no formato é simples; algumas regras não são, e são elas que explicam tarefas que rodam na hora errada, duas vezes ou nunca. Este guia segue o padrão POSIX e o cronie, um cron muito usado no Linux, e indica onde outros agendadores são diferentes.

Os cinco campos

Uma linha de crontab tem cinco campos de tempo separados por espaços, seguidos do comando. A tarefa roda em cada minuto que atende a todos eles, com uma exceção para os dois campos de dia, explicada mais abaixo. O padrão numera os dias da semana de 0 a 6, com 0 para domingo; o cronie e a maioria dos cron do Linux aceitam também 7 para domingo, e nomes em inglês de três letras, como mon ou jan, em maiúsculas ou minúsculas.

CampoValoresExemploSignifica
Minuto0–5930no minuto 30
Hora0–232das 02:00 às 02:59
Dia do mês1–311,15nos dias 1 e 15
Mês1–12 ou jan–dec*todo mês
Dia da semana0–7 ou sun–sat (0 e 7 são domingo)1-5de segunda a sexta

Um asterisco quer dizer todos os valores do campo. As horas seguem o relógio de 24 horas: 9 é 09:00 e 21 é 21:00.

Listas, intervalos e passos

Um campo pode ter uma lista (1,15), um intervalo (9-17) ou um passo. O passo divide um intervalo: 0-30/10 no campo de minutos são os minutos 0, 10, 20 e 30, e */15 percorre todos os valores a partir do primeiro, ou seja, os minutos 0, 15, 30 e 45. Os passos contam a partir do início do intervalo e recomeçam a cada nova hora, dia ou mês; não continuam do anterior.

No campo de minutos, só os passos que dividem 60 exatamente (1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30) dão intervalos iguais. Para rodar a cada 90 minutos são necessárias duas linhas: 0 0-21/3 * * * roda às 00:00, 03:00 … 21:00, e 30 1-22/3 * * * às 01:30, 04:30 … 22:30.

O cronie também aceita atalhos: @hourly, @daily (0 0 * * *), @weekly (0 0 * * 0), @monthly (0 0 1 * *), @yearly ou @annually (0 0 1 1 *) e @reboot, que roda uma vez na inicialização. Eles não fazem parte do padrão: o GitHub Actions, por exemplo, não os aceita.

Gerador de expressão Cron

Dia do mês ou dia da semana

Quando os campos de dia do mês e de dia da semana têm algo diferente de um asterisco, o padrão diz que um dia vale se qualquer um dos dois bater, não os dois. Por isso 0 9 13 * 5 roda às 09:00 todo dia 13 e toda sexta-feira, e não só na sexta-feira 13. Em novembro de 2026 são os dias 6, 13 (uma sexta, executado uma vez), 20 e 27.

Para combinar os dois, agende um campo e deixe o comando conferir o outro. Num crontab, um % no comando vira quebra de linha, então ele precisa ser escrito \%:

Fusos horários e horário de verão

O cron lê o agendamento no fuso horário da máquina ou do serviço que o executa, que em servidores e plataformas hospedadas costuma ser UTC. 0 9 * * * num servidor em UTC roda sempre às 06:00 em São Paulo, já que o Brasil não tem horário de verão; em Lisboa e Londres, às 09:00 ou 10:00, e em Paris, Berlim, Madri ou Roma, às 10:00 ou 11:00, conforme a época do ano. O cronie deixa um crontab definir o próprio fuso com a variável CRON_TZ; o GitHub Actions aceita uma chave timezone ao lado de cron; o Kubernetes tem o campo .spec.timeZone, estável desde a versão 1.27, e recusa CRON_TZ ou TZ escritos dentro do agendamento.

Onde há horário de verão, algumas horas locais somem ou se repetem. Em 29 de março de 2026 os relógios de Paris, Berlim, Madri e Roma pulam das 02:00 para as 03:00, então 30 2 * * * indica uma hora que não existe; em 25 de outubro de 2026 a hora das 02:00 às 03:00 acontece duas vezes. Em Lisboa e Londres é a hora da 01:00 às 02:00.

AgendadorTarefa na hora puladaTarefa na hora repetida
cronie (mudanças de menos de 3 horas, tarefas em hora fixa ou menos frequentes que de hora em hora)roda logo depois da mudançaroda uma vez
GitHub Actions (com timezone)passa para a próxima hora válida: 02:30 vira 03:00não informado
AWS EventBridge Scheduler (com fuso horário)é puladaroda uma vez
Agendamentos em UTCsem efeitosem efeito

O cronie agenda normalmente as tarefas que rodam mais de uma vez por hora, e o manual do crontab avisa de modo geral que horas que faltam nunca batem e horas repetidas podem disparar duas vezes, então o comportamento muda de um cron para outro. O mais seguro é manter o agendamento em UTC ou evitar as horas entre 01:00 e 03:00 locais para tarefas que precisam rodar exatamente uma vez por dia.

O ambiente em que a tarefa roda

Uma tarefa do cron não recebe o ambiente do seu terminal. O padrão executa o comando com sh e um conjunto mínimo de variáveis (HOME, LOGNAME, PATH e SHELL), então um comando que funciona quando você digita pode falhar no cron porque um programa não está no PATH ou falta uma variável. Use caminhos completos ou defina PATH no início do crontab.

Tudo o que o comando imprime é enviado por e-mail ao dono do crontab; o cronie envia para o endereço em MAILTO e não envia nada se MAILTO estiver vazia. Num servidor sem e-mail configurado essa saída se perde com facilidade, então é melhor mandá-la para um arquivo de log.

O cron inicia cada execução na hora marcada, tenha a anterior terminado ou não, então uma tarefa que às vezes demora mais que o intervalo pode acabar rodando duas vezes ao mesmo tempo. O flock, do util-linux, mantém um arquivo de trava enquanto o comando roda; com -n ele desiste na hora, com código de saída 1, se a trava estiver ocupada. O Kubernetes tem a mesma escolha embutida: concurrencyPolicy é Allow por padrão e pode ser Forbid (pular a nova execução) ou Replace (parar a anterior).

O mesmo agendamento em outras plataformas

O formato de cinco campos não é universal. Alguns agendadores acrescentam segundos ou um ano, outros exigem um ponto de interrogação num dos dois campos de dia porque não aceitam a regra de um ou outro, e outros numeram os dias da semana a partir de 1. “Dias úteis às 09:00” em cada um:

AgendadorExpressãoObservações
Cron do Linux (cronie)0 9 * * 1-5Fuso da máquina, ou CRON_TZ.
GitHub Actions0 9 * * 1-5UTC, a menos que timezone seja definido; no máximo uma vez a cada 5 minutos; sem atalhos com @.
Kubernetes CronJob0 9 * * 1-5Fuso do controlador, ou .spec.timeZone.
AWS EventBridgecron(0 9 ? * MON-FRI *)Seis campos com o ano; ? num campo de dia; os dias 1–7 começam no domingo; as regras agendadas usam UTC.
Quartz (Java)0 0 9 ? * MON-FRISegundos primeiro, ano opcional; ? num campo de dia; os dias 1–7 começam no domingo.
Timer do systemdOnCalendar=Mon..Fri *-*-* 09:00:00O dia da semana e a data precisam bater os dois; *-*~01 é o último dia do mês.

Ao copiar um agendamento entre sistemas, confira o número de campos e como os dias da semana são numerados: 1 é segunda-feira no cron, mas domingo no Quartz e no EventBridge.

Por que uma tarefa não rodou

Antes de confiar num agendamento, releia campo por campo e, no Linux, confira as próximas execuções: systemd-analyze calendar mostra essas datas para uma expressão de timer.

Perguntas frequentes

Domingo é 0 ou 7?

Os dois, no cronie e na maioria dos cron do Linux. O padrão POSIX só define de 0 a 6, com 0 para domingo, então 0 é a escolha portável.

O cron consegue rodar uma tarefa a cada 30 segundos?

Não: a menor unidade é o minuto. Agendadores com campo de segundos, como o Quartz, conseguem; no Linux, um timer do systemd também.

Como rodo uma tarefa a cada 90 minutos?

Com duas linhas: 0 0-21/3 * * * e 30 1-22/3 * * *. Juntas, rodam a cada hora e meia, das 00:00 às 22:30.

O que significa 0 0 * * 0?

Meia-noite no início de todo domingo. É o mesmo que @weekly no cronie.

Por que minha tarefa roda em dias que eu não escolhi?

Provavelmente porque os dois campos de dia estão definidos. O cron padrão roda a tarefa quando bate o dia do mês ou o dia da semana.

Referências

  1. The Open Group Base Specifications (POSIX.1-2024) — crontab
  2. cronie — crontab(5): tables for driving cron
  3. cronie — cron(8): daylight saving time and other time changes
  4. util-linux — flock(1)
  5. GitHub Docs — Events that trigger workflows: schedule
  6. Kubernetes documentation — CronJob
  7. Amazon EventBridge — Cron expressions for scheduled rules
  8. Amazon EventBridge Scheduler — Schedule types (time zones and daylight saving)
  9. Quartz Scheduler — CronTrigger tutorial
  10. systemd — systemd.timer(5) and systemd.time(7): calendar events

Guias relacionados