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