After MUCH fiddling I got crontab
to activate my conda environment with conda activate my_env
and run the Python interpreter within that environment.
Note I'm using 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 opens bash
interactively. The snippet allows the user to run conda
commands (ie conda activate my_env
) from bash
.
Anaconda installer v2020.02 appended the following conda
snippet in ~/.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/
.
The problem
Sourcing ~/.bashrc
in crontab -e
won't work (at least not on Ubuntu).
Explanation:
- On Ubuntu,
~/.bashrc
has the following (or similar) line at the beginning of the file:
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
- This means that if we try to source the
~/.bashrc
file in crontab
, the rest of the .bashrc
file will not execute because crontab
is not running interactively (see another post on this topic). Which means that the conda
snippet mentioned above will never get executed by crontab
even if we source ~/.bashrc
.
_________ Working solution _________
The solution I have found is to copy the conda
snippet to a separate file.
1. Copying the conda
snippet from ~/.bashrc
to ~/.bashrc_conda
Copy the snippet mentioned above to another file, for example ~/.bashrc_conda
.
Ensure that:
- The user running the cronjob has permission to read this file.
- Other users cannot write to this file (security risk).
2. In crontab -e
insert 2 lines to run bash
instead of sh
and to source ~/.bashrc_conda
Run crontab -e
and add the following 2 lines before the cronjob:
SHELL=/bin/bash
BASH_ENV=~/.bashrc_conda
Explanation:
3. In crontab -e
insert in the cronjob line conda activate my_env;
before the desired .py
script execution
Example of entry for a script that would execute at noon 12:30 each day within the desired conda environment:
30 12 * * * conda activate my_env; python /path/to/script.py
Notice conda activate my_env;
before the command to run the Python interpreter.
_______________
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.
One could also to append ; conda deactivate
at the end of that cronjob, but this may be redundant.