IT story

크론과 virtualenv

hot-time 2020. 5. 6. 21:04
반응형

크론과 virtualenv


cron에서 Django 관리 명령을 실행하려고합니다. 프로젝트를 샌드 박스로 유지하기 위해 virtualenv를 사용하고 있습니다.

여기와 다른 곳에서 virtualenv와 같은 관리 명령을 실행하는 예제를 보았습니다.

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

그러나 syslog가 태스크를 시작해야 할 때 항목을 표시하더라도이 태스크는 실제로 실행되지 않습니다 (스크립트의 로그 파일이 비어 있음). 쉘에서 수동으로 라인을 실행하면 예상대로 작동합니다.

현재 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에 대한 activate 스크립트를 호출해도 아무런 효과가 없습니다. 이것은 쇼와 함께 작동합니다.


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

실행 sourcecronfile에서하는 것은 크론 용도로 작동하지 않습니다 /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오류 세부 정보를 기록하지 않으므로 왜 이것이 실패하는지 알아내는 것은 까다 롭습니다 . cron 오류로 이메일을받을 수 있도록 루트에 자신을 알리는 것이 가장 좋습니다. 자신을 추가 /etc/aliases하고 실행 하기 만하면 sendmail -bi됩니다.

자세한 정보는 여기 : http://codeinthehole.com/archives/43-Running-django-cronjobs-within-a-virtualenv.html

위의 링크는 https://codeinthehole.com/tips/running-django-cronjobs-within-a-virtualenv/ 로 변경되었습니다.


더 이상 보지 마십시오 :

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

이것에 대한 아름다움은 SHELLcrontab에 대한 변수를에서 sh변경할 필요가 없다는 것입니다bash


virtualenv 특정 shebang을 사용하지 않고 PATHcrontab 앞에 추가 하십시오.

활성화 된 virtualenv에서 다음 세 가지 명령을 실행하면 Python 스크립트가 작동합니다.

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

crontab의 첫 줄은 다음과 같습니다 :

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

virtualenv를 사용할 때 python cron 작업을 실행하는 유일한 올바른 방법은 환경을 활성화 한 다음 환경의 python을 실행하여 코드를 실행하는 것입니다.

One way to do this is use virtualenv's activate_this in your python script, see: http://virtualenv.readthedocs.org/en/latest/userguide.html#using-virtualenv-without-bin-python

Another solution is echoing the complete command including activating the environment and piping it into /bin/bash. Consider this for your /etc/crontab:

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

The best solution for me was to both

  • use the python binary in the venv bin/ directory
  • set the python path to include the venv modules directory.

man python mentions modifying the path in shell at $PYTHONPATH or in python with sys.path

Other answers mention ideas for doing this using the shell. From python, adding the following lines to my script allows me to successfully run it directly from cron.

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

Here's how it looks in an interactive session --

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

I'd like to add this because I spent some time solving the issue and did not find an answer here for combination of variables usage in cron and virtualenv. So maybe it'll help someone.

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

It did not work well when it was configured like

DIR_SMTH="cd /smth && . venv/bin/activate"

Thanks @davidwinterbottom, @reed-sandberg and @mkb for giving the right direction. The accepted answer actually works fine until your python need to run a script which have to run another python binary from venv/bin directory.

참고URL : https://stackoverflow.com/questions/3287038/cron-and-virtualenv

반응형