我设置了 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
:
conda activate ~/anaconda3/envs/sql_server_etl/
现在,当我登录时,环境会自动激活。
然而,问题仍然存在。
我又尝试了一件事。我更改了 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 应该在虚拟环境下运行呢?
答案1
发布了工作解决方案(在Ubuntu 18.04上)以及SO的详细推理。
缩写形式是:
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 的用户有读取权限for
~/.bashrc_conda
(并且没有其他用户可以写入此文件)。
2.添加在源crontab -e
上运行 cronjobs 的行bash
~/.bashrc_conda
运行crontab -e
并插入以下内容在 cronjob 之前:
SHELL=/bin/bash
BASH_ENV=~/.bashrc_conda
3. 在crontab -e
cronjob 的开头包含conda activate my_env;
,如示例所示
每天中午 12:30 在 conda 环境中的 Python 解释器上执行的脚本的条目示例:
30 12 * * * conda activate my_env; python /path/to/script.py; conda deactivate
就是这样。
您可能需要不时检查 中的代码片段是否~/.bashrc_conda
是最新的,以防 conda 更新其在 中的代码片段~/.bashrc
。
答案2
这是一个对我来说效果很好的解决方案。
source /root/miniconda3/etc/profile.d/conda.sh && \
conda activate <your_env> && \
python <your_application> &
我在 Ubuntu 18.04.3 LTS 上使用 miniconda 和 Conda 版本 4.7.12。
我可以将上述内容放入脚本中并通过 crontab 运行它,没有任何问题。
答案3
在堆栈溢出上找到答案:
https://stackoverflow.com/questions/3287038/cron-and-virtualenv
解决方案是在虚拟环境本身中引用 python 可执行文件。就我而言,我更改了 bash 文件来运行此可执行文件:
/home/etlservice/anaconda3/envs/sql_server_etl/bin/python
答案4
这个解决方案对我有用。
尝试使用
source /path/to/conda/bin/activate my_env
代替
conda activate my_env
在你的 bash 脚本中run_parallel_workflow.sh
。