design

Guia da Sintaxe do Cron (2026): Como Ler e Criar Qualquer Expressão Crontab

Sintaxe do cron explicada: a ordem dos 5 campos, um modelo para ler em 10 segundos, 16 receitas testadas, a pegadinha do OR no dia da semana, armadilhas de horário de verão e cron vs systemd timers.

Published 2026-07-04 · 10 min read

Affiliate disclosure

Some links below are affiliate links. I may earn a commission from qualifying purchases at no extra cost to you. I only recommend tools I have used or tested.


“Falar é fácil. Mostre-me o código.”
― Linus Torvalds
Photo by Mohammad Rahmani on Unsplash

TL;DR

  • Cinco campos, nesta ordem: minute hour day-of-month month day-of-week (minuto, hora, dia do mês, mês, dia da semana). Deixe como * qualquer campo que você não queira restringir.
  • A pegadinha que pega todo mundo: se você restringir tanto o dia do mês quanto o dia da semana, o Vixie cron executa o job quando qualquer um dos dois der match (um OR, e não um AND). Restrinja apenas um e deixe o outro como *.
  • Teste antes de subir para produção: cole qualquer expressão no Cron Parser para ver os próximos horários exatos de execução em linguagem simples.

Você precisa que um script rode toda noite às 2 da manhã. Você abre o crontab -e, encara cinco asteriscos e percebe que não sabe qual deles é a hora. Este guia resolve isso de uma vez por todas: como ler qualquer linha de cron em dez segundos, montar a que você precisa usando receitas testadas e conhecer as duas ou três armadilhas que quebram jobs silenciosamente em produção.

Como ler qualquer expressão cron em 10 segundos?

Leia da esquerda para a direita como cinco campos, sempre nesta ordem exata:

┌───────────── minuto         (0-59)
│ ┌─────────── hora           (0-23)
│ │ ┌───────── dia do mês     (1-31)
│ │ │ ┌─────── mês            (1-12)
│ │ │ │ ┌───── dia da semana  (0-7, 0 e 7 = Domingo)
│ │ │ │ │
* * * * *  comando a executar

O modelo mental todo é este: você só controla três coisas — o minuto, a hora e um seletor de dia — e deixa todos os outros campos que não importam como *. O asterisco significa "todos os valores deste campo", então * * * * * roda o comando a cada minuto, para sempre. Todas as receitas que você vai criar são essa linha de base com um a três campos fixados.

Então 30 2 * * * lê-se assim: minuto 30, hora 2, todos os dias do mês, todos os meses, todos os dias da semana — ou seja, 2:30 da manhã todos os dias. O comando logo após o quinto campo é o que será executado; não é um sexto campo de tempo. Esse é o pulo do gato. Os intervalos de cada campo e o significado do asterisco são definidos na man page do crontab(5) e na especificação POSIX do crontab; na dúvida, cheque a linha no Cron Parser em vez de tentar adivinhar.

O que significa cada um dos cinco campos?

Cada campo tem um intervalo fixo e um par de particularidades que valem a pena conhecer de antemão. Esta é a tabela de referência para a qual você sempre vai voltar.

CampoIntervaloObservações
Minuto0-59Minuto da hora. 0 é o topo da hora.
Hora0-23Relógio de 24 horas, horário local do sistema. 0 é meia-noite, 23 é 23h.
Dia do mês1-31Começa no 1, e não no 0. Não existe um "último dia do mês" nativo.
Mês1-121 é janeiro. Nomes de três letras (JANDEC) também funcionam na maioria das implementações.
Dia da semana0-70 e 7 significam domingo, 1 é segunda-feira, 6 é sábado. Nomes (SUNSAT) também funcionam.

Dois detalhes sobre os intervalos costumam confundir. O dia do mês começa no 1, enquanto os campos de tempo (minuto, hora) começam no 0. E o dia da semana tem dois domingos: a man page do crontab(5) define como 0-7, onde "0 ou 7 é domingo", então tanto 0 (início da semana nos EUA) quanto 7 (final da semana na ISO) funcionam. A especificação POSIX é mais rígida — 0-6 sendo 0=domingo — então num cron POSIX minimalista, fique com 0-6 e não dependa do 7.

O que fazem *, ,, - e /?

Quatro caracteres cobrem todos os padrões do cron padrão. Qualquer coisa além disso é uma extensão não padrão, e você não deve assumir que haverá suporte.

