क्रोन और virtualenv


227

मैं क्रोन से एक Django प्रबंधन कमांड चलाने की कोशिश कर रहा हूं। मैं अपने प्रोजेक्ट को सैंडबॉक्स करने के लिए virtualenv का उपयोग कर रहा हूं।

मैंने यहाँ और अन्य जगहों के उदाहरण देखे हैं जो कि virtualenv के अंदर से रनिंग मैनेजमेंट कमांड दिखाते हैं:

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

हालाँकि, भले ही syslog एक प्रविष्टि दिखाता है जब कार्य शुरू होना चाहिए था, यह कार्य वास्तव में कभी नहीं चलता है (स्क्रिप्ट के लिए लॉग फ़ाइल खाली है)। यदि मैं शेल से मैन्युअल रूप से लाइन चलाता हूं, तो यह अपेक्षित रूप से काम करता है।

जिस तरह से मैं वर्तमान में क्रोन के माध्यम से चलाने के लिए कमांड प्राप्त कर सकता हूं, वह है कमांड्स को तोड़ना और उन्हें गूंगा बैश रैपर स्क्रिप्ट में डालना:

#!/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 के लिए सक्रिय स्क्रिप्ट को लागू करने से कुछ नहीं हुआ। यह काम करता है, इसलिए शो के साथ।


एक अंतर जो मैं देख रहा हूं, वह यह है कि स्क्रिप्ट मौजूदा वर्किंग डायरेक्टरी के रूप में / होम / यूजर / प्रोजेक्ट के साथ मैनेजमेन्ट चलेगी। आपका क्रोन कमांड आपके होम डायरेक्टरी के साथ cwd के रूप में चलाया जाएगा। शायद लॉग फ़ाइल है?
बजे

वास्तव में लॉग पथ बिल्कुल परिभाषित है, यह केवल इसलिए नहीं बनाया गया है / क्योंकि स्क्रिप्ट नहीं चल रही है।
जॉन-स्कॉट

क्रोन मुद्दों का एक त्वरित और गंदा समाधान आपके पर्यावरण (जिसमें आपका आदेश बेवजह काम कर रहा है) को डंप करना है envऔर exportउन सभी को एक बैश स्क्रिप्ट रैपर में आप क्रॉस्टब से कॉल करते हैं।
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 ...

आप क्रोन से विफलता को लॉग इन करने का भी प्रयास कर सकते हैं:

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
वह भी काम नहीं करता है। मेरी उन चीजों की सूची में रखना भूल गए जो काम नहीं करती हैं। हां, मैं उस कमांड को शेल में मैन्युअल रूप से चला सकता हूं लेकिन यह क्रोन से काम नहीं करता है।
जॉन-स्कॉट

क्या आपने ~पूरा रास्ता बदल दिया ? (आप शायद ही किया, बस सुनिश्चित करने के ...)
आर्स

आह, आप एक काम के उदाहरण के साथ आए हैं! मैंने हर संयोजन के बारे में कोशिश की है और virtualenv को सक्रिय करने से कोई प्रभाव नहीं पड़ता है। मैं अपने PYTHONPATH को .bashrc में सेट करता हूं लेकिन यह जाहिरा तौर पर क्रॉन द्वारा उपयोग नहीं किया जाता है? आपके उत्तर को उजागर करने के लिए मेरे प्रश्न को अपडेट करेगा।
जॉन-स्कॉट

हाँ, मैं भूल गया कि क्रोन बहुत ही न्यूनतम वातावरण में चलता है। सामान्य अनुशंसा यह है कि आपकी नौकरी के लिए जिस भी वातावरण की आवश्यकता होगी, उसे सेट करने के लिए बैश स्क्रिप्ट लिखें। आप सीधे क्रश में बैश प्रोफाइल को सोर्स करने की कोशिश कर सकते हैं, लेकिन इससे सूक्ष्म कीड़े हो सकते हैं जो आपके प्रोफाइल में क्या है (शायद अगर आपके पास ऐसी ज़रूरतों के लिए एक अलग और न्यूनतम प्रोफ़ाइल है, तो यह ठीक होगा)।
ars

7
परीक्षण करने का एक अच्छा तरीका / बिन / श को निष्पादित करना है, और फिर वहां से अपनी कमांड निष्पादित करने का प्रयास करना है। कम से कम आपके पास क्रोन के समान पर्यावरण सेटअप होगा।
डिक

98

sourceक्रोनफाइल से रनिंग काम नहीं करेगी क्योंकि क्रोन /bin/shअपने डिफ़ॉल्ट शेल के रूप में उपयोग करता है , जो समर्थन नहीं करता है source। आपको होना चाहिए शेल पर्यावरण चर सेट करने के लिए /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त्रुटि विवरण लॉग नहीं करता है। अपने आप को रूट करने के लिए सबसे अच्छा है ताकि आप किसी भी क्रोन त्रुटियों के साथ ईमेल करें। बस अपने आप को जोड़ने /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
या '।' (डॉट कमांड), जो समर्थित है / बिन / श. /path/to/virtualenv/bin/activate
रीड सैंडबर्ग

5
डेविडवर्थबॉटम, अगर यह आपका असली नाम है, तो आप मेरे हीरो हैं। मुझे नहीं पता था कि श बनाम बश और स्रोत फ़ाइलों के बारे में। आपने मेरी छोटी-सी बैश-स्क्रिप्टिंग दुनिया में एक प्रकाश डाला है। धन्यवाद।
जोमेर्फी

