308 votes

Cron et virtualenv

Je suis en train de lancer un Django de commande de gestion de cron. Je suis à l'aide de virtualenv pour garder mon projet de bac à sable.

J'ai vu des exemples d'ici et d'ailleurs qui montrent l'exécution de la gestion des commandes à partir de virtualenv est comme:

0 3 * * * source /home/user/project/env/bin/activate && /home/user/project/manage.py command arg

Cependant, même si syslog montre d'une entrée si la tâche doit avoir commencé, cette tâche n'a jamais vraiment fonctionne (le fichier journal pour le script est vide). Si j'exécute la ligne manuellement à partir du shell, il fonctionne comme prévu.

La seule façon que je peux actuellement obtenir l'exécution de la commande via cron, est de briser les commandes et les mettre dans un muet bash script:

#!/bin/sh
source /home/user/project/env/bin/activate
cd /home/user/project/
./manage.py command arg

Merci de m'éclairer quelle est la différence. Ce qui me manque?

Merci

EDIT:

ars est venu avec une combinaison de commandes:

0 3 * * * cd /home/user/project && /home/user/project/env/bin/python /home/user/project/manage.py command arg

Au moins dans mon cas, en invoquant l'activer script pour le virtualenv n'a rien fait. Cela fonctionne, donc le spectacle.

328voto

ars Points 35803

Vous devriez être en mesure de le faire en utilisant le `` dans votre environnement virtuel :

EDIT : Si votre projet django ne figure pas dans la PYTHONPATH, alors vous aurez besoin basculer vers le bon répertoire :

Vous pouvez également essayer de connecter l’échec de cron :

Une autre chose à essayer est d’apporter la même modification dans votre `` script tout en haut :

127voto

DavidWinterbottom Points 2632

L'exécution source d'un cronfile ne fonctionne pas comme cron utilise /bin/sh comme shell par défaut, qui ne prend pas en charge source. Vous devez configurer le SHELL variable d'environnement /bin/bash:

SHELL=/bin/bash
*/10 * * * * root source /path/to/virtualenv/bin/activate && /path/to/build/manage.py some_command > /dev/null

Il est difficile de repérer pourquoi cela échoue car /var/log/syslog ne vous connectez pas les détails de l'erreur. Mieux alias vous-même à la racine de sorte que vous obtenez par courriel avec toute cron erreurs. Simplement ajouter vous-même à l' /etc/aliases et exécutez sendmail -bi.

Plus d'infos ici: http://codeinthehole.com/archives/43-Running-django-cronjobs-within-a-virtualenv.html

17voto

Ivanhoe Points 185

Bien que c'est un enfant de 3 ans post la réponse est encore utilisé donc voici mes 2 cents.

La seule façon correcte de lancer python cronjobs - lors de l'utilisation d'un virtualenv - est de l'activer à l'environnement, puis d'exécuter l'environnement python pour exécuter votre code.

Une façon de faire cela est d'utiliser virtualenv est activate_this dans votre script python, voir: http://www.virtualenv.org/en/latest/virtualenv.html#using-virtualenv-without-bin-python

Une autre solution est l'écho de la commande complète, y compris l'activation de l'environnement et de la tuyauterie en /bin/bash pris en compte pour votre /etc/crontab:

***** root echo 'source /env/bin/activate; python /your/script' | /bin/bash

10voto

joemaller Points 2349

Plutôt que bidouillent avec virtualenv spécifiques shebang, juste ajouter `` sur la crontab.

Dans un virtualenv activé, exécuter ces trois commandes et scripts python devraient fonctionner :

Première ligne de la crontab devrait maintenant ressembler à ceci :

4voto

here Points 458

La meilleure solution pour moi a été à la fois

  • utiliser le python binaire dans le venv le répertoire bin/
  • définir le python path pour inclure le venv le répertoire des modules.

man python mentions modifiant le chemin de la coquille à l' $PYTHONPATH ou en python, avec sys.path

D'autres réponses mentionnent des idées pour ce faire, l'utilisation de la coque. À partir de python, en ajoutant les lignes suivantes dans mon script me permet de réussir à le lancer directement à partir de cron.

import sys
sys.path.insert(0,'/path/to/venv/lib/python3.3/site-packages');

Voici à quoi il ressemble dans une session interactive --

Python 3.3.2+ (default, Feb 28 2014, 00:52:16) 
[GCC 4.8.1] on linux
Type "help", "copyright", "credits" or "license" for more information.

>>> import sys

>>> sys.path
['', '/usr/lib/python3.3', '/usr/lib/python3.3/plat-x86_64-linux-gnu', '/usr/lib/python3.3/lib-dynload']

>>> import requests
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named 'requests'   

>>> sys.path.insert(0,'/path/to/venv/modules/');

>>> import requests
>>>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X