运行 使用 anaconda 环境的 crontab 作业

run a crontab job using an anaconda env

我想让 cron 作业使用名为 my_env 的现有 anaconda python 环境执行 python 脚本。我唯一能想到的就是让 cron 作业 运行 一个名为 my_script.bash 的脚本激活环境,然后 运行s python 脚本。

#!/bin/bash
source activate my_env
python ~/my_project/main.py

尝试从命令行执行此脚本无效:

$ sh scripts/my_script.bash
scripts/my_script.bash: 9: scripts/my_script.bash: source: not found

我需要做什么来确保正确的环境被激活。像我5岁一样给我解释一下就好了

不要调用 sh,而是调用 bashsource 是一个 bash 命令。

    - sh scripts/my_script.bash
    + bash scripts/my_script.bash

或者只是

    chmod +x scripts/my_script.bash
    ./scripts/my_script.bash

自从您添加了 bash shebang。

我最近从 切换到 Anaconda 正是为了摆脱必须在 cron 作业中激活 env。 Anaconda 基于 PATH 环境变量使这变得非常简单。 (我使用的是 而不是完整的 Anaconds 安装,但我相信 anaconda 应该以同样的方式工作)

有两种不同的方法,我测试过;

  • 在您的 python 脚本中添加一个 shebang,main.py

    #!/home/users/user_name/miniconda2/envs/my_env/bin/python

  • 将 PATH 添加到 crontab 的顶部

    PATH=/home/users/user_name/miniconda2/envs/my_env/bin

更新:

Jérôme 的回答和 cbarrick 的评论是正确的。我刚刚在需要 pynco, 的 Conda env 中使用上述方法被烧毁,它需要完整的 conda 环境才能找到正确的 nco 命令,例如 ncks, ncrcat. 由 运行 解决来自 cron 的 bash 脚本首先调用 conda 激活。

就我而言,当我 运行 这行 shell 脚本时出现此错误:source activate my_env

activate: No such file or directory

所以我把source activate my_env改成了source /path/to/conda/bin/activate my_env。然后它开始工作。

经过多次摆弄后,我 crontab 使用 conda activate my_env 和 运行 在该环境中的 Python 解释器激活了我的 conda 环境。

注意我使用的是 Ubuntu 18.04.

背景

  • 当 Anaconda 安装程序初始化 conda 时,它会在 ~/.bashrc 文件的末尾附加一个片段。每次用户以交互方式打开 bash 时都会执行此文件。该代码段允许用户从 bash.

  • 运行 conda 命令(即 conda activate my_env
  • Anaconda 安装程序 v2020.02 在 ~/.bashrc 中附加了以下 conda 片段:

# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/opt/anaconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
    eval "$__conda_setup"
else
    if [ -f "/opt/anaconda3/etc/profile.d/conda.sh" ]; then
        . "/opt/anaconda3/etc/profile.d/conda.sh"
    else
        export PATH="/opt/anaconda3/bin:$PATH"
    fi
fi
unset __conda_setup
# <<< conda initialize <<<
  • 要替换为正确引用的路径/opt/anaconda3/:通常为/home/USERNAME/anaconda3/.

问题

crontab -e 中采购 ~/.bashrc 将不起作用(至少在 Ubuntu 上不会)。

解释:

  • 在 Ubuntu 上,~/.bashrc 在文件开头有以下(或类似的)行:
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
  • 这意味着如果我们尝试在 crontab 中获取 ~/.bashrc 文件,.bashrc 文件的其余部分将不会执行,因为 crontab 不是 运行ning 交互(参见另一个 post on this topic)。 这意味着即使我们获取 ~/.bashrc.
  • ,上面提到的 conda 片段也永远不会被 crontab 执行

_________ 工作解决方案 _________

我找到的解决方案是将 conda 片段复制到一个单独的文件中。

1.将 conda 片段从 ~/.bashrc 复制到 ~/.bashrc_conda

将上面提到的片段复制到另一个文件,例如~/.bashrc_conda

确保:

  • 执行 cronjob 的用户 运行 有权读取此文件。
  • 其他用户无法写入此文件(存在安全风险)。

2。在 crontab -e 中插入 2 行到 运行 bash 而不是 sh 和来源 ~/.bashrc_conda

运行 crontab -e 并在 cronjob:

之前添加以下两行
SHELL=/bin/bash
BASH_ENV=~/.bashrc_conda

解释:

  • SHELL=/bin/bash 意味着 crontab 将 运行 通过 bash 而不是 sh (默认)的 cronjobs。 See post.

  • BASH_ENV=~/.bashrc_conda 通过 chrontabconda 片段来源到 bash 运行。见 post and post.

3.在 crontab -e 中,在所需的 .py 脚本执行之前插入 cronjob 行 conda activate my_env;

每天中午 12:30 在所需的 conda 环境中执行的脚本条目示例:

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

注意 conda activate my_env; 在命令 运行 Python 解释器之前。

_______________

并且 voilà,成功了。

有什么缺点吗?

如果 .bashrc 中的 conda 片段被 conda 更新更新,它当然不会反映在单独的 .bashrc_conda 文件中。可能需要不时检查更新。

也可以在该 cronjob 的 末尾 附加 ; conda deactivate,但这可能是多余的。

截至 2022 年 5 月,我只是在 Windows 10 中使用 .bat 来激活 myenv,然后启动我的 localhost 或您需要的任何脚本:

@echo off
set CONDAPATH=C:\Users\MyName\anaconda3
set ENVNAME=myenv
if %ENVNAME%==base (set ENVPATH=%CONDAPATH%) else (set ENVPATH=%CONDAPATH%\envs\%ENVNAME%)
call %CONDAPATH%\Scripts\activate.bat %ENVPATH%

call cd /d d:/mysite
python manage.py runserver 0.0.0.0:8000