यदि आपके पास कोई postactivateफ़ाइल है, तो आपको ऐसा करना चाहिएsource /path/to/virtualenv/bin/activate && source /path/to/virtualenv/bin/postactivate
dspacejs

1
धन्यवाद! मेरे लिए, यह जेराल्ड द्वारा स्वीकृत उत्तर के बजाय काम करता है।
मार्टिन बेकर

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

इसके बारे में सुंदरता यह है कि आपको SHELLकोंट्राब से चर को बदलने की आवश्यकता नहीं shहैbash


13

एक virtualenv का उपयोग करते समय अजगर क्रोन नौकरियों को चलाने का एकमात्र सही तरीका पर्यावरण को सक्रिय करना है और फिर अपने कोड को चलाने के लिए पर्यावरण के अजगर को निष्पादित करना है।

ऐसा करने का एक तरीका यह है कि activate_thisआप अपने python स्क्रिप्ट में 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
मैं इस बात पर बहुत उत्सुक हूं कि क्या आम सहमति है कि यह वास्तव में एकमात्र सही तरीका है।
एरोन शूमाकर

1
यह शायद एकमात्र सही तरीका है। लेकिन ऐसे अन्य तरीके हैं जो काम करते हैं।
विल

4
यह "एकमात्र सही तरीका नहीं है।" मैंने एक वर्चुअन में स्क्रिप्ट को सफलतापूर्वक निष्पादित किया है क्रोनजॉब को वर्चुअन के पाइथन बाइनरी को इंगित करता है, जैसे कि '/ home / user / folder / env / bin / python'। पर्यावरण को सक्रिय करने की आवश्यकता नहीं है।
Canucklesandwich

यदि आप वर्चुअल वातावरण में कस्टम PYTHONPATH का उपयोग करते हैं तो env / bin / python आपके लिए काम नहीं करेगा। इसीलिए env / bin / activate का प्रयोग बेहतर है
varela

1
यह इस बात पर निर्भर करता है कि आपने PYTHONPATH को कैसे सेट किया है और यदि आप इसे इस तरीके से सेट करते हैं, जिसमें आपको vev को "सक्रिय" करने की आवश्यकता होती है, तो आप इसे गलत कर रहे हैं

10

वर्चुअनव-विशिष्ट शेबंग के साथ घूमने के बजाय, बस कॉन्टैब PATHपर चलें ।

एक सक्रिय virtualenv से, इन तीन आदेशों को चलाने और अजगर लिपियों को बस काम करना चाहिए:

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

Crontab की पहली पंक्ति अब इस तरह दिखनी चाहिए:

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

12
अच्छा समाधान नहीं। Crontab में हर अजगर कार्य फिर virtualenv से बाइनरी के साथ चलेगा। उस द्विआधारी को एक छद्म वैश्विक अजगर बनाना वर्चुअन के उद्देश्य के खिलाफ जाता है।
विक्टर श्रोडर

4

मेरे लिए सबसे अच्छा समाधान दोनों के लिए था

  • अजगर बिन / निर्देशिका में बाइनरी का उपयोग करें
  • अजगर मॉड्यूल निर्देशिका को शामिल करने के लिए अजगर पथ सेट करें।

man pythonमें $PYTHONPATHया पर अजगर के साथ खोल में पथ को संशोधित करने का उल्लेख हैsys.path

अन्य उत्तर शेल के उपयोग से ऐसा करने के विचारों का उल्लेख करते हैं। अजगर से, मेरी स्क्रिप्ट में निम्नलिखित पंक्तियों को जोड़ने से मुझे इसे सफलतापूर्वक क्रोन से सीधे चलाने की अनुमति मिलती है।

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

मैं इसे जोड़ना चाहता हूं क्योंकि मैंने इस मुद्दे को हल करने में कुछ समय बिताया और क्रोन और वर्चुअलाइज में चर के उपयोग के संयोजन के लिए यहां कोई उत्तर नहीं मिला। तो शायद यह किसी की मदद करेंगे।

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 / सक्रिय"

धन्यवाद @davidwinterbottom , @ ईख-सैंडबर्ग और @mkb सही दिशा देने के लिए। स्वीकृत उत्तर वास्तव में ठीक काम करता है जब तक कि आपके अजगर को एक स्क्रिप्ट चलाने की आवश्यकता नहीं होती है जिसे वेव या बिन डायरेक्टरी से एक और पायथन बाइनरी चलाना होता है।


0

यह एक ऐसा समाधान है जिसने मेरे लिए अच्छा काम किया है।

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

मैं एक Ubuntu 18.04.3 LTS पर कॉनडा संस्करण 4.7.12 के साथ मिनीकोन्डा का उपयोग कर रहा हूं।

मैं एक स्क्रिप्ट के अंदर ऊपर रखने में सक्षम हूं और बिना किसी परेशानी के इसे कॉट्रैब के माध्यम से चलाता हूं।


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 * * * * - हर एक टकसाल निष्पादित करें
  • cd / कार्यक्षेत्र / testcron / - अजगर स्क्रिप्ट का पथ
  • / कार्यक्षेत्र / टेस्टक्रॉन / वेनेरिक्रोन / बिन / पायथन 3 - वर्चुअनव मार्ग
  • कार्यक्षेत्र / testcron / testcronwithparam.py - फ़ाइल पथ
  • परम - पैरामीटर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.