크론과 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
실행 source
cronfile에서하는 것은 크론 용도로 작동하지 않습니다 /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
이것에 대한 아름다움은 SHELL
crontab에 대한 변수를에서 sh
로 변경할 필요가 없다는 것입니다bash
virtualenv 특정 shebang을 사용하지 않고 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...]
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
'IT story' 카테고리의 다른 글
리스트의 사전을 만드는 파이썬 (0) | 2020.05.06 |
---|---|
Python Pandas : 특정 값과 일치하는 열의 색인을 가져옵니다. (0) | 2020.05.06 |
모든 개발자는 데이터베이스에 대해 무엇을 알아야합니까? (0) | 2020.05.06 |
CTOR의 의미는 무엇입니까? (0) | 2020.05.06 |
matplotlib을 사용하여 이미지를 회색조로 표시 (0) | 2020.05.06 |