크론과 virtualenv


227

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


내가 볼 수있는 한 가지 차이점은 스크립트가 현재 작업 디렉토리로 / home / user / project와 함께 manage.py를 실행한다는 것입니다. cron 명령은 홈 디렉토리를 cwd로 사용하여 실행됩니다. 로그 파일이 있습니까?
rettops

실제로 로그 경로는 절대적으로 정의되며 스크립트가 실행되고 있지 않기 때문에 단순히 생성 / 추가되지 않습니다.
John-Scott

크론 문제에 대한 신속하고 더러운 솔루션으로 (당신의 명령을 알수없는 작업하는) 환경을 덤프하는 것입니다 env그리고 export당신은 crontab에서 호출 랩퍼 떠들썩한 파티 스크립트에서 모두.
jberryman

답변:


250

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

1
그것은 또한 작동하지 않습니다. 작동하지 않는 것들을 내 목록에 넣는 것을 잊었다. 예, 셸에서 해당 명령을 수동으로 실행할 수 있지만 cron에서는 작동하지 않습니다.
John-Scott

~전체 경로로 교체 했습니까 ? (아마, 당신은 아마 ...)
ars

아, 당신은 실제 사례를 생각해 냈습니다! 모든 조합에 대해 시도했지만 virtualenv를 활성화해도 아무런 효과가없는 것으로 보입니다. .bashrc에 PYTHONPATH를 설정했지만 cron에서 사용하지 않는 것 같습니다. 답변을 강조하기 위해 내 질문을 업데이트하겠습니다.
John-Scott

그래, 나는 cron이 최소한의 환경에서 실행된다는 것을 잊었다. 일반적인 권장 사항은 작업에 필요한 환경을 설정하기 위해 bash 스크립트를 작성하는 것입니다. cron에서 bash 프로파일을 직접 소싱 할 수는 있지만 프로파일의 내용에 따라 미묘한 버그가 발생할 수 있습니다 (아마도 그러한 요구에 대해 별도의 최소한의 프로파일이 있으면 괜찮을 것입니다).
ars

7
테스트하는 좋은 방법은 / bin / sh를 실행 한 다음 거기서 명령을 실행하는 것입니다. 최소한 cron과 동일한 환경 설정이 필요합니다.
Dick

98

실행 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/ 로 변경되었습니다.


12
또는 '.' / dot / sh에 의해 지원되는 (점 명령). /path/to/virtualenv/bin/activate
Reed Sandberg

5
DavidWinterbottom, 그것이 당신의 진짜 이름이라면, 당신은 나의 영웅입니다. 나는 sh vs bash 및 소스 파일에 대해 결코 알지 못했습니다. 당신은 내 작은 bash-scripting world dude에 빛을 비췄습니다. 감사.
joemurphy

당신이있는 경우 postactivate파일을, 당신은 일을해야source /path/to/virtualenv/bin/activate && source /path/to/virtualenv/bin/postactivate
dspacejs

1
감사! 저에게는 Gerald의 대답이 아니라 작동합니다.
Martin Becker

1
'루트'란 무엇입니까? 누구나 설명 할 수 있습니다
adnanmuttaleb

19

더 이상 보지 마십시오 :

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


13

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

이를 수행하는 한 가지 방법은 activate_this파이썬 스크립트에서 virtualenv를 사용하는 것입니다 . 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

1
이것이 실제로 유일한 방법이라는 합의가 있는지 궁금합니다.
Aaron Schumacher

1
이것이 유일한 올바른 방법 일 것입니다. 그러나 작동하는 다른 방법이 있습니다.

4
이것은 "유일한 올바른 방법"이 아닙니다. cronjob을 virtualenv의 python 바이너리 (예 : '/ home / user / folder / env / bin / python')를 가리 키기 만하면 virtualenv에서 스크립트를 성공적으로 실행했습니다. 환경을 활성화 할 필요가 없습니다.
Canucklesandwich

가상 환경에서 사용자 정의 PYTHONPATH를 사용하면 env / bin / python이 작동하지 않습니다. 그래서 env / bin / activate를 사용하는 것이 더 좋습니다
varela

1
그것은 당신이 PYTHONPATH를 어떻게 설정 하느냐에 달려 있습니다. 그리고 당신이 그것을 venv "활성화"를 요구하는 방식으로 설정한다면, 당신은 잘못하고 있습니다

10

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

12
좋은 해결책이 아닙니다. crontab의 모든 python 작업은 virtualenv의 바이너리로 실행됩니다. 이 바이너리를 의사 글로벌 파이썬으로 만드는 것은 virtualenv의 목적에 위배됩니다.
Victor Schröder

4

나에게 가장 좋은 해결책은

  • venv bin / 디렉토리에서 python 바이너리를 사용하십시오.
  • venv 모듈 디렉토리를 포함하도록 Python 경로를 설정하십시오.

man python쉘에서 $PYTHONPATH또는 파이썬 에서 경로를 수정하는 것을 언급합니다.sys.path

다른 답변은 셸을 사용 하여이 작업을 수행하기위한 아이디어를 언급합니다. 파이썬에서 다음 줄을 스크립트에 추가하면 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
>>>

4

문제를 해결하는 데 시간이 걸리고 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 / activate"

올바른 방향을 제시해@davidwinterbottom , @ reed-sandberg@mkb 에게 감사 합니다. 받아 들여진 대답은 실제로 파이썬이 venv / bin 디렉토리에서 다른 파이썬 바이너리를 실행 해야하는 스크립트를 실행해야 할 때까지 정상적으로 작동합니다.


0

이것은 나를 위해 잘 작동 한 솔루션입니다.

source /root/miniconda3/etc/profile.d/conda.sh && \
conda activate <your_env> && \
python <your_application> &

Ubuntu 18.04.3 LTS에서 Conda 버전 4.7.12와 함께 miniconda를 사용하고 있습니다.

위의 스크립트를 스크립트 안에 넣고 문제없이 crontab을 통해 실행할 수 있습니다.


0

파이썬 스크립트

from datetime import datetime                                                                                                                                                                
import boto   # check wheather its taking the virtualenv or not                                                                                                                                                                        
import sys                                                                                                                                                                                   
param1=sys.argv[1]     #Param                                                                                                                                                                                                                                                                                                                                                                    
myFile = open('appendtxt.txt', 'a')                                                                                                                                                      
myFile.write('\nAccessed on ' + param1+str(datetime.now())) 

크론 명령

 */1 * * * *  cd /Workspace/testcron/ && /Workspace/testcron/venvcron/bin/python3  /Workspace/testcron/testcronwithparam.py param  

위 명령에서

  • * / 1 * * * * -1 분마다 실행
  • cd / Workspace / testcron / -파이썬 스크립트의 경로
  • / Workspace / testcron / venvcron / bin / python3 -Virtualenv 경로
  • 작업 공간 /testcron/testcronwithparam.py- 파일 경로
  • param- 매개 변수
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.