89

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

pkowalczyk
  • 16,763
  • 6
  • 27
  • 35
matt_k
  • 4,139
  • 4
  • 27
  • 33
  • `echo $PATH` **where** says that? Are you running `example.sh` as a script itself (i.e. `./example.sh`)? Instead of `source`ing it (i.e. `source example.sh`)? – Etan Reisner Dec 30 '15 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 '15 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. – Etan Reisner Dec 30 '15 at 18:32
  • Possible duplicate of [How to source virtualenv activate in a Bash script](http://stackoverflow.com/questions/13122137/how-to-source-virtualenv-activate-in-a-bash-script) – Etan Reisner Dec 30 '15 at 18:36
  • Thanks sourcing the script fixes it. – matt_k Dec 30 '15 at 18:54
  • I had the same problem and ended up forcing my script to be sourced. That caused other troubles (such as running it with set -e) - eventually it was worth changing to to "ordinary" run (not sourced) and apply the accepted answer. Thanks for asking this! – Guy Rapaport Dec 13 '20 at 11:32

5 Answers5

169

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

eval "$(conda shell.bash hook)"
conda activate <env-name>
Anthony Scopatz
  • 3,265
  • 2
  • 15
  • 14
  • 7
    Could you please explain a little bit why do we need `eval "$(conda shell.bash hook)"`? – Jon May 21 '19 at 02: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. – Anthony Scopatz May 21 '19 at 20:51
  • 4
    @AnthonyScopatz That explains what you're doing, but not why. `conda activate ` works just fine without that eval expression, so it's still not clear why you're doing that. – Cerin Sep 19 '19 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`. – Allen Baron Nov 07 '19 at 17:23
  • 2
    Getting: `CommandNotFoundError: Your shell has not been properly configured to use 'conda activate'.` – ntg Feb 14 '20 at 08:57
  • I'm getting: `Could not find conda environment: ` – Wassadamo May 18 '20 at 12:28
  • 1
    Works for me! would be great for anaconda to put this in the CLI – Kevin R. Jun 22 '21 at 02:11
  • This perfectly worked for me.... without the eval statement I was getting: CommandNotFoundError: Your shell has not been properly configured to use 'conda activate'. But the eval statement solved it..so thank you! – Dipanwita Mallick Jul 30 '21 at 18:42
  • I am still not sure why this works (but it does). I can run `source activate $CONDA_ENV` without any error, but the environment is not actually loaded until I add the eval command OP suggests. – zephyrus Apr 05 '22 at 01:44
42

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
user3150079
  • 459
  • 4
  • 6
27

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.

merv
  • 67,214
  • 13
  • 180
  • 245
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.

Jithin Scaria
  • 1,271
  • 1
  • 15
  • 26
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.

Ebrahim Pasbani
  • 9,168
  • 2
  • 23
  • 30