bash 使用 anaconda env 运行 crontab 作业

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36365801/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 14:27:11  来源:igfitidea点击:

run a crontab job using an anaconda env

pythonbashcronanacondaconda

提问by stoebelj

I want to have a cron job execute a python script using an already existing anaconda python environment called my_env. The only thing I can think to do is have the cron job run a script called my_script.bashwhich in turn activates the env and then runs the python script.

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

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

Trying to execute this script from the command lines doesn't work:

尝试从命令行执行此脚本不起作用:

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

What do I need to do to make sure the proper environment is activated. Its ok to explain it to me like I'm 5.

我需要做什么来确保正确的环境被激活。可以像我 5 岁一样向我解释它。

采纳答案by Jér?me

Don't call shbut bash. sourceis a bash command.

不要打电话sh但是bashsource是一个 bash 命令。

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

Or just

要不就

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

since you added the bash shebang.

因为你添加了 bash shebang。

回答by Eric Bridger

I recently switched from canopyto Anaconda precisely to get away from having to activate an env in cron jobs. Anaconda makes this very simple, based on the PATH enviornment variable. (I'm using minicondanot the full Anaconds install but I believe anaconda should work the same way)

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

There are two different approaches, I've tested;

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

  • Add a shebang in your python script, main.py

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

  • Add PATH to the top of your crontab

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

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

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

  • 将 PATH 添加到 crontab 的顶部

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

Update:

更新:

Jér?me's answer and cbarrick's comments are correct. I just got burned using the above approach in a Conda env which needed pynco,which needs the full conda environment to find proper the ncocommands, such as ncks, ncrcat.Solved by running a bash script from cron which calls conda activate first.

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

回答by Youngmin Kim

In my case, I got this error when I ran this line of shell script: source activate my_env

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

activate: No such file or directory

activate: No such file or directory

So I changed source activate my_envto source /path/to/conda/bin/activate my_env. Then it starts working.

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

回答by Jean Monet

After MUCH fiddling I got crontabto activate my conda environment with conda activate my_envand run the Python interpreter within that environment.

经过大量的摆弄之后,我必须crontab激活我的 conda 环境conda activate my_env并在该环境中运行 Python 解释器。

Note I'm using Ubuntu 18.04.

注意我使用的是 Ubuntu 18.04。

Background

背景

  • When the Anaconda installer initializes conda, it appends a snippet at the end of the ~/.bashrcfile. This file is executed each time the user opens bashinteractively. The snippet allows the user to run condacommands (ie conda activate my_env) from bash.

  • Anaconda installer v2020.02 appended the following condasnippet in ~/.bashrc:

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

  • Anaconda 安装程序 v2020.02 在 中附加了以下conda代码段~/.bashrc

# >>> 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 <<<
  • The path /opt/anaconda3/to be replaced with the correct reference: usually /home/USERNAME/anaconda3/.
  • /opt/anaconda3/要被正确引用替换的路径:通常是/home/USERNAME/anaconda3/.

The problem

问题

Sourcing ~/.bashrcin crontab -ewon't work (at least not on Ubuntu).

采购~/.bashrccrontab -e行不通的(至少在 Ubuntu 上不行)。

Explanation:

解释:

  • On Ubuntu, ~/.bashrchas the following (or similar) line at the beginning of the file:
  • 在 Ubuntu 上,~/.bashrc文件开头有以下(或类似的)行:
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
  • This means that if we try to source the ~/.bashrcfile in crontab, the rest of the .bashrcfile will not execute because crontabis not running interactively (see another post on this topic). Which means that the condasnippet mentioned above will never get executed by crontabeven if we source ~/.bashrc.
  • 这意味着,如果我们尝试在 中获取~/.bashrc文件crontab,则文件的其余部分.bashrc将不会执行,因为crontab不是以交互方式运行的(请参阅有关此主题的另一篇文章)。这意味着即使我们 source ,conda上面提到的代码片段也永远不会被执行。crontab~/.bashrc

_________ Working solution _________

_________ 工作解决方案 _________

The solution I have found is to copy the condasnippet to a separate file.

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

1. Copying the condasnippet from ~/.bashrcto ~/.bashrc_conda

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

Copy the snippet mentioned above to another file, for example ~/.bashrc_conda.

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

Ensure that:

确保这件事:

  • The user running the cronjob has permission to read this file.
  • Other users cannot write to this file (security risk).
  • 运行 cronjob 的用户有权读取此文件。
  • 其他用户无法写入此文件(安全风险)。

2. In crontab -einsert 2 lines to run bashinstead of shand to source ~/.bashrc_conda

2. 在crontab -e插入 2 行来运行bash而不是sh~/.bashrc_conda

Run crontab -eand add the following 2 lines before the cronjob:

在 cronjob 之前运行crontab -e并添加以下两行:

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

Explanation:

解释:

  • SHELL=/bin/bashmeans that crontabwill run the cronjobs via bashinstead of sh(default). See post.

  • BASH_ENV=~/.bashrc_condasources the condasnippet to bashrun by chrontab. See postand post.

  • SHELL=/bin/bash意味着crontab将通过bash而不是sh(默认)运行 cronjobs 。见帖子

  • BASH_ENV=~/.bashrc_conda获取condabash运行的代码段chrontab。见帖子帖子

3. In crontab -einsert in the cronjob line conda activate my_env;before the desired .pyscript execution

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

Example of entry for a script that would execute at noon 12:30 each day within the desired conda environment:

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

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

Notice conda activate my_env;before the command to run the Python interpreter.

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

_______________

_____________

And voilà, it worked.

而且,它的工作。

Any downsides?有什么缺点吗?

If the condasnippet in .bashrcgets updated by a condaupdate, it will of course not be reflected in the separate .bashrc_condafile. One may need to check for updates from time to time.

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

One could also to append ; conda deactivateat the endof that cronjob, but this may be redundant.

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