3

I'm trying to write a script to install miniConda, then activate a conda environment.

Here's the relevant part of the code:

if ! command -v conda --version &> /dev/null
then
    wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O conda.sh
    bash conda.sh -b -p ~/local/miniconda3
    rm -f conda.sh
    ~/local/miniconda3/bin/conda init bash
    . ~/.bashrc
fi
conda config --set auto_activate_base false

conda create -yn my_env
eval "$(conda shell.bash hook)"
conda activate my_env

When I run the script, the output on my terminal looks as though conda was installed successfully. I get a long stream of messages, and, after reading through them all, it seems clear that everything was successful. (It's stuff like Solving environment: done, if that helps).

However, when I run conda --version at my terminal to test if I did install conda, I get the error conda: command not found

I can get conda --version to work as expected if I follow this StackOverflow answer and type bash into my terminal, then run conda --version from there.

I've read a lot of answers about shells and subshells and how they relate to conda. I have the vague idea that my issue has to do with something (?) being executed in a subshell instead of the parent shell (?), and maybe something about sourcing ~/.bashrc wrong (?). I need some major pointers on the details, though.

I apologize for not being able to form a better question. If I had a more specific idea of what to ask, I would just google it. :)

NOTE: Some of the stuff in my script (like ~/local/miniconda3/bin/conda init bash; . ~/.bashrc) was copied from other StackOverflow answers. I read the explanations on those SO questions very carefully, but I unfortunately didn't come away with much more than the general idea "It works if you do this". It would be great if anyone answering could also explain if those lines relate to my question.

teddy
  • 105
  • 7

2 Answers2

1

Probably the install script is adding something to $PATH and this is not picked up until the shell is restarted or the configuration file is re-sourced. You could try exec $SHELL at the end of the script to spawn a new shell which will pick up such changes.

old greg
  • 799
  • 8
  • 19
  • That's a really good fix. It works perfectly. Unfortunately, I should have clarified that I'm writing this script for other people to use. The team workflow is to ssh into a remote server, run `conda activate `, and be good to go. I want this script to be something that new people to the team can run once to get their environment set up. I don't want them to have to run `bash` every time. – teddy Sep 27 '20 at 15:55
0

After you have updated the user's PATH you may need to run hash -r conda to update Bash's internal command lookup cache.

In brief, your installation program cannot update the current shell ulnless you require your users to source it, or eval whatever it prints. Maybe organize it to do the former, but encapsulate the latter.

echo 'PATH=$PATH:/blah-blah' >>~/.bashrc
eval "$(tail -n 1 ~/.bashrc; echo 'hash -r conda')"
tripleee
  • 175,061
  • 34
  • 275
  • 318
  • Thank you! Could you please clarify what you mean? Where in my script should I put the commands you listed? Also, you’re saying I need to get the users to `source` it or `eval` whatever it prints. What would this look like? My goal is to create a script so that people who need to set up their environment can simply run the script. I want to make it so that, next time the user ssh’s onto their remote machine, they can run `conda activate ` and be ready to go. Is this possible? How can I change my script to achieve this functionality? – teddy Sep 27 '20 at 18:45
  • You will probably have to refactor your script so it can be safely sourced. After that, it doesn't really matter much where you put these lines; maybe near the end if there isn't an obvius other part where you are already doing something like this. – tripleee Sep 27 '20 at 18:59
  • What do you mean "so that it can be safely sourced"? Does this have to do with what commands are run in a subshell? If so, could you point me to some tutorial on how this works and what happens? – teddy Sep 27 '20 at 19:19
  • Usually when a script is run normally you can use temporary variables etc with full abandon because everything will be cleaned out when the process ends; when you are not running in a separate process, you have to take care to not mess up the caller's environment. If you go pure `eval` route (require `eval "$(yourscript)"` instead of `source yourscript`) all you need to worry about is to make sure the script only outputs text which goes into the `eval`. – tripleee Sep 28 '20 at 04:25