Analisador de expressões cron

Leia uma expressão cron em linguagem clara e veja exatamente quando ela roda na próxima vez.

minuto · hora · dia do mês · mês · dia da semana. Macros como @daily também funcionam.

Experimente:

Isto corre

às 03:00, à segunda-feira

Próximas seis execuções · UTC

  1. 2026-09-21 03:00segunda-feira
  2. 2026-09-28 03:00segunda-feira
  3. 2026-10-05 03:00segunda-feira
  4. 2026-10-12 03:00segunda-feira
  5. 2026-10-19 03:00segunda-feira
  6. 2026-10-26 03:00segunda-feira

Mostrado em UTC. Um crontab real corre no fuso horário do servidor, que é onde a mudança de hora causa problemas — veja abaixo.

Campo a campo

minuto
00
hora
33
dia do mês
*qualquer
mês
*qualquer
dia da semana
11

O que vale a pena saber sobre este agendamento

  • O dia 31 não existe em todos os meses, por isso nesses meses simplesmente não corre.
  • O 29 de fevereiro só existe em anos bissextos — isto corre uma vez de quatro em quatro anos.

Cinco campos, o mais grosseiro no fim

PosiçãoCampoIntervaloNotas
1Minuto0–59
2Hora0–23Relógio de 24 horas, hora do servidor
3Dia do mês1–31Os dias que não existem são simplesmente saltados
4Mês1–12Ou JANDEC
5Dia da semana0–70 e 7 significam ambos domingo. Ou SUNSAT

Dentro de um campo: * é qualquer, , enumera valores, - dá um intervalo e / avança em passos. */15 no campo dos minutos é de quinze em quinze minutos; 5/10 significa a partir de 5, de dez em dez, ou seja 5, 15, 25 e por aí fora. Os intervalos podem dar a volta, portanto FRI-MON é uma forma válida de dizer o fim-de-semana mais as suas pontas.

A regra que apanha toda a gente

É esta a única coisa que vale a pena levar desta página.

Quando ambos os campos — dia do mês e dia da semana — estão restringidos, o cron corre a tarefa quando qualquer um deles coincide. Não os dois. É um OU, e lê-se como um E.

0 0 1 * MON   # NOT "the 1st, if it is a Monday"
              # Actually: every 1st, AND every Monday

Esse agendamento dispara umas cinco vezes por mês. Cole-o no analisador acima e olhe para as próximas execuções — a sequência denuncia-o imediatamente.

A regra só se aplica quando ambos os campos estão restringidos. Se um deles for *, manda simplesmente o outro, e é por isso que 0 0 * * MON se comporta exactamente como se espera. O comportamento está na especificação POSIX e todos os cron correntes o implementam, portanto não é um defeito que se desligue nas configurações.

Para exigir mesmo as duas condições, restrinja um campo no agendamento e verifique o outro no início da tarefa:

0 0 * * MON  [ "$(date +\%d)" = "01" ] && /usr/local/bin/job

A mudança de hora, que parte tarefas duas vezes por ano

O cron corre no fuso horário local do servidor salvo indicação em contrário, e a hora local não é contínua. Quando os relógios adiantam, desaparece uma hora: uma tarefa marcada para as 02:30 pode ser saltada por completo ou disparar às 03:30, conforme o cron que tiver. Quando atrasam, a 01:30 acontece duas vezes, e a tarefa pode acontecer também.

O Vixie cron moderno faz um esforço — as tarefas perdidas por um salto para a frente costumam correr uma vez a seguir — mas o comportamento não é consistente entre implementações, e os agendadores de contentores variam outra vez.

A correcção duradoura é correr o agendador em UTC e converter nas pontas. Os CronJobs do Kubernetes usam UTC por omissão exactamente por isto. Se uma tarefa tiver mesmo de correr a uma hora local específica, aceite que ficará uma hora ao lado durante parte do ano, ou use um agendador que perceba fusos horários a sério — os temporizadores do systemd percebem.

Outras razões para uma tarefa cron não correr

  • O ambiente está quase vazio. O cron não carrega o perfil da sua shell, portanto o PATH é mínimo e o seu ambiente virtual não está activo. Use sempre caminhos absolutos.
  • Um sinal de percentagem solto. Numa crontab, % significa mudança de linha. date +%Y parte-se em silêncio; tem de ser date +\%Y.
  • Sem mudança de linha final. Alguns cron ignoram a última linha de uma crontab que não termine numa.
  • A saída vai para lado nenhum. O cron envia a saída por correio ao utilizador, e se o correio não estiver configurado ela desaparece. Redireccione para um ficheiro de registo para que as falhas se vejam.
  • Execuções sobrepostas. O cron não espera que a execução anterior acabe. Uma tarefa de cinco minutos num agendamento de um minuto acumula-se até algo ceder. Use flock.

