Cronと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のアクティブ化スクリプトを呼び出しても何も起こりませんでした。これは上手くいきます。


私が目にする1つの違いは、スクリプトが/ home / user / projectを現在の作業ディレクトリとしてmanage.pyを実行することです。cronコマンドは、ホームディレクトリをcwdとして実行されます。たぶんログファイルはありますか?
10

実際には、ログパスは絶対的に定義されています。スクリプトが実行されていないため、ログパスは作成または追加されません。
John-Scott、

cronの問題に対する迅速で汚い解決策は、(コマンドが不可解に機能している)環境をダンプしenvexportそれらすべてをcrontabから呼び出すbashスクリプトラッパーにダンプすることです。
jberryman 2012年

回答:


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

もう1つ試すことは、manage.pyスクリプトの最上部にある同じ変更を加えることです。

#!/home/my/virtual/bin/python

1
それも機能しません。機能しないもののリストにそれを入れるのを忘れました。はい、そのコマンドをシェルで手動で実行できますが、cronからは機能しません。
John-Scott

~フルパスに置き換えましたか?(あなたはおそらくそうしました、念のため...)
ars

ああ、あなたは実用的な例を思いついた!私はあらゆる組み合わせを試してみましたが、virtualenvをアクティブにしてもまったく効果がないようです。PYTHONPATHを.bashrcに設定しましたが、これは明らかにcronで使用されていませんか?あなたの答えを強調するために私の質問を更新します。
John-Scott

ええ、cronが非常に最小限の環境で実行されることを忘れていました。一般的な推奨事項は、bashスクリプトを作成して、ジョブに必要な環境をセットアップすることです。cronで直接bashプロファイルを取得することもできますが、プロファイルの内容によっては微妙なバグが発生する可能性があります(おそらく、そのようなニーズに対応した最小限のプロファイルがある場合は問題ありません)。
ARS

7
テストする良い方法は、/ bin / shを実行してから、そこからコマンドを実行することです。少なくとも、cronと同じ環境がセットアップされます。
ディック

98

sourcecronが/bin/shデフォルトのシェルとして使用するため、cronファイルからの実行は機能しません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

上記のリンクは次のように変更されます:https : //codeinthehole.com/tips/running-django-cronjobs-within-a-virtualenv/


12
または「。」(ドットコマンド)、/ bin / shでサポート. /path/to/virtualenv/bin/activate
Reed Sandberg

5
DavidWinterbottom、それがあなたの本名なら、あなたは私のヒーローです。sh対bashとソースファイルについては、そのことを知りませんでした。あなたは私の小さなbashスクリプトの世界の男に光を当てました。ありがとう。
joemurphy 2016

postactivateファイルがある場合は、行う必要がありますsource /path/to/virtualenv/bin/activate && source /path/to/virtualenv/bin/postactivate
dspacejs '27

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から、crontabのための変数shへのbash


13

virtualenvを使用しているときにpython cronジョブを実行する唯一の正しい方法は、環境をアクティブにしてから、環境のpythonを実行してコードを実行することです。

これを行う1つの方法は、使用virtualenvののでactivate_this、あなたの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

1
これが実際に唯一の正しい方法であるというコンセンサスがあるかどうかについて、私は非常に興味があります。
アーロンシューマッハ

1
これがおそらく唯一の正しい方法です。しかし、動作する他の方法があります。
ウィル

4
これは「唯一の正しい方法」ではありません。'/ home / user / folder / env / bin / python'などのvirtualenvのpythonバイナリをcronjobに指定するだけで、virtualenvでスクリプトを正常に実行しました。環境をまったくアクティブにする必要はありません。
Canucklesandwich、2015年

仮想環境でカスタムPYTHONPATHを使用する場合、env / bin / pythonは機能しません。だからこそ、env / bin / activateを使用する方が良い
varela

1
それはあなたがPYTHONPATHの設定方法に依存し、あなたがvenvを「活性化」が必要な方法でそれを設定している場合、あなたは間違ってそれをやっている

10

virtualenv固有のシバンをいじくるのではなくPATH、crontabを先頭に追加します。

アクティブ化されたvirtualenvから、次の3つのコマンドを実行すると、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からのバイナリで実行されます。そのバイナリを疑似グローバル Pythonにすることは、virtualenvの目的そのものに反します。
VictorSchröder2017年

4

私にとって最良の解決策は両方に

  • venv bin /ディレクトリでpythonバイナリを使用します
  • Pythonパスを設定して、envパッケージモジュールディレクトリを含めます。

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

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リード・サンドバーグ@@mkb右方向を与えます。受け入れられた答えは、pythonがvenv / binディレクトリから別のpythonバイナリを実行する必要のあるスクリプトを実行する必要があるまで、実際には問題なく機能します。


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

Pythonスクリプト

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

cronコマンド

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

上記のコマンドで

  • * / 1 * * * *-1分ごとに実行
  • cd / Workspace / testcron /-Pythonスクリプトのパス
  • / Workspace / testcron / venvcron / bin / python3 - Virtualenvパス
  • Workspace / testcron / testcronwithparam.py-ファイルパス
  • param-パラメータ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.