Por que os scripts crontab não estão funcionando?

Por que os scripts crontab não estão funcionando?

Freqüentemente, crontabos scripts não são executados dentro do cronograma ou conforme esperado. Existem inúmeras razões para isso:

  1. notação crontab errada
  2. problema de permissões
  3. variáveis ​​ambientais

Este wiki da comunidade tem como objetivo agregar os principais motivos pelos quais crontabos scripts não são executados conforme o esperado. Escreva cada motivo em uma resposta separada.

Inclua um motivo por resposta - detalhes sobre o motivo pelo qual não foi executado - e as correções para esse motivo.

Por favor, escreva apenas questões específicas do cron, por exemplo, comandos que são executados conforme esperado no shell, mas executados erroneamente pelo cron.

Responder1

Ambiente diferente

O Cron passa um conjunto mínimo de variáveis ​​de ambiente para seus trabalhos. Para ver a diferença, adicione um trabalho fictício como este:

* * * * * env > /tmp/env.output

Aguarde /tmp/env.outputa criação e remova o trabalho novamente. Agora compare o conteúdo de /tmp/env.outputcom a saída de envrun em seu terminal normal.

Uma "pegadinha" comum aqui é a PATHvariável de ambiente ser diferente. Talvez o seu script cron use o comando somecommandencontrado em /opt/someApp/bin, ao qual você adicionou PATHem /etc/environment? O cron ignora PATHesse arquivo, portanto, a execução somecommanddo seu script falhará quando executada com o cron, mas funcionará quando executada em um terminal. É importante notar que as variáveis ​​from /etc/environmentserão passadas para os cron jobs, mas não as variáveis ​​que o cron define especificamente, como PATH.

Para contornar isso, basta definir sua própria PATHvariável no topo do script. Por exemplo

#!/bin/bash
PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# rest of script follows

Alguns preferem usar apenas caminhos absolutos para todos os comandos. Eu recomendo contra isso. Considere o que acontece se você quiser executar seu script em um sistema diferente e, nesse sistema, o comando estiver ativado /opt/someAppv2.2/bin. Você teria que passar por todo o script substituindo /opt/someApp/binpor /opt/someAppv2.2/binem vez de apenas fazer uma pequena edição na primeira linha do script.

Você também pode definir a variável PATH no arquivo crontab, que será aplicada a todos os cron jobs. Por exemplo

PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

15 1 * * * backupscript --incremental /home /root

Responder2

Minha principal pegadinha: se você esquecer de adicionar uma nova linha no final do crontabarquivo. Em outras palavras, o arquivo crontab deve terminar com uma linha vazia.

Abaixo está a seção relevante nas páginas de manual para este problema ( man crontabpule para o final):

   Although cron requires that each entry in a crontab end  in  a  newline
   character,  neither the crontab command nor the cron daemon will detect
   this error. Instead, the crontab will appear to load normally. However,
   the  command  will  never  run.  The best choice is to ensure that your
   crontab has a blank line at the end.

   4th Berkeley Distribution      29 December 1993               CRONTAB(1)

Responder3

O daemon Cron não está em execução. Eu realmente estraguei tudo isso há alguns meses.

Tipo:

pgrep cron 

Se você não vir nenhum número (ou seja, o PID principal do cron), então o cron não está em execução. sudo /etc/init.d/cron startpode ser usado para iniciar o cron.

EDIT: Em vez de invocar scripts de inicialização através de /etc/init.d, use o utilitário de serviço, por exemplo

sudo service cron start

EDIT: Você também pode usar systemctl no Linux moderno, por exemplo

sudo systemctl start cron

Responder4

Em muitos ambientes, o cron executa comandos usando sh, enquanto muitas pessoas presumem que ele usará bash.

Sugestões para testar ou corrigir isso para um comando com falha:

  • Tente executar o comando shpara ver se funciona:

    sh -c "mycommand"
    
  • Envolva o comando em um subshell bash para garantir que ele seja executado no bash:

    bash -c "mybashcommand"
    
  • Diga ao cron para executar todos os comandos no bash configurando o shell na parte superior do seu crontab:

    SHELL=/bin/bash
    
  • Se o comando for um script, certifique-se de que o script contenha um shebang:

    #!/bin/bash
    

informação relacionada