O que o cron não consegue exprimir

Os campos são independentes, portanto tudo o que não divida certo numa hora ou num dia fica fora de alcance. «De 90 em 90 minutos» não se escreve. Nem «a última sexta-feira do mês» no cron padrão — é para isso que existem o L e o # do Quartz, e é por isso que não são portáveis.

Se der por si a lutar com a sintaxe, isso costuma ser o sinal para passar a um agendador que pense em intervalos e não em campos de calendário. Um temporizador do systemd com OnUnitActiveSec=90min diz o que queria dizer numa linha.

Relacionado

As horas de execução acima estão em UTC — o conversor de marcas temporais passa qualquer uma delas para o seu fuso, ou para o formato que o seu agendador usa nos registos. Para comparar texto em vez de agendar, o testador de regex fica mesmo ao lado.

Perguntas sobre cron

Porque é que a minha tarefa corre em dias que não agendei?

Quase de certeza pela regra do dia do mês com o dia da semana. Quando os dois campos estão restringidos, o cron corre a tarefa quando QUALQUER um deles coincide — não os dois. Portanto 0 0 1 * MON dispara no dia 1 de cada mês e em todas as segundas-feiras, o que dá umas cinco vezes por mês em vez da única que pretendia. Se um dos campos for *, a regra não se aplica e manda simplesmente o outro. Para exigir as duas condições, restrinja um campo no cron e verifique o outro dentro da própria tarefa.

O que significam os cinco campos?

Minuto (0–59), hora (0–23), dia do mês (1–31), mês (1–12), dia da semana (0–7, em que tanto 0 como 7 são domingo). Da esquerda para a direita vai ficando progressivamente mais grosseiro, o que dá uma boa mnemónica. Alguns agendadores — o Quartz, o Spring e vários executores de tarefas — acrescentam à frente um sexto campo para segundos; o crontab padrão não tem campo de segundos nenhum.

O que acontece a uma tarefa cron na mudança de hora?

Depende da implementação, e é aqui que as tarefas agendadas se avariam em silêncio duas vezes por ano. Quando os relógios adiantam, há uma hora que não existe — uma tarefa das 02:30 pode ser saltada por completo ou correr às 03:30, conforme o cron. Quando atrasam, a 01:30 acontece duas vezes, portanto a tarefa pode correr duas vezes. O Vixie cron moderno e os temporizadores do systemd tentam ser sensatos nisto; os antigos não. A resposta robusta é correr o trabalho agendado em UTC e converter nas pontas.

O que são L, W e # e porque são recusados aqui?

São extensões do Quartz — L para «último» (último dia do mês, última sexta-feira), W para o dia útil mais próximo e # para «o n-ésimo dia da semana do mês». São genuinamente úteis e não são cron padrão. O crontab, os CronJobs do Kubernetes e o GitHub Actions ou os rejeitam ou os lêem mal. Este analisador recusa em vez de adivinhar, porque um agendamento que ignore um L em silêncio estaria errado exactamente da maneira que ninguém confere.

O que faz o @reboot?

Corre a tarefa uma vez quando o cron arranca, normalmente no arranque da máquina. Não tem agendamento recorrente, portanto não há próximas execuções para calcular — e é por isso que esta ferramenta o diz em vez de mostrar uma lista vazia. Convém saber que o @reboot dispara quando o serviço cron arranca e não quando a máquina acaba de arrancar, por isso tudo o que dependa de a rede estar de pé tem de esperar por conta própria.

Como corro alguma coisa de 90 em 90 minutos?

Não consegue exprimi-lo directamente, e esta é uma limitação genuína e não um truque que ainda não aprendeu. Os campos do cron são independentes, portanto */90 no campo dos minutos é inválido e não há maneira de fazer um agendamento que não divida certo numa hora ou num dia. As saídas são duas entradas que cubram o padrão ao longo de um dia ou — mais honestamente — um agendador que pense em intervalos em vez de campos de calendário, como um temporizador do systemd com OnUnitActiveSec.

Última revisão . Encontrou algo desactualizado? Diga-nos.