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
run a crontab job using an anaconda env
提问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.bash
which 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 sh
but bash
. source
is a bash command.
不要打电话sh
但是bash
。source
是一个 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 nco
commands, 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_env
to source /path/to/conda/bin/activate my_env
. Then it starts working.
所以我改变了source activate my_env
对source /path/to/conda/bin/activate my_env
。然后它开始工作。
回答by Jean Monet
After MUCH fiddling I got crontab
to activate my conda environment with conda activate my_env
and 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
~/.bashrc
file. This file is executed each time the user opensbash
interactively. The snippet allows the user to runconda
commands (ieconda activate my_env
) frombash
.Anaconda installer v2020.02 appended the following
conda
snippet 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 ~/.bashrc
in crontab -e
won't work (at least not on Ubuntu).
采购~/.bashrc
是crontab -e
行不通的(至少在 Ubuntu 上不行)。
Explanation:
解释:
- On Ubuntu,
~/.bashrc
has 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
~/.bashrc
file incrontab
, the rest of the.bashrc
file will not execute becausecrontab
is not running interactively (see another post on this topic). Which means that theconda
snippet mentioned above will never get executed bycrontab
even if we source~/.bashrc
.
- 这意味着,如果我们尝试在 中获取
~/.bashrc
文件crontab
,则文件的其余部分.bashrc
将不会执行,因为crontab
不是以交互方式运行的(请参阅有关此主题的另一篇文章)。这意味着即使我们 source ,conda
上面提到的代码片段也永远不会被执行。crontab
~/.bashrc
_________ Working solution _________
_________ 工作解决方案 _________
The solution I have found is to copy the conda
snippet to a separate file.
我找到的解决方案是将conda
代码片段复制到一个单独的文件中。
1. Copying the conda
snippet from ~/.bashrc
to ~/.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 -e
insert 2 lines to run bash
instead of sh
and to source ~/.bashrc_conda
2. 在crontab -e
插入 2 行来运行bash
而不是sh
源~/.bashrc_conda
Run crontab -e
and add the following 2 lines before the cronjob:
在 cronjob 之前运行crontab -e
并添加以下两行:
SHELL=/bin/bash
BASH_ENV=~/.bashrc_conda
Explanation:
解释:
SHELL=/bin/bash
means thatcrontab
will run the cronjobs viabash
instead ofsh
(default). See post.BASH_ENV=~/.bashrc_conda
sources theconda
snippet tobash
run bychrontab
. See postand post.
SHELL=/bin/bash
意味着crontab
将通过bash
而不是sh
(默认)运行 cronjobs 。见帖子。
3. In crontab -e
insert in the cronjob line conda activate my_env;
before the desired .py
script 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 conda
snippet in .bashrc
gets updated by a conda
update, it will of course not be reflected in the separate .bashrc_conda
file. One may need to check for updates from time to time.
如果 中的conda
片段.bashrc
被更新conda
更新,它当然不会反映在单独的.bashrc_conda
文件中。人们可能需要不时检查更新。
One could also to append ; conda deactivate
at the endof that cronjob, but this may be redundant.
也可以; conda deactivate
在该cronjob的末尾附加,但这可能是多余的。