CaractereNomeSignificadoExemplo
*AsteriscoTodos os valores ("do primeiro ao último") do campo* * * * * = a cada minuto
,VírgulaUma lista de valores específicos0 0,12 * * * = meia-noite e meio-dia
-HífenUm intervalo inclusivo0 9-17 * * * = de hora em hora, das 9h às 17h
/BarraUm passo ("a cada enésimo") num intervalo ou **/5 * * * * = a cada 5 minutos

A única sutileza é a partir de onde o passo começa a contar. Um passo num asterisco começa no primeiro valor do campo: */5 no campo de minutos significa minutos 0, 5, 10 … 55. Um passo num intervalo explícito começa no limite inferior do intervalo: 10-50/5 significa 10, 15, 20 … 50 — começa no 10, e não no 0. Errar isso gera aqueles bugs de "por que ele rodou num minuto estranho", então teste schedules com passo no Cron Parser se tiver dúvida.

Qualquer outra coisa — L (último), W (dia útil mais próximo), # (enésimo dia da semana do mês), ? (sem valor específico) e um campo de segundos inicial — é não padrão. Segundo a referência do cron na Wikipédia, esses caracteres "existem apenas em algumas implementações do cron, como no agendador Quartz do Java", e o campo de segundos só aparece em variantes de 6 e 7 campos. O cron clássico Vixie/POSIX (o crontab -e da sua máquina) não tem nenhum deles. Copiar uma expressão 0 0 12 * * ? de um tutorial de Quartz não vai funcionar num crontab normal — aquele 0 inicial é um campo de segundos que o cron clássico não possui.

A tabela de receitas — 16 expressões verificadas para copiar

Cada expressão abaixo foi checada campo a campo de acordo com os intervalos acima. Copie a que você precisa; e, quando for ajustar, confira o resultado no Cron Parser.

ExpressãoEm linguagem simples
*/5 * * * *A cada 5 minutos
*/15 * * * *A cada 15 minutos
*/30 * * * *A cada 30 minutos (na hora cheia e na meia-hora)
0 * * * *De hora em hora, no minuto zero
0 */2 * * *A cada 2 horas (00:00, 02:00, 04:00 …)
0 */6 * * *A cada 6 horas (00:00, 06:00, 12:00, 18:00)
0 0 * * *Todos os dias à meia-noite
0 9 * * *Todos os dias às 9h
0 0,12 * * *Duas vezes ao dia — meia-noite e meio-dia
0 9 * * 1-59h em dias úteis (seg a sex)
0 9-17 * * 1-5De hora em hora, das 9h às 17h, dias úteis
0 0 * * 0Todo domingo à meia-noite
0 8 * * 6Todo sábado às 8h
0 18 * * 1,3,518h às segundas, quartas e sextas
0 0 1 * *Meia-noite no dia 1º de todo mês
0 0 1 1,4,7,10 *Meia-noite no dia 1º de jan, abr, jul, out (trimestral)

Repare no padrão: todas elas são * * * * * com apenas os campos importantes fixados. "Todos os dias às 9h" (0 9 * * *) mexe apenas no minuto e na hora, deixando os três campos de dia/mês como *. "Dias úteis das 9h às 17h" (0 9-17 * * 1-5) mexe no minuto, num intervalo de horas e no dia da semana — e, o mais importante, deixa o dia do mês como * para que a pegadinha do OR (próxima seção) nunca seja ativada.

Por que restringir ambos os campos de dia causa um OR, e não um AND?

Porque é assim que o Vixie cron foi especificado — e essa é de longe a regra mais surpreendente de todo o sistema.

Normalmente, o cron exige que todos os campos correspondam para rodar um job (um AND lógico). Os campos de dia são a exceção. Segundo a man page do crontab(5), textualmente:

Se ambos os campos forem restritos (ou seja, não forem *), o comando será executado quando qualquer campo corresponder ao horário atual.

A especificação POSIX diz o mesmo ("qualquer dia que corresponda ao dia do mês ou ao dia da semana será considerado"), e o crontab(5) original do Vixie cron também. Pegue esta expressão:

0 0 1,15 * 5    →  meia-noite no dia 1, no dia 15 E todo sexta-feira

Se você queria dizer "meia-noite nos dias 1 e 15, mas somente se cair numa sexta", isso está errado — o job vai disparar no dia 1, no dia 15 e em todas as sextas, porque os dois campos de dia são tratados com OR. A solução já está embutida no modelo mental: restinja apenas um seletor de dia e deixe o outro como *. Quer um dia específico do mês? Coloque o dia da semana como *. Quer um dia da semana específico? Coloque o dia do mês como *. Restrinja os dois apenas quando você quiser deliberadamente a união. O cron não tem um AND nativo para os campos de dia; se você realmente precisa do "dia 15, mas somente se for sexta", coloque essa validação dentro do próprio script. Qualquer expressão que restrinja os dois campos de dia vale a pena colar no Cron Parser para ver as reais datas de execução antes.

