web-dev-qa-db-ja.com

conda仮想環境で実行するcronジョブ

Anaconda Python仮想環境がセットアップされています。その仮想環境がアクティブ化されているときにプロジェクトを実行すると、すべてが適切に実行されます。

しかし、私はそれを毎時間実行するように設定されたcronjobを持っています。正しく実行されていなかったため、出力をログにパイプしました。

crontab -e

10 * * * * bash /work/sql_server_etl/src/python/run_parallel_workflow.sh >> /home/etlservice/cronlog.log 2>&1

私はcronlog.logでこのエラーを受け取ります:

Traceback (most recent call last):
  File "__parallel_workflow.py", line 10, in <module>
    import yaml
ImportError: No module named yaml

これは、cronjobが仮想環境をアクティブ化せずにファイルを実行していないことを示しています。

これを修正するために、/home/user/.bash_profileファイルに1行追加しました。

conda activate ~/anaconda3/envs/sql_server_etl/

ログインすると、環境が自動的にアクティブになります。

ただし、問題は解決しません。

もう1つ試してみました。私はcronjobを変更しました(また、cronjobが実行するbashファイルでこれを試しました)、実行するたびに環境を明示的に手動でアクティブ化しましたが、役に立ちませんでした:

10 * * * * conda activate ~/anaconda3/envs/sql_server_etl/ && bash /work/sql_server_etl/src/python/run_parallel_workflow.sh >> /home/etlservice/cronlog.log 2>&1

もちろん、私が試したことは何もありません。私はLinuxについて何も知らないので、変更が必要なことは明らかだと思います。

それでは、とにかくcronjobを仮想環境で実行するように指定する方法はありますか?

2
Legit Stack

SOについての詳細な推論を伴う(Ubuntu 18.04での)実用的なソリューション を投稿しました。

短い形式は次のとおりです。

1. Anacondaによって~/.bashrcに追加されたスニペットを(ファイルの最後に)別のファイル~/.bashrc_condaにコピーします

Anaconda 2020.02のインストール以降、スニペットは次のようになります。

# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/home/USERNAME/anaconda3/bin/conda' 'Shell.bash' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
    eval "$__conda_setup"
else
    if [ -f "/home/USERNAME/anaconda3/etc/profile.d/conda.sh" ]; then
        . "/home/USERNAME/anaconda3/etc/profile.d/conda.sh"
    else
        export PATH="/home/USERNAME/anaconda3/bin:$PATH"
    fi
fi
unset __conda_setup
# <<< conda initialize <<<

次のことを確認してください。

  • パス/home/USERNAME/anaconda3/は正しいです。
  • Cronjobを実行しているユーザーは、~/.bashrc_condaに対して読み取り権限を持っています(他のユーザーはこのファイルに書き込むことができません)。

2. crontab -ebashでcronjobsを実行し、ソース~/.bashrc_condaに行を追加します

crontab -eを実行し、次のcronjobの前を挿入します。

Shell=/bin/bash
BASH_ENV=~/.bashrc_conda

3.例のようにcrontab -eにcronjob conda activate my_env;の先頭に含めます

Python conda環境内のインタープリターで毎日正午12:30に実行されるスクリプトのエントリの例:

30 12 * * * conda activate my_env; python /path/to/script.py; conda deactivate

以上です。

Condaが~/.bashrc_condaのスニペットを更新した場合に備えて、~/.bashrcのスニペットが最新であることを時々確認することをお勧めします。

1
Jean Monet

スタックオーバーフローで回答が見つかりました:

https://stackoverflow.com/questions/3287038/cron-and-virtualenv

解決策は、仮想環境自体内でpython実行可能ファイルを参照することです。私の場合、この実行可能ファイルを実行するようにbashファイルを変更しました。

/home/etlservice/anaconda3/envs/sql_server_etl/bin/python

3
Legit Stack

これは私にとってうまくいった解決策です。

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経由でも問題なく実行できます。