1

I use a conda environment with a lot of dependencies and some personal packages compiled with conda-build. When doing conda activate iota2_dev I'll update the $PATH variable to propose some executable to the user. The activate.sh script is available here After doing conda deactivate the following /home/btardy/miniconda3/envs/iota2_dev/bin is still in $PATH.

However the following added in activate.sh ${CONDA_PREFIX}/lib/python3.6/site-packages/iota2:${CONDA_PREFIX}/lib/python3.6/site-packages/iota2/Common/Tools: is well removed after conda deactivate

After looking at all activate scripts in /home/btardy/miniconda3/envs/iota2_dev/etc/conda/activate.d no one update $PATH variable. It seems that when entering in the first activate.sh script $PATH was already modified with /home/btardy/miniconda3/envs/iota2_dev/bin... then it seems that our activate/deactivate procedure works well.

The question is why and how the $PATH is modified before, and why it is not reset at the end.

If I comment the $PATH modification in our activate.sh, the path is correctly cleared after conda deactivate. But we loose simple access to executables.

What happened:

~$ echo $PATH
/home/btardy/miniconda3/condabin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
~$ conda activate iota2_dev
(iota2) ~$ echo $PATH
/home/btardy/miniconda3/envs/iota2_dev/lib/python3.6/site-packages/iota2:/home/btardy/miniconda3/envs/iota2_dev/lib/python3.6/site-packages/iota2/Common/Tools:/home/btardy/miniconda3/envs/iota2_dev/bin:/home/btardy/miniconda3/condabin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
(iota2) ~$ conda deactivate
~$ echo $PATH
/home/btardy/miniconda3/envs/iota2_dev/bin:/home/btardy/miniconda3/condabin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

What should happened:

~$ echo $PATH
/home/btardy/miniconda3/condabin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
~$ conda activate iota2
(iota2) ~$ echo $PATH
/home/btardy/miniconda3/envs/iota2_dev/lib/python3.6/site-packages/iota2:/home/btardy/miniconda3/envs/iota2_dev/lib/python3.6/site-packages/iota2/Common/Tools:/home/btardy/miniconda3/envs/iota2_dev/bin:/home/btardy/miniconda3/condabin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
(iota2) ~$ conda deactivate
~$ echo $PATH
/home/btardy/miniconda3/condabin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

With an environment containing other packages (no $PATH modification in activate.sh) the path is correctly cleared after conda deactivate. I did not found how conda natively store and restore $PATH. There is a variable somewhere that we can use in our scripts to restore correctly the path ?

Any help or explanations about the behaviour of conda activate when no activate.sh script are available will be also useful.

This question is also on conda github )

ZF007
  • 3,708
  • 8
  • 29
  • 48
tardyb
  • 11
  • 2
  • 1
    It sounds like you are modifying the activate script directly or something of the likes? Have you tried simply creating a custom script in activate.d and deactivate.d as laied out [here](https://stackoverflow.com/a/49238956/5012099)? – FlyingTeller Nov 08 '21 at 09:08
  • Yes exactly. We store the $PATH content when entering in the activate script. The issue here is it was already modified by conda. And I don't find where conda update the path and store the initial $PATH value... I have just added a custom script "activate.sh" in activate.d and the PATH is already modified too. The issue seems very linked only with PATH as we also modify LD_LIBRARY_PATH and it works correctly for it. – tardyb Nov 08 '21 at 12:21

1 Answers1

1

I took a quick look. It seems like conda does its own modification of PATH before calling anything in activate.d, but also before calling anything in deactivate.d, so when you have in activate.d\test.sh something like

echo ${PATH}
export OLD_PATH=${PATH}

export PATH=/usr/users/dummy/testdir:${PATH}

you will have in OLD_PATH already the bin directory of your environment. So when you then do in deactivate.d\test.sh something like

export PATH=${OLD_PATH}

Then you will add the bin directory to PATH after conda has purged it. Only way to directly adress your question that I can think of is to prune the already added prefix to PATH in your activate.d script like this:

export OLD_PATH=$(echo ${PATH} | sed 's/^[^:]*://g')

BUT

I personally do not like that solution much. You are relying on the fact that conda will just prepend one entry to PATH which might or might not be a stable assumption. I am not an expert in conda recipes, but I am fairly certain that it should not be too difficult to just copy scripts into the actual bin directory of the env (which is added to PATH automatically) and have them as entry points for your code.

FlyingTeller
  • 17,638
  • 3
  • 38
  • 53
  • Thank you for your answers @FlyingTeller. I agree that pruning the `$PATH` is not an elegant solution. I create alias for the entry points instead of modify `$PATH`, and then unalias them in deactivate.sh. Another solution is to warn user to close the terminal once they deactivate the environment to avoid conflict in `$PATH` – tardyb Nov 10 '21 at 08:17