O que são os atalhos @ (@daily, @hourly, @reboot)?

O cron vem com oito atalhos nomeados que se expandem para uma expressão padrão, então você raramente precisa escrever os mais comuns à mão. Eles estão documentados no crontab(5):

AtalhoEquivalenteSignificado
@yearly / @annually0 0 1 1 *Uma vez por ano, meia-noite do dia 1º de janeiro
@monthly0 0 1 * *Uma vez por mês, meia-noite do dia 1º
@weekly0 0 * * 0Uma vez por semana, meia-noite do domingo
@daily / @midnight0 0 * * *Uma vez por dia, à meia-noite
@hourly0 * * * *De hora em hora, no minuto zero
@rebootUma vez, após o cron iniciar no boot

@midnight é um apelido exato para @daily (ambos são 0 0 * * *), e @annually é um apelido exato para @yearly. O @reboot é o diferente da turma — ele não tem equivalente em campos de tempo porque dispara uma vez quando o cron inicia, e não num agendamento. É útil para iniciar um job demorado logo no boot, mas lembre-se de que ele roda quando o cron começa, o que na maioria dos sistemas ocorre cedo no processo de boot, antes que outros serviços estejam prontos.

As armadilhas que picam na produção

A maioria das dores de cabeça com o cron não é de sintaxe — são essas cinco armadilhas de ambiente. Aprenda-as uma vez e você vai resolver os chamados de "rodou no horário errado" em segundos.

Fuso horário e horário de verão (DST). O cron usa o horário local do sistema, e não UTC, a menos que seja instruído do contrário — o que torna as transições de horário de verão perigosas. Na virão para a frente (spring-forward), o relógio pula das 2h para as 3h, então um job agendado para as 2:30 cai numa hora que não existe e pode ser ignorado. Na virada para trás (fall-back), a janela de 1–2h da manhã se repete, então um job nesse intervalo pode rodar duas vezes. O Vixie/cronie cron moderno possui tratamento especial para mudanças inferiores a três horas, o que atenua isso em jobs diários, mas o comportamento varia entre as implementações. A solução robusta é agendar jobs críticos fora dessa janela de 1–3h da manhã ou deixar a máquina em UTC. Você pode fixar um fuso com uma linha CRON_TZ=America/New_York acima do job — mas o CRON_TZ só muda quando o cron dispara; seu script ainda vai enxergar o fuso do sistema, a menos que você exporte a variável TZ no próprio script.

Falta de um "último dia do mês" nativo. O cron clássico não tem suporte ao L, então 0 0 31 * * simplesmente não vai rodar em fevereiro, abril, junho, setembro ou novembro. Rode diariamente e verifique a data no script, ou rode no dia 1º e processe "o dia anterior".

Passo em intervalo vs. passo no asterisco. Como vimos acima, */5 começa no 0, mas 10-50/5 começa no 10. Para algo como "a cada 5 minutos, mas só na segunda metade da hora", escreva o intervalo explicitamente.

Execuções longas e sobrepostas. O cron não verifica se a execução anterior já terminou. Se um */5 dispara um job que às vezes leva 8 minutos para rodar, duas cópias dele rodarão ao mesmo tempo — uma causa frequente de "por que rodou duas vezes", trabalho duplicado ou saída corrompida. Envolva o comando no flock (ex.: flock -n /tmp/job.lock -c 'seu-comando') para que uma segunda invocação saia imediatamente enquanto a primeira ainda segura a trava.

Ambiente e PATH minimalistas. O cron roda com um ambiente enxuto e um PATH mínimo (normalmente /usr/bin:/bin), e não com o do seu shell. Um script que funciona no seu terminal pode falhar sob o cron porque um binário não está no PATH dele. Use caminhos absolutos para binários ou defina PATH= no topo do crontab.

Cron vs systemd timers vs cloud schedulers — quando usar cada um?

Os três executam coisas agendadas; a diferença está no que sobrevive e no custo operacional. Escolha pensando no modo de falha, e não no hábito.

O Cron é o padrão universal: está em praticamente toda máquina Unix, não exige configuração além do daemon que já está rodando, e uma linha resolve o problema. Seus pontos fracos são as armadilhas que vimos acima — ele silenciosamente descarta execuções perdidas enquanto a máquina estava desligada, não tem log nativo de sucesso/erro e não impede sobreposições. Recorra ao cron para jobs simples, por host e de melhor esforço.

