Quando Jobs do Cron Nao Executam - Checklist de Troubleshooting
O que voce vai aprender
- Por que um script que funciona manualmente falha no cron
- Como confirmar falhas do cron pelos logs
- Como resolver as armadilhas comuns: PATH, ambiente, sintaxe de agendamento e permissoes
Resumo rapido (ordem de triagem)
Quase todo caso de "cron nao executa" se reduz a um destes cinco. Verifique de cima para baixo.
- O daemon do cron nao esta rodando
- Sem entrada de execucao nos logs (nunca foi iniciado)
- PATH errado (cron e um ambiente diferente do seu shell interativo)
- Variaveis de ambiente ausentes (
.bashrcnao e lido) - Sintaxe de agendamento, permissoes ou erros de final de linha
Premissas (ambiente alvo)
- SO: Ubuntu / Debian (pacote
cron, log em/var/log/syslog) - RHEL / CentOS usam servico
cronde log em/var/log/cron - Foco no crontab do usuario (
crontab -e)
Por que funciona manualmente mas nao no cron?
Conclusao: Diferente de um login interativo, o cron executa um shell nao-interativo que nunca le
.bashrc/.profilee mantem um PATH minimo. Essa diferenca de ambiente explica a maioria dos casos de "funciona manualmente, falha no cron".
Uma execucao manual (shell de login) e uma execucao no cron iniciam o shell por caminhos fundamentalmente diferentes.
| Item | Shell de login interativo | Job do cron |
|---|---|---|
| Arquivos de inicializacao lidos | .bash_profile / .bashrc, etc. |
nenhum |
PATH |
completo (inclui /usr/local/bin, etc.) |
minimo (frequentemente /usr/bin:/bin) |
HOME / LOGNAME |
definidos | parcialmente definidos |
| Diretorio de trabalho | onde voce esta | $HOME do usuario |
| Saida padrao | terminal | enviada por email (ou descartada) |
Uma vez que voce internalize essa diferenca, cada verificacao abaixo se torna "preencher o que falta no ambiente minimo do cron", um item por vez.
O daemon do cron esta rodando?
Conclusao: Primeiro confirme o daemon com
systemctl status cron. Se esta parado, nenhum job executa. Esta e a pre-condicao a descartar antes de qualquer outra coisa.
# Ubuntu / Debian $ systemctl status cron # RHEL / CentOS $ systemctl status crond
Se nao esta active (running), habilite e inicie.
$ sudo systemctl enable --now cron
O nome do servico difere por distribuicao: Ubuntu usa cron, familia RHEL usa crond. Se status diz Unit cron.service could not be found, tente o outro nome.
Como confirmar se executou pelos logs?
Conclusao: O cron registra no syslog toda vez que dispara. Se
grep CRON /var/log/syslognao mostra entrada, o job nunca foi iniciado.
A existencia ou nao de uma linha de log muda a direcao da sua triagem.
# Ubuntu / Debian $ grep CRON /var/log/syslog | tail -20 # Via journal do systemd $ journalctl -u cron --since "1 hour ago" # RHEL / CentOS $ sudo grep CRON /var/log/cron | tail -20
Um disparo bem-sucedido deixa uma linha como esta.
Jun 5 10:00:01 host CRON[12345]: (alice) CMD (/home/alice/backup.sh)
Como ler:
- Existe uma entrada -> o cron disparou. O problema esta no script (PATH / permissoes / ambiente). Prossiga para as proximas secoes.
- Sem entrada -> nunca foi iniciado. Suspeite de erro na sintaxe de agendamento, localizacao errada do crontab ou daemon parado.
Se nenhum log aparece no Ubuntu, rsyslog pode estar ausente ou parado (systemctl status rsyslog). Nesse caso use journalctl -u cron como fonte primaria.
Por que o PATH causa falha?
Conclusao: O PATH do cron e minimo (frequentemente
/usr/bin:/bin). Escreva comandos em/usr/local/bine similares com caminhos absolutos, ou defina PATH no topo do crontab.
"Funciona manualmente mas command not found no cron" quase sempre vem disso. Ha tres correcoes.
# 1) Usar caminho absoluto (encontrar com which) $ which node /usr/local/bin/node # No crontab, especificar o caminho absoluto * * * * * /usr/local/bin/node /home/alice/job.js
# 2) Definir PATH no topo do crontab PATH=/usr/local/bin:/usr/bin:/bin 0 * * * * node /home/alice/job.js
# 3) Exportar PATH dentro do script antes de executar #!/bin/bash export PATH=/usr/local/bin:/usr/bin:/bin node /home/alice/job.js
Capturar o ambiente real do cron e o metodo mais seguro. Adicione temporariamente a linha abaixo, depois faca diff do cronenv resultante contra seu shell.
* * * * * env > /tmp/cronenv 2>&1
$ diff <(env) /tmp/cronenv
Uma variavel de ambiente ausente e a causa?
Conclusao: O cron nao le
.bashrc/.profile. Jobs frequentemente falham porqueLANGou variaveis de runtime (NODE_ENV,JAVA_HOME, etc.) nao estao definidas.
Variaveis que seu shell interativo definiu implicitamente estao vazias no cron. Defini-las explicitamente no script e a correcao mais confiavel.
#!/bin/bash # Variaveis que tendem a nao estar definidas no ambiente do cron export LANG=en_US.UTF-8 export HOME=/home/alice export NODE_ENV=production cd "$HOME/app" || exit 1 /usr/local/bin/node index.js
Fazer source de ~/.bashrc dentro de um script do cron como workaround e fragil. A guarda "retornar imediatamente se nao-interativo" no topo do .bashrc (padrao do Ubuntu) pode impedir que qualquer coisa carregue. Exporte as variaveis que voce precisa individualmente.
Como encontrar erros de agendamento e sintaxe?
Conclusao: Sao cinco campos: minuto, hora, dia-do-mes, mes, dia-da-semana. O comportamento OR de dia/dia-da-semana e o
%sem escape sao as armadilhas classicas. Se nenhuma entrada de execucao aparece no log, suspeite da sintaxe primeiro.
+-- minuto (0-59) | +-- hora (0-23) | | +-- dia do mes (1-31) | | | +-- mes (1-12) | | | | +-- dia da semana (0-7, 0 e 7 sao domingo) | | | | | * * * * * comando a executar
Tropecos comuns:
%nao e literal: o cron transforma%em um comando em nova linha. Faca escape com barra invertida, ex. escrevadate +%Y-%m-%dcomodate +\%Y-\%m-\%d.- Dia e dia-da-semana ambos definidos:
0 0 1 * 1executa no "dia 1 ou segunda-feira" (um OR), nao no "dia 1 e segunda-feira". Isso facilmente diverge da intencao. - Sem comentarios no final da linha:
* * * * * cmd # notae invalido. Comentarios devem estar em sua propria linha com#.
crontab.guru e uma forma rapida de verificar o que um agendamento significa. Apos salvar, sempre re-verifique com crontab -l que foi armazenado como pretendido.
Verificar permissoes e localizacao do crontab
Conclusao: Um script sem permissao de execucao ou com caminho de shebang errado falha logo apos disparar. Ao colocar arquivos em
/etc/cron.d/, e facil esquecer que a linha precisa de um campo de usuario.
Permissao de execucao do script e shebang
$ chmod +x /home/alice/backup.sh $ head -1 /home/alice/backup.sh #!/bin/bash
Um script editado no Windows pode pegar finais de linha CRLF e falhar com bad interpreter. Veja Corrigindo "bad interpreter" para detalhes.
A sintaxe difere por tipo de crontab
| Localizacao | Campo de usuario | Uso |
|---|---|---|
crontab -e (usuario) |
nenhum | jobs pessoais |
/etc/crontab |
obrigatorio | sistema inteiro |
/etc/cron.d/<file> |
obrigatorio | pacotes / jobs extras |
# /etc/cron.d/ e /etc/crontab exigem um campo de usuario # +min +hr +dia +mes +dsem +usuario +comando 0 3 * * * alice /home/alice/backup.sh
Errar o campo de usuario e o log mostra um erro como bad username, ou o job silenciosamente nunca executa.
Como redirecionar saida para depuracao?
Conclusao: O cron envia saida padrao e erro padrao por email. Em hosts sem MTA, essa saida desaparece, entao redirecionar para arquivo torna os erros visiveis.
# Enviar stdout e stderr para um arquivo de log * * * * * /home/alice/backup.sh >> /tmp/backup.log 2>&1
2>&1 combina erro padrao no mesmo arquivo. Apos executar, /tmp/backup.log mantem as mensagens brutas de command not found ou Permission denied.
Reproducao minima
Quando voce nao consegue isolar a causa, primeiro confirme que o cron funciona com um job que apenas escreve a data a cada minuto.
* * * * * date >> /tmp/cron-test.log 2>&1
Se este log cresce, o cron esta saudavel e voce isolou o problema no script.