101

I'm trying to activate my conda env via a bash script. Even though the script runs fine and my PATH appears to be changed within the script, it's getting reset somehow after the script terminates. I can call source activate test from the cmd line and it works fine. An example along with output below.

script:

PycharmProjects/test » cat ./example.sh
echo "before calling source: $PATH"
source activate test
echo "after calling source: $PATH"

output:

./example.sh
before calling source: /Use rs/me/miniconda3/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/TeX/texbin

discarding /Users/me/miniconda3/bin from PATH
prepending /Users/me/miniconda3/envs/test/bin to PATH

after calling source: /Users/me/miniconda3/envs/test/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/TeX/texbin`

but if I echo $PATH after the script finishes, you can see that the $PATH has not changed (i.e. no /Users/me/miniconda3/envs/test/bin):

PycharmProjects/test » echo $PATH /Users/me/miniconda3/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/TeX/texbin

7
  • 1
    echo $PATH where says that? Are you running example.sh as a script itself (i.e. ./example.sh)? Instead of sourceing it (i.e. source example.sh)? Dec 30, 2015 at 18:27
  • running example.sh as as script (./example.sh). I called echo $PATH after script finished running, just to show $PATH is not actually changed.
    – matt_k
    Dec 30, 2015 at 18:30
  • 2
    Running it as a script the changes stop with the shell running the script. That's why you need to source the activate script to make it apply to the running script/shell in the first place. Dec 30, 2015 at 18:32
  • Possible duplicate of How to source virtualenv activate in a Bash script Dec 30, 2015 at 18:36
  • Thanks sourcing the script fixes it.
    – matt_k
    Dec 30, 2015 at 18:54

5 Answers 5

188

On more recent versions of conda (4.6+), I have noticed that the following works:

eval "$(conda shell.bash hook)"
conda activate <env-name>
10
  • 8
    Could you please explain a little bit why do we need eval "$(conda shell.bash hook)"?
    – Jon
    May 21, 2019 at 2:01
  • 3
    conda shell.bash hook returns a string of bash. I suppose you could right this out to a file and then source that file, but it is easier/faster to eval it. May 21, 2019 at 20:51
  • 4
    @AnthonyScopatz That explains what you're doing, but not why. conda activate <env> works just fine without that eval expression, so it's still not clear why you're doing that.
    – Cerin
    Sep 19, 2019 at 16:59
  • 14
    When conda activate errors out requesting conda init to be run, the eval expression here makes it work without conda init. Nov 7, 2019 at 17:23
  • 2
    Getting: CommandNotFoundError: Your shell has not been properly configured to use 'conda activate'.
    – ntg
    Feb 14, 2020 at 8:57
44

I have found the following to work on Mac OSX running a bash shell:

#!/bin/bash
source /Users/yourname/anaconda/bin/activate your_env
python --version # example way to see that your virtual env loaded as expected

Make sure you make the scripted executable with:

chmod +x yourscript.bash
1
  • It worked for me on ubuntu 18, conda 4.9. It took less time than the Anthony Scopatz approach. The reason is out of my understandings. Feb 2, 2021 at 10:26
34

Interactive Shell

The conda activate command is intended for interactive shell sessions. One solution is to deliberately run the script in an interactive shell. This can be done through a shebang (if planning to use ./example.sh call):

example.sh

#!/usr/bin/env bash -l
echo "before calling source: $PATH"
## `source activate` is deprecated
conda activate test
echo "after calling source: $PATH"

or, by specifying via flags to the shell:

## bash
bash -l example.sh

## zsh
zsh -i example.sh

All of these assume that the executing user has run conda init for the shell.

Using conda run

For programmatic execution within an environment, Conda provides the conda run command. Rather than muck around with shell state, let Conda guarantee execution within the environment:

crun_example.sh

echo "PATH outside environment: $PATH"

## printing shell variables is complicated by escaping
conda run -n test bash -c "echo \"PATH inside environment: \${PATH}\""

## but realistic application is usually a non-trivial script
conda run -n test python my_script.py

Code that involves user-facing I/O will often need a --live-stream flag. See conda run --help for details.

6

See the link below,

digitalocean-how-to-read-and-set-environmental-and-shell-variables-on-a-linux-vps

below is the snippet from the website,

This is because environmental variables are only passed to child processes. There isn't a built-in way of setting environmental variables of the parent shell. This is good in most cases and prevents programs from affecting the operating environment from which they were called.

0
0

I am using a workstation with the spec:

  • Fedora 37
  • Bash: GNU bash, version 5.2.15(1)-release (x86_64-redhat-linux-gnu)
  • conda: 23.7.2

None of these solutions worked for me, neither using bash interactive mode, nor login mode, nor eval "$(conda shell.bash hook)", etc.

I have a workaround for this issue for everyone like me being unable to make those solutions worked:

  1. Create a bash file named activate.sh in the project folder with this content:
#!/bin/bash
conda activate your_env_name
  1. Add an alias in ~/.bash_aliases like this:
alias conda-activate='test -f $PWD/activate.sh && source $PWD/activate.sh'
  1. Run conda-activate in your project folder

I know the question is about macos, but this is the most referenced issue for this problem in stackoverflow and I think is a good place to post my solution here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.