web-dev-qa-db-ja.com

Cronとvirtualenv

Django管理コマンドをcronから実行しようとしています。プロジェクトをサンドボックス化するためにvirtualenvを使用しています。

ここや他の場所で、virtualenvのような管理コマンドの実行を示す例を見てきました。

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

ただし、タスクを開始する必要があるときにsyslogにエントリが表示されていても、このタスクは実際には実行されません(スクリプトのログファイルは空です)。シェルから手動で行を実行すると、期待どおりに機能します。

現在、cronを介してコマンドを実行できる唯一の方法は、コマンドを分割し、ダムバッシュラッパースクリプトに入れることです。

#!/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スクリプトを呼び出しても何も起こりませんでした。これは、ショーでも同様に機能します。

203
John-Scott

仮想環境で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
225
ars

Cronはsourceをサポートしていないデフォルトのシェルとして/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がエラーの詳細を記録しないため、これが失敗する理由を見つけるのは難しいです。 cronエラーがメールで送信されるように、自分自身をrootにエイリアスするのが最善です。自分を/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/

88

これ以上見てはいけません:

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

これの利点は、crontabのShell変数をshからbashに変更する必要がないことです。

10
Basil Musa

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

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

これを行う1つの方法は、pythonスクリプトでvirtualenvのactivate_thisを使用することです。以下を参照してください。 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
9
Ivanhoe

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

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

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

この問題を解決するのに少し時間を費やし、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 に正しい方向を与えてくれてありがとう。 pythonがvenv/binディレクトリから別のpythonバイナリを実行する必要があるスクリプトを実行する必要があるまで、受け入れられた答えは実際にうまく機能します。

2
Dmitriy