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スクリプトを呼び出しても何も起こりませんでした。これは、ショーでも同様に機能します。
仮想環境で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
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/
これ以上見てはいけません:
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
に変更する必要がないことです。
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...]
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
私にとって最良の解決策は両方に
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
>>>
この問題を解決するのに少し時間を費やし、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バイナリを実行する必要があるスクリプトを実行する必要があるまで、受け入れられた答えは実際にうまく機能します。