O trabalho do Cron falha silenciosamente

4

Eu tenho um script python que quero rodar via crontab. Meu crontab é assim:

5,20,35,50 * * * * /var/www/django-apps/callreport/util.py

Esse script é configurado para analisar um monte de arquivos simples e colocar as informações em um banco de dados MySQL e, em seguida, excluir os arquivos. Ele corre bem a partir da linha de comando, os dados são copiados para o banco de dados e os arquivos simples são removidos. Mas nada acontece quando configurado para ser executado como um trabalho cron.

No passado, eu recebia uma mensagem de e-mail quando uma tarefa cron falhava, mas não estou recebendo nenhum feedback com essa, e ainda estou sentindo o caminho a ser um administrador de sistema nesta caixa. O que estou fazendo errado?

    
por saturdayplace 18.08.2009 / 17:57

11 respostas

7

O problema usual com os trabalhos 'cron' é que eles têm um ambiente zero - ao contrário dos trabalhos 'at' que copiam seu ambiente. Quando algo funciona a partir da linha de comando e não do 'cron', minha experiência é que 'ambiente' é um dos problemas mais comuns. Ocasionalmente, você se depara com outro problema - as tarefas 'cron' não são executadas com um terminal e, ocasionalmente, os programas são afetados por isso. No entanto, isso está na faixa de 1% em comparação com 99% para problemas ambientais.

A outra técnica chave que uso é sempre executar um script de shell a partir do 'cron'; o shell script garante que o ambiente esteja configurado corretamente e, em seguida, execute o programa real. Se um trabalho 'cron' está me dando problemas, posso ajustar o script para fazer coisas úteis como esta:

{
    date
    env | sort
    set -x
    ...what was there before adding the debug...
} >/tmp/cron.jobname.$$ 2>&1

Isso redireciona toda a saída padrão de saída e erro padrão para um nome de arquivo. Você pode criar registros de data e hora no nome do arquivo, se preferir, ao ID do processo. Analisar os arquivos de log geralmente revela os problemas rapidamente.

    
por 19.10.2009 / 07:58
2

Primeiro, apenas verifique se o crond está sendo executado.

Quando os cronjobs que funcionam na linha de comando não são executados como esperado, geralmente é um problema de ambiente para mim - lembre-se de que o cronjob não estará sendo executado como um shell interativo.

Da sua linha de comando, execute env (1) e copie-os em algum lugar. Em seguida, modifique seu cronjob para executar env para comparar os valores. Cron deve mandar por e-mail a saída (você disse que era antes); HD mencionou como configurar isso.

5,20,35,50 * * * * env; /var/www/django-apps/callreport/util.py
    
por 18.08.2009 / 18:53
2

Estas são algumas ideias para resolver o seu problema:

  • Verifique seus logs do sistema para ver se o daemon do cron está realmente iniciando o script
  • Se suas tarefas não estiverem sendo registradas, tente aumentar o nível de registro para que você que cron registre o início de cada tarefa (consulte man cron ). Por exemplo, se você estiver executando o daemon do Vixie cron, isso pode ser feito especificando a opção -L 1 (ou -L 2 se você também quiser verificar quando sua tarefa é concluída).
  • A partir do seu script Python, assim que ele for iniciado, crie um arquivo vazio no diretório / tmp (essa é outra maneira de ajudá-lo a verificar se o script está sendo chamado pelo cron e está sendo iniciado sem problemas)
por 18.08.2009 / 18:54
2

whereis python

saída deve ser ...

/ usr / bin / python

então o caminho completo para python antes do script.

5,20,35,50 * * * * / usr / bin / python /var / www / django-apps/callreport/util.py

    
por 18.08.2009 / 18:55
0

Acho que você pode redirecionar a saída do comando para um arquivo para ver por que ele está falhando, algo como

/var/www/django-apps/callreport/util.py > /tmp/util_log.txt

a maioria dos casos que eu vi para falha silenciosa é porque o script não pode ser executado e não um problema com o próprio script

    
por 18.08.2009 / 18:03
0

Você pode colocar esta linha no topo do seu crontab:

MAILTO="[email protected]"

Para receber um email do cron. Além disso, você pode redirecionar a saída para uma falha temporária, como Dinesh Manne diz para verificar o que aconteceu com o seu comando. Apenas perguntando: tem certeza de que você está usando o usuário que está executando o comando é o mesmo que o proprietário do crontab que você está editando?

    
por 18.08.2009 / 18:23
0

Tenha certeza absoluta de que o seu crond roda scripts com um ponto no nome do arquivo ...!

    
por 07.09.2009 / 02:32
0

Além disso, verifique se o seu usuário não está no arquivo cron.deny . Se você quiser que apenas cron seja executado para determinadas pessoas, adicione seu usuário a cron.allow .

    
por 07.09.2009 / 03:20
0

Força a falha. Coloque algo errado em vez de #! / Usr / bin / python e verifique se você recebe um relatório de erro por e-mail - você deve configurar a variável MAILTO para o seu endereço de e-mail. Mas verifique primeiro se os scripts realmente falharão se você executá-lo a partir da linha de comando. Se você ainda não receber um erro de e-mail, verifique se alguns e-mails estão presos na fila de mensagens local ( mailq ). Talvez isso ajude a descobrir o fracasso silencioso.

Além disso, em quais sistemas internos esse script depende? DNS, ldap / nis? Possui algum endereço IP ou nome de host que não existe mais (ou seja, host mysql)? Você pode correlacionar a última vez que foi executado com sucesso com a última alteração feita no script? Alguém fez uma atualização furtiva para python na sua máquina? Você tem espaço suficiente em disco e indoes (df -i)?

Você tem uma linha vazia no final do seu arquivo crontab? Se você forçar o script a ser executado como root (ruim, use-o apenas para testes) isso funciona?

    
por 19.10.2009 / 05:54
0

Você tem esse trabalho no crontab de um usuário (você pode vê-lo com crontab -l ?) ou está no crontab do sistema ( /etc/crontab )? O sistema crontab (Pelo menos no linux, não sei sobre outros sistemas) requer um argumento de usuário adicional que os crontabs do usuário não possuem.

Em um crontab específico do usuário, ele deve se parecer com:

# crontab -l
...
5,20,35,50 * * * * /var/www/django-apps/callreport/util.py

Considerando que o mesmo comando no crontab do sistema deve ser semelhante:

# cat /etc/crontab
...
5,20,35,50 * * * * www-data /var/www/django-apps/callreport/util.py

O usuário pode ser diferente em seu sistema, é claro, mas essa é a ideia geral.

    
por 19.10.2009 / 06:12
0

Parece que você já verificou, mas verifique se o script está sendo executado como o usuário correto. Quando eu trabalho defeitos agendam trabalhos, eu gosto de usar (no meu mac) chamadas de sistema usando o comando say de modo que eu ouço os parâmetros em que eu estou interessado. Assim eu poderia adicionar a util.py o seguinte:

import os
os.system('whoami')

Além disso, eu colocaria meu dinheiro em um problema de permissão; seu cron job pode não ser capaz de fazer as coisas que você pede, porque as permissões não permitem isso.

    
por 07.09.2009 / 02:01

Tags