Cron и virtualenv - PullRequest
       71

Cron и virtualenv

195 голосов
/ 20 июля 2010

Я пытаюсь запустить команду управления Django из cron.Я использую virtualenv, чтобы сохранить свой проект в изолированной среде.

Я видел здесь и в других примерах примеры запуска команд управления изнутри virtualenv, например:

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

Однако, хотя в системном журнале есть записькогда задача должна была начаться, эта задача фактически никогда не запускается (файл журнала для скрипта пуст).Если я запускаю строку вручную из оболочки, она работает как положено.

Единственный способ получить команду для запуска через cron - это разбить команды на части и поместить их в сценарий оболочки тупого bash:

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

РЕДАКТИРОВАТЬ:

ars придумали рабочую комбинацию команд:

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

По крайней мере, в моем случае вызов сценария активации для virtualenv ничего не сделал.Это работает, так и с шоу.

Ответы [ 7 ]

221 голосов
/ 20 июля 2010

Вы можете сделать это, используя python в своей виртуальной среде:

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

РЕДАКТИРОВАТЬ: если ваш проект django не находится в PYTHONPATH, вам нужно переключиться на правильный каталог:

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

Вы также можете попытаться зарегистрировать ошибку из cron:

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

Еще одна попытка - внести те же изменения в скрипт manage.py в самом верху:

#!/home/my/virtual/bin/python
84 голосов
/ 11 августа 2011

Запуск source из cronfile не будет работать, поскольку cron использует /bin/sh в качестве оболочки по умолчанию, которая не поддерживает source.Необходимо установить переменную среды SHELL равной /bin/bash:

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

Сложно определить причину сбоя, поскольку /var/log/syslog не регистрирует подробности ошибки.Лучше всего использовать псевдоним root, чтобы получать по электронной почте сообщения об ошибках cron.Просто добавьте себя в /etc/aliases и запустите sendmail -bi.

Подробнее здесь: http://codeinthehole.com/archives/43-Running-django-cronjobs-within-a-virtualenv.html

10 голосов
/ 12 декабря 2012

Вместо того, чтобы дурачиться с помощью виртуозных шебангов, просто добавьте PATH к crontab.

Из активированного virtualenv запустите эти три команды, и сценарии Python должны просто работать:

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

Первая строка crontab теперь должна выглядеть так:

PATH=/home/me/virtualenv/bin:/usr/bin:/bin:  # [etc...]
9 голосов
/ 28 мая 2018

Не смотрите дальше:

0 3 * * * /usr/bin/env bash -c 'cd /home/user/project && source /home/user/project/env/bin/activate && ./manage.py command arg' > /dev/null 2>&1

Общий подход:

* * * * * /usr/bin/env bash -c 'YOUR_COMMAND_HERE' > /dev/null 2>&1

Прелесть этого в том, что вам НЕ нужно изменять переменную SHELL для crontab сsh до bash

9 голосов
/ 29 марта 2014

Единственный правильный способ запуска заданий Python cron при использовании virtualenv - это активировать среду и затем запустить python среды для запуска вашего кода.

Один из способов сделать это - использовать activate_this в virtualenvваш скрипт на python, см .: http://virtualenv.readthedocs.org/en/latest/userguide.html#using-virtualenv-without-bin-python

Еще одно решение - отображение всей команды, включая активацию среды и передачу ее в /bin/bash.Рассмотрим это для вашего /etc/crontab:

***** root echo 'source /env/bin/activate; python /your/script' | /bin/bash
3 голосов
/ 25 апреля 2014

Лучшим решением для меня было то, чтобы оба

  • использовали двоичный файл python в каталоге venv bin / directory
  • , чтобы указать путь python для включения каталога модулей venv.

man python упоминает об изменении пути в оболочке в $PYTHONPATH или в python с помощью sys.path

В других ответах упоминаются идеи сделать это с помощью оболочки.Из python добавление следующих строк в мой скрипт позволяет мне успешно запускать его прямо из cron.

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

Вот как это выглядит в интерактивном сеансе -

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
>>>
2 голосов
/ 08 августа 2018

Я хотел бы добавить это, потому что я потратил некоторое время на решение проблемы и не нашел здесь ответа на вопрос об использовании комбинации переменных в cron и virtualenv. Так что, может быть, это кому-нибудь поможет.

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DIR_SMTH="cd /smth"
VENV=". venv/bin/activate"
CMD="some_python_bin do_something"
# m h  dom mon dow   command
0 * * * * $DIR_SMTH && $VENV && $CMD -k2 some_target >> /tmp/crontest.log 2>&1

Он не работал хорошо, когда он был настроен как

DIR_SMTH = "cd / smth &&. Venv / bin / activ"

Спасибо @ davidwinterbottom , @ reed-sandberg и @ mkb за правильное направление. Принятый ответ на самом деле работает нормально, пока вашему питону не понадобится запустить скрипт, который должен запускать другой двоичный файл питона из каталога venv / bin.

...