python django cron virtualenv

python - Cron y virtualenv



django (5)

Debería poder hacer esto usando python en su entorno virtual:

/home/my/virtual/bin/python /home/my/project/manage.py command arg

EDITAR: si su proyecto django no está en PYTHONPATH, deberá cambiar al directorio correcto:

cd /home/my/project && /home/my/virtual/bin/python ...

También puede intentar registrar el error de cron:

cd /home/my/project && /home/my/virtual/bin/python /home/my/project/manage.py > /tmp/cronlog.txt 2>&1

Otra cosa que manage.py probar es hacer el mismo cambio en tu script manage.py en la parte superior:

#!/home/my/virtual/bin/python

Estoy intentando ejecutar un comando de administración de Django desde cron. Estoy usando virtualenv para mantener mi proyecto aislado.

He visto ejemplos aquí y en otros lugares que muestran comandos de administración en ejecución desde virtualenv''s como:

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

Sin embargo, aunque syslog muestra una entrada cuando la tarea debería haber comenzado, esta tarea en realidad nunca se ejecuta (el archivo de registro para el script está vacío). Si ejecuto la línea manualmente desde el shell, funciona como se esperaba.

La única forma en que actualmente puedo obtener el comando para ejecutar a través de cron, es dividir los comandos y ponerlos en un script mudo bash wrapper:

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

EDITAR:

ars se le ocurrió una combinación de comandos que funciona:

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

Al menos en mi caso, invocar el script de activación para el virtualenv no hizo nada. Esto funciona, etc. con el espectáculo.


En lugar de perder el tiempo con shebangs específicos de virtualenv, simplemente anteponga PATH al crontab.

Desde un virtualenv activado, ejecute estos tres comandos y los scripts de python deberían funcionar:

$ echo "PATH=$PATH" > myserver.cron $ crontab -l >> myserver.cron $ crontab myserver.cron

La primera línea del crontab debería verse así:

PATH=/home/me/virtualenv/bin:/usr/bin:/bin: # [etc...]


La única forma correcta de ejecutar trabajos cron de python cuando se usa un virtualenv es activar el entorno y luego ejecutar el python del entorno para ejecutar el código.

Una forma de hacerlo es utilizar virtualenv''s activate_this en su script python, ver: http://virtualenv.readthedocs.org/en/latest/userguide.html#using-virtualenv-without-bin-python

Otra solución es hacer eco del comando completo, que incluye activar el entorno y conectarlo a /bin/bash . Considere esto para su /etc/crontab :

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


La ejecución de la source desde un archivo cron no funcionará ya que cron usa /bin/sh como su shell predeterminado, que no es compatible con la source . Necesita configurar la variable de entorno SHELL para que sea /bin/bash :

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

Es complicado detectar por qué esto falla, ya que /var/log/syslog no registra los detalles del error. Lo mejor es alias a la raíz para recibir un correo electrónico con cualquier error cron. Simplemente sendmail -bi a /etc/aliases sendmail -bi y ejecute sendmail -bi .

Más información aquí: http://codeinthehole.com/archives/43-Running-django-cronjobs-within-a-virtualenv.html


La mejor solución para mí fue para ambos

  • use el binario de python en el directorio / directorio venv
  • establece la ruta de Python para incluir el directorio de los módulos venv.

man python menciona la modificación de la ruta en shell en $PYTHONPATH o en python con sys.path

Otras respuestas mencionan ideas para hacer esto usando el caparazón. Desde python, agregar las siguientes líneas a mi script me permite ejecutarlo con éxito directamente desde cron.

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

Así es como se ve en una sesión interactiva:

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 >>>