Os systemd timers são a opção mais pesada e robusta em distribuições Linux modernas. O OnCalendar= de um timer usa os mesmos conceitos de calendário que o cron, mas o recurso matador é o Persistent=: segundo a man page do systemd.timer(5), quando ativado, "a unidade de serviço é disparada imediatamente se teria sido disparada pelo menos uma vez durante o tempo em que o timer esteve inativo" — ou seja, uma execução perdida é recuperada após a queda, em vez de sumir. Timers também contam com logs no journal, agendamento monotônico (OnBootSec=, OnUnitActiveSec=) e RandomizedDelaySec= para escalonar frotas. O custo: você escreve uma unit .timer e uma .service em vez de uma única linha. Escolha-os quando precisar de recuperação, logs ou ordenação de dependências.

Os Cloud schedulers (cron gerenciado, CronJobs em containers, agendadores serverless) brilham quando o job precisa sobreviver à morte de uma máquina específica. Eles rodam de forma independente de qualquer host, centralizam logs e tentativas automáticas (retries), e escalam horizontalmente. A contrapartida é o vendor lock-in, a dependência de rede e o custo por execução. Escolha-os quando o agendamento for crítico para o negócio e não puder depender de uma única máquina no ar.

Não importa qual você escolha, a expressão exige a mesma habilidade. A mesma disciplina de testar antes de subir vale para regex; confira o guia do regex tester para essa outra metade da caixa de ferramentas.

Resumo

O cron se resume a cinco campos numa ordem fixa, e 95% de tudo o que você vai escrever é * * * * * com o minuto, a hora e um seletor de dias fixados. Aprenda a ordem dos campos, memorize os quatro operadores (* , - /), copie a tabela de receitas e incorpore a única regra que salva você de execuções misteriosas.

Resumo: Nunca restrinja ambos os campos de dia do mês e dia da semana, a menos que você realmente queira a lógica OR — e cole todas as suas expressões no Cron Parser para conferir os próximos horários reais de execução antes de subi-las para o servidor.

Continue lendo

ferramenta de desenvolvedor testador de regex e construtor de padrões — ilustração original da capa

design

Regex Tester & Pattern Builder: Um Guia Prático para Padrões que Realmente Funcionam

Como criar expressões regulares que realmente funcionam: âncoras, quantificadores, as armadilhas entre motores e o padrão ReDoS que pode travar seu servidor. Teste enquanto escreve.

9 min read

Notebook com código e planta em cafeteria

design

JSON vs YAML vs TOML: Quando Escolher Cada Um (Guia para Desenvolvedores)

JSON vs YAML vs TOML, sem mistério: JSON para APIs e dados, YAML para config de Kubernetes/CI (cuidado com o problema da Noruega), TOML para configurações explícitas como Cargo.toml. Um guia de decisão prático.

9 min read

Tudo começou com apenas HTML, CSS e um pouco de JavaScript.

design

Base64 Explicado: Quando e Por Que Desenvolvedores Usam (e as Armadilhas)

O que o Base64 faz (3 bytes viram 4 caracteres ASCII, +33% de tamanho), os casos de uso reais (data URIs, JWT, autenticação Basic auth) e as armadilhas: ele não é criptografia e nem compressão.

8 min read

Um código QR estilizado e escaneável em um fundo verde, ilustrando o design de um QR code personalizado com a marca

design

QR Codes com a Sua Marca: Como Adicionar Logo e Cores com um Gerador Gratuito

Como a correção de erros permite sobrepor um logo a um QR code, as regras de contraste e zona de silêncio para manter a leitura, e a pegadinha do estático versus dinâmico.

8 min read

Cartelas de amostras de cores com valores CMYK e RGB hex sendo usadas por um designer gráfico em sua mesa de trabalho

design

HEX para RGB e CMYK em 2026: Por que a cor de impressão nunca fica igual à da tela

Converter HEX para RGB é uma matemática exata. Já RGB para CMYK é um palpite imperfeito que depende da impressora, do papel e de um perfil ICC. Entenda a diferença, veja a matemática por trás disso e saiba onde um conversor online realmente ajuda.

8 min read

Primeiro plano da folha de adesivos do Google Material design em um MacBook.

design

Ferramentas de Paleta de Cores para Acessibilidade: Por Que a Maioria das Paletas Falha Antes de Você Publicar

83,6% das homepages falham em contraste. Como escolher ferramentas que verificam paletas acessíveis, evitam erros comuns e testam as combinações corretas.

9 min read