Related
How do I get snakemake to activate a conda environment that already exists in my environment list?
I know you can use the --use-conda with a .yaml environment file but that seems to generate a new environment which is just annoying when the environment already exists. Any help with this would be much appreciated.
I have tried using the:
conda:
path/to/some/yamlFile
but it just returns command not found errors for packages in the environment
It is possible. It is essentially an environment config issue. You need to call bash in the snakemake rules and load conda-init'd bash profiles there. Below example works with me:
rule test_conda:
shell:
"""
bash -c '
. $HOME/.bashrc # if not loaded automatically
conda activate base
conda deactivate'
"""
In addition, --use-conda is not necessary in this case at all.
Follow up to answer by liagy, since snakemake runs with strict bash mode (set -u flag), conda activate or deactivate may throw an error showing unbound variable related to conda environment. I ended up editing parent conda.sh file which contains activate function. Doing so will temporarily disable u flag while activating or deactivating conda environments but will preserve bash strict mode for rest of snakemake workflow.
Here is what I did:
Edit (after backing up the original file) ~/anaconda3/etc/profile.d/conda.sh and add following from the first line within __conda_activate() block:
__conda_activate() {
if [[ "$-" =~ .*u.* ]]; then
local bash_set_u
bash_set_u="on"
## temporarily disable u flag
## allow unbound variables from conda env
## during activate/deactivate commands in
## subshell else script will fail with set -u flag
## https://github.com/conda/conda/issues/8186#issuecomment-532874667
set +u
else
local bash_set_u
bash_set_u="off"
fi
# ... rest of code from the original script
And also add following code at the end of __conda_activate() block to re-enable bash strict mode only if present prior to running conda activate/deactivate functions.
## reenable set -u if it was enabled prior to
## conda activate/deactivate operation
if [[ "${bash_set_u}" == "on" ]]; then
set -u
fi
}
Then in Snakefile, you can have following shell commands to manage existing conda environments.
shell:"""
## check current set flags
echo "$-"
## switch conda env
source ~/anaconda3/etc/profile.d/conda.sh && conda activate r-reticulate
## Confirm that set flags are same as prior to conda activate command
echo "$-"
## switch conda env again
conda activate dev
echo "$-"
which R
samtools --version
## revert to previous: r-reticulate
conda deactivate
"""
You do not need to add above patch for __conda_deactivate function as it sources activate script.
PS: Editing ~/anaconda3/etc/profile.d/conda.sh is not ideal. Always backup the original and edited filed. Updating conda will most likely overwrite these changes.
Prefer Snakemake-managed environments
This is an old answer, from before Snakemake added a feature to allow user-managed environments. Other answers cover the newer functionality. Nevertheless, I am retaining this answer here because I believe it adds perspective to the problem, and why this feature is still discouraged from being used. Specifically, from the documentation:
"Importantly, one should be aware that this can hamper reproducibility, because the workflow then relies on this environment to be present in exactly the same way on any new system where the workflow is executed. Essentially, you will have to take care of this manually in such a case. Therefore, the approach using environment definition files described above is highly recommended and preferred." [emphasis in the original]
(Mostly) Original Answer
This wasn't previously possible and I'd still argue it was mostly a good thing. Snakemake having sole ownership of the environment helps improve reproducibility by requiring one to update the YAML instead of directly manipulating the environment with conda (install|update|remove). Note that such a practice of updating a YAML and recreating is a Conda best practice when mixing in Pip, and it definitely doesn't hurt to adopt it generally.
Conda does a lot of hardlinking, so I wouldn't sweat the duplication too much - it's mostly superficial. Moreover, if you create a YAML from the existing environment you wish to use (conda env export > env.yaml) and give that to Snakemake, then all the identical packages that you already have downloaded will be used in the environment that Snakemake creates.
If space really is such a tight resource, you can simply not use Snakemake's --use-conda flag and instead activate your named envs as part of the shell command or script you provide. I would be very careful not to manipulate those envs or at least be very diligent about tracking changes made to them. Perhaps, consider tracking the output of conda env export > env.yaml under version control and putting that YAML as an input file in the Snakemake rules that activate the environment. This way Snakemake can detect that the environment has mutated and the downstream files are potentially outdated.
This question is still trending on Google, so an update:
Since snakemake=6.14.0 (2022-01-26) using an existing, named conda environment is a supported feature.
You simply put the name of the environment some-env-name into the rules conda directive (instead of the .yaml file) and use snakemake --use-conda:
rule NAME:
input:
"table.txt"
output:
"plots/myplot.pdf"
conda:
"some-env-name"
script:
"scripts/plot-stuff.R"
Documentation: https://snakemake.readthedocs.io/en/stable/snakefiles/deployment.html#using-already-existing-named-conda-environments
Note: It is recommended to use the feature sparsely and prefer to specify a environment.yaml file instead to increase reproduceability.
I want to learn Data Science and so have used some really popular Python modules likes Pandas, Matplotlib, Numpy, etc. So I clean installed Anaconda and am now using it as my default Python interpreter and also using Conda for installing packages and making virtual environments. I use VS Code as my daily text editor. But I have run into some issues when using the integrated Git terminal in VS Code with the Anaconda Python interpreter.
There are a couple of issues that I am facing. One of the first issues that I see is when I am using CMD to run Python. If I type and enter python in cmd, the Python interpreter provided by anaconda comes up. But I also get a warning:
Warning:
This Python interpreter is in a conda environment, but the environment has not been activated. Libraries may fail to load. To activate this environment please see https://conda.io/activation
I didn't expect to get this output. Anyway, there's another problem in VS code. But first I would like to mention that I have checked "Add to PATH" when installing Anaconda so no issues there. Now, when I open a new Terminal in VS Code, automatically C:/Users/User/Anaconda3/Scripts/activate is run and then conda activate base is run. But when conda activate base is run, automatically, as mentioned, I get a CommandNotFoundError. It states Your shell has not been properly configured to use 'conda activate'.
If using 'conda activate' from a batch script, change your
invocation to 'CALL conda.bat activate'
And then I am told to initialize my shell, so I did conda init bash but still no luck. And this brings me to talk about .bash_profile. I think it has to do something with this bash profile. Anyway, this is what is in my bash profile
# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
eval "$('/C/Users/User/Anaconda3/Scripts/conda.exe' 'shell.bash' 'hook')"
# <<< conda initialize <<<
Just a summary of the problem:
Unexpected warning in CMD when running Anaconda Python interpreter
Automatically run Anaconda Scripts and conda activate base when opening new Terminal in VS Code
Conda init bash not helping
P.S I have tried using conda activate [env_name] in CMD and also in Git Bash and they work without any issues. In other words, Anaconda and Conda work perfectly outside of VS Code terminal.
I have figured out the answer myself and would like to share it here. First of all at the time of writing the question I was using Git Bash as my Terminal in VS Code (am still using it). So the issue was that when I ran the command conda init bash in Git Bash or the VS Code Terminal, Conda just basically put the command used for activating Conda environments in the .bash_profile since it is sourced during logging into Bash. But the integrated Terminal in VS Code is a subshell of a Git Bash session. That is why .bash_profile is NOT sourced in VS Code since .bash_profile is only sourced during the main Bash session. The .bashrc file is the file that is sourced when creating a Terminal session in VS Code. So what you actually need to do is take the code that is put into .bash_profile by conda init bash and paste it into your .bashrc file and make the .bash_profile source that .bashrc file automatically.
So, to sum up, using conda init bash will put the conda command in the .bash_profile and it is usually sourced by Git Bash, but VS Code Git Bash terminal will use .bashrc.
So you can just cut and paste the code from .bash_profile to .bashrc (as already mentioned) or if you want, just simply follow this: put this code in your .bash_profile:
if [ -f ~/.bashrc ]; then
source ~/.bashrc
fi
And in your .bashrc, put this code:
# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
eval "$('{path_to_your_conda.exe}' 'shell.bash' 'hook')"
# <<< conda initialize <<<
# You can get conda.exe path by using `which conda` in Git Bash
Now, when you open up a Git Bash session in VS Code Terminal, you can use conda activate env_name to activate any environments you have.
Everything is now supposed to work as expected in VS Code terminal but I would like to further elaborate about something. If you want, you can skip the conda init bash process (NOT recommended, just read on for additional knowledge but please follow the above steps only). This is a feature that was introduced in conda 4.4.0. Till then the way of activating conda environments was by using source activate but that command was NOT cross-platform, meaning that the command could not be used in OSes like Windows.
So they made this change by introducing commands like: conda activate env_name so that conda environments become much easier to use despite the OS platform.
conda activate also has other advantages. This is directly from their release docs:
conda activate: The logic and mechanisms underlying environment activation have been reworked. With conda 4.4, conda activate and conda deactivate are now the preferred commands for activating and deactivating environments. You'll find they are much more snappy than the source activate and source deactivate commands from previous conda versions. The conda activate command also has advantages of (1) being universal across all OSes, shells, and platforms, and (2) not having path collisions with scripts from other packages like Python virtualenv's activate script.
I used this question as a reference. Check it out to learn more.
Having said that, using source activate env_name will still work if you are using Git Bash, even in VS Code Git Bash terminal. source activate env_name requires no prior set up or config. But it is highly recommended that you only use conda init to set everything up and then use conda activate env_name.
[NOTE]: Locating and modifying the said .bashrc and .bash_profile on Windows is usually not as simple as it is on Linux. But can be done fairly easily like this:
It goes without saying but, you should have Git Bash installed. Having Git Bash installed should, as far as I know, automatically create .bashrc or .bash_profile or maybe both. These files are called "dotfiles" (since they start with a dot) and these are by default hidden on most OSes and definitely on Windows. If they were auto-created by Git Bash on your system, it is most likely that they are placed in your home directory. Home directory on Windows is C:\Users\<you>\. With that said, follow this:
Open Git Bash and go to your home directory with: cd. Just type this and you will be in your home directory
Enter this command: ls -a and you will see all your files, even hidden ones. Look for .bash_profile and .bashrc. Both should be present. If they are, you are ready to follow the above instructions. But if one is not there or if both are missing create them using: touch .bashrc && touch .bash_profile. You should now see these files when you again type: ls -a
That's it. Now that you have your .bashrc and .bash_profile, you can follow the above instructions. Also, to access these two files quicker, open them like this with VS Code: code ~/.bashrc or code ~/.bash_profile. Now, modify these two files as per the instructions.
In the question, I have also talked about VS Code activating Conda environments automatically. There's no issue with VS Code doing that since this is the default behavior.
I misinterpreted that as something that's an issue. But if anyone was looking to stop VS Code from automatically doing that, I would recommend trying to set this in the user settings:
"python.terminal.activateEnvironment": false
EDIT: A better solution than using source activate to get conda activate commands to work in the git bash terminal in VS Code:
Run conda init in the Git Bash Terminal in VS Code
Type in bash -l in VS Code's Git Bash terminal to launch your configured shell as a login shell
You should now be able to run conda activate commands per normal!
More info: bash -l runs your ~/.profile/~/.bash_profile/~/.zprofile scripts where the conda executable is actually referenced (but in which Git Bash as a integrated terminal does not run by default and refers to). Hence, git bash does not know where to search for conda when running conda activate commands and per Arafat's explanation above, running conda init changes the git bash PATHs in this .bash_profile file, but is ineffectual as the git bash terminal in VS Code doesn't actually refer to this file! Further info in VS Code's official docs.
Supplementing the explanation of the accepted answer, I've posted a solution that worked for me here that might possibly help others (changing user settings did not solve the issue for me). Link could also point to other working solutions if the below or accepted answer above doesn't work.
NOTE: Please read Arafat's answer before attempting the source activate method below to understand why it's not normally recommended. That said leaving it up as it still solves the problem.
Here's what worked for me using the Git Bash terminal in VS Code on
windows in succinct steps:
source activate env-name - You should see your line appended by the (base) tag now.
After calling on source activate, I've found following conda activate commands to work: i.e. conda activate env2-name
What didn't work for Git Bash (as a VS Code terminal) for me: activate
env-name and conda activate env-name.
A year later I am still running into this issue. The following is a streamlined and updated approach based on Arafat's answer.
Install Git Bash
Configure Git Bash to be used in VSC (see How do I use Bash on Windows from the Visual Studio Code integrated terminal?)
Open the git bash Terminal from VSC
If conda activate is run successfully, skip the rest
run
conda init bash
Check for the exiting bash dot files:
ls -al ~/.bash*
Likely only one of '.bashrc' and '.bash_profile' exist
Check the existing dot file for conda initialization code
e.g.
cat ~/.bash_profile
This included in my case '>>> conda initialize >>> ...' code
(But, and this is the source of the problem, it is not executed when the terminal is opened. To check which of the files is executed simple add 'echo hello-X' to each of them.)
To fix the problem, we must create the missing dot file and make it execute the OTHER previously existing one:
tee -a ~/.bashrc << END
if [ -f ~/.bash_profile ]; then
source ~/.bash_profile
fi
END
Reopen the Terminal in VSC
I am hoping to run a simple shell script to ease the management around some conda environments. Activating conda environments via conda activate in a linux os works fine in the shell but is problematic within a shell script. Could someone point me into the right direction as to why this is happening?
Example to repeat the issue:
# default conda env
$ conda info | egrep "conda version|active environment"
active environment : base
conda version : 4.6.9
# activate new env to prove that it works
$ conda activate scratch
$ conda info | egrep "conda version|active environment"
active environment : scratch
conda version : 4.6.9
# revert back to my original conda env
$ conda activate base
$ cat shell_script.sh
#!/bin/bash
conda activate scratch
# run shell script - this will produce an error even though it succeeded above
$ ./shell_script.sh
CommandNotFoundError: Your shell has not been properly configured to use 'conda activate'.
To initialize your shell, run
$ conda init <SHELL_NAME>
Currently supported shells are:
- bash
- fish
- tcsh
- xonsh
- zsh
- powershell
See 'conda init --help' for more information and options.
IMPORTANT: You may need to close and restart your shell after running 'conda init'.
I use 'source command' to run the shell script, it works:
source shell_script.sh
The error message is rather helpful - it's telling you that conda is not properly set up from within the subshell that your script is running in. To be able to use conda within a script, you will need to (as the error message says) run conda init bash (or whatever your shell is) first. The behaviour of conda and how it's set up depends on your conda version, but the reason for the version 4.4+ behaviour is that conda is dependent on certain environment variables that are normally set up by the conda shell itself. Most importantly, this changelog entry explains why your conda activate and deactivate commands no longer behave as you expect in versions 4.4 and above.
For more discussion of this, see the official conda issue on GitHub.
Edit: Some more research tells me that the conda init function mentioned in the error message is actually a new v4.6.0 feature that allows a quick environment setup so that you can use conda activate instead of the old source activate. However, the reason why this works is that it adds/changes several environment variables of your current shell and also makes changes to your RC file (e.g.: .bashrc), and RC file changes are never picked up in the current shell - only in newly created shells. (Unless of course you source .bashrc again). In fact, conda init --help says as much:
IMPORTANT: After running conda init, most shells will need to be closed and restarted for changes to take effect
However, you've clearly already run conda init, because you are able to use conda activate interactively. In fact, if you open up your .bashrc, you should be able to see a few lines added by conda teaching your shell where to look for conda commands. The problem with your script, though, lies in the fact that the .bashrc is not sourced by the subshell that runs shell scripts (see this answer for more info). This means that even though your non-login interactive shell sees the conda commands, your non-interactive script subshells won't - no matter how many times you call conda init.
This leads to a conjecture (I don't have conda on Linux myself, so I can't test it) that by running your script like so:
bash -i shell_script.sh
you should see conda activate work correctly. Why? -i is a bash flag that tells the shell you're starting to run in interactive mode, which means it will automatically source your .bashrc. This should be enough to enable you to use conda within your script as if you were using it normally.
Quick solution for bash: prepend the following init script into your Bash scripts.
eval "$(command conda 'shell.bash' 'hook' 2> /dev/null)"
Done.
For other shells, check the init conf of your shell, copy the following content within the shell conf and prepend it into your scripts.
# >>> conda initialize >>>
...
# <<< conda initialize <<<
You can also use
conda init --all --dry-run --verbose
to get the init script you need in your scripts.
Explanation
This is related with the introduction of conda init in conda 4.6.
Quote from conda 4.6 release log
Conda 4.4 allowed “conda activate envname”. The problem was that setting up your shell to use this new feature was not always straightforward. Conda 4.6 adds extensive initialization support so that more shells than ever before can use the new “conda activate” command. For more information, read the output from “conda init –help”
After conda init is introduced in conda 4.6, conda only expose command
conda into the PATH but not all the binaries from "base". And environment switch is unified by conda activate env-name and conda deactivate on all platforms.
But to make these new commands work, you have to do an additional initialization with conda init.
The problem is that your script file is run in a sub-shell, and conda is not initialized in this sub-shell.
References
Conda 4.6 Release
Unix shell initialization
Shell startup scripts
Using conda activate or source activate in shell scripts does not always work and can throw errors like this. An easy work around it to place source ~/miniconda3/etc/profile.d/conda.sh above any conda activate command in the script:
source ~/miniconda3/etc/profile.d/conda.sh # Or path to where your conda is
conda activate some-conda-environment
This is the solution that has worked for me and will also work if sharing scripts. This also gets around having to use conda init as on some clusters I have worked with the system is initialised but conda activate still won't work in a shell script.
if you want to use the shell script to run the other python file in the other conda env, just run the other file via the following command.
os.system('conda run -n <env_name> python <path_to_other_script>')
What is the problem with simply doing something like this in your shell:
source /opt/conda/etc/profile.d/conda.sh
(The conda init is still marked as Experimental, and thus not sure if it is a good idea to use it yet).
I also had the exact same error when trying to activate conda env from C++ or Python file. I solved it by bypassing the conda activate statement and using the absolute path of the specific conda env.
For me, I set up an environment called "testenv" using conda.
I searched all python environments using
whereis python | grep 'miniconda'
It returned a list of python environments. Then I ran my_python_file.py using the following command.
~/miniconda3/envs/testenv/bin/python3.8 my_python_file.py
You can do the same thing on windows too but looking up for python and conda python environments is a bit different.
This answer from Github worked for me (I'm using Ubuntu so it's not for Windows only):
eval "$(conda shell.bash hook)"
conda activate my_env
I just followed a similar solution like the one from hong-xu
So to run a shell command that calls the script with arguments and using a specific conda environment:
from a jupyter cell, goes like this :
p1 = <some-value>
run = f"conda run -n {<env-name>} python {<script-name>.py} \
--parameter_1={p1}"
!{run}
I didn't find any of the above scripts useful. These are fine if you want to run conda in non-interactive mode, but I'd like to run it in interactive mode. If I run:
conda activate my_environment
in a bash script it just runs in the script.
I found that creating an alias in .bashrc is all that is required to change directory to a particular project I'm working on, and set up the correct conda environment for me. So I included in .bashrc:
alias my_environment="cd ~/subdirectory/my_project && conda activate my_environment"
and then:
source ~/.bashrc
Then I can just type at the command line:
my_environment
to change to the correct project and correct environment everytime I want to work on a different project.
This answer is similar to #Lamma answer. This worked for me ->
(1) I defined several variables; the conda activate function, environments directory and environment
conda_activate=~/anaconda3/bin/activate
conda_envs_dir=~/anaconda3/envs
conda_env=<env name>
(2) I source conda activate with the environment
source ${conda_activate} ${conda_envs_dir}/${conda_env}
(3) then you can run your python script
python <path to script.py>
This bypasses the conda init requirement. my .bashrc already was initialized and sourcing the .bashrc file didn't work for me. #Lamma's answer worked for me as well as the above code.
The problem is that when you run the bash script, a new (linux) shell environment is created that was not initialized properly. If your intention is to activate a conda environment, and then run python through the script, you can properly initialize the created shell
environment as discussed in the accepted solution.
If however you want to have the conda environment active after you finish this script, then this will not work because the conda environment has changed on the new shell and you exit that shell when you finish the script. Think of this as running bash, then conda activate... then running exit to exit that bash... More details in How to execute script in the current shell on Linux?:
TL;DR:
Add the line #!/bin/bash as the first line of the script
Type the command source shell_script.sh or . shell_script.sh
Note: . in bash is equivalent to source in bash.
$ conda activate scratch
or
$ source activate scratch
#open terminal or CMD as administrator
$ cd <path Anaconda3 install>\Scripts
$ activate
$ cd ..
$ conda activate scratch
I'm a novice in shell scripting, but I want to make a bash script for activate/deactivate a virtual enviroment using virtualenv.
Then I want to use this script like a service in Ubuntu copying it inside /etc/init.d folder.
In my script, I have a variable like this:
VENV=/opt/odoo/odoo_server/venv_oddo/bin
This variable represents the bin path in my virtual enviroment.
Inside the script, I can activate the virtual enviroment with this statement:
. ${VENV}/activate
This is possible because activate is a file inside bin directory in the virtual enviroment.
But I don't know the statement to use in my script to deactivate my virtual enviroment.
I can't do this: . ${VENV}/deactivate
The problem is that doesn't exist a file named deactivate, but deactivated is a function inside the bin/activate file in the virtual enviroment.
Just deactivate. It will work in the script as well as in command line, as long as you're using bash.
Edit: also in most cases it is a better idea to spell full python path in your scripts and services. It is stateless, more portable and works pretty much everywhere. So instead of doing
. $VENV/bin/activate
/path/to/my/script.py --parameters
it is usually preferable to do
$VENV/bin/python /path/to/my/script --parameters
Trust me, it will save you debugging time)
It'll be hard to make a service like that useful.
. ${VENV}/activate # note the dot
or
source ${VENV}/activate
will source the activate script, i.e. run its contents as if they were part of the shell or script where you source them. virtualenvironment's activate is designed for this usage. In contrast, just executing the script normally with
${VENV}/activate # note: NO dot and NO 'source' command
will run its content in a subshell and won't have any useful effect.
However, your service script will already run in a subshell of its own. So except for any python commands you run as part of the service start process, it won't have any effect.
On the plus side, you won't even have to care about de-activating the environment, unless you want to run even more python stuff in the service start process, but outside of your virtualenv.
The deactivate "command" provided by virtualenvwrapper is actually a shell function, likewise so for workon. If you have a virtual env active, you can list the names of these functions with typeset -F.
In order to use them in a script, they need to be defined there, because shell functions do not propagate to child shells.
To define these functions, source the virtualenvwrapper.sh script in the shell script where you intend to invoke these functions, e.g.:
source $(which virtualenvwrapper.sh)
That allows you to invoke these functions in your shell script like you would do in the shell:
deactivate
Update: What I described works for the other functions provided by virtualenvwrapper (e.g. workon). I incorrectly assumed it would work also for deactivate, but that one is a more complicated case, because it is a function that will be defined only in the shell where workon or activate was run.
copy deactivate code in ${VENV}/activate.
paste your ~/.bashrc
deactivate() {
# reset old environment variables
if [ -n "$_OLD_VIRTUAL_PATH" ] ; then
PATH="$_OLD_VIRTUAL_PATH"
export PATH
unset _OLD_VIRTUAL_PATH
fi
if [ -n "$_OLD_VIRTUAL_PYTHONHOME" ] ; then
PYTHONHOME="$_OLD_VIRTUAL_PYTHONHOME"
export PYTHONHOME
unset _OLD_VIRTUAL_PYTHONHOME
fi
# This should detect bash and zsh, which have a hash command that must
# be called to get it to forget past commands. Without forgetting
# past commands the $PATH changes we made may not be respected
if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then
hash -r
fi
if [ -n "$_OLD_VIRTUAL_PS1" ] ; then
PS1="$_OLD_VIRTUAL_PS1"
export PS1
unset _OLD_VIRTUAL_PS1
fi
unset VIRTUAL_ENV
if [ ! "$1" = "nondestructive" ] ; then
# Self destruct!
unset -f deactivate
fi
}
run command.
$ $VENV/activate
$ deactivate
I have selectively used without problems python 2.7 and python 3.5 in this way.
I want to know the reason for the negative evaluation.
Somehow deactivate also can't be found in my case (usually I work under far2l inside bash). I use the solution:
unset VIRTUAL_ENV & deactivate
After that pip -V is showing path in .local.
If you only need to programatically disable / change virtualenv, you can use a shell function instead of a shell script. For example, put at the end of your ~/.bashrc or ~/.bash_aliases (if you have it set up) or ~/.zshrc or ~/.zsh_aliases (if you use zsh):
function ch() {
# change this to your directory
cd ~/git-things/my_other_py_project
# this works, as a shell function won't spawn a subshell as the script would
deactivate
# re-source to change the virtualenv (my use case; change to fit yours)
source .venv-myotherpyproject/bin/activate
}
Restart the shell or re-source the file you changed with source ~/.zsh_aliases and use the command ch to execute the function.
I recently installed the Anaconda version of Python. Now when I type python into the terminal it opens the Anaconda distribution rather than the default distribution. How do I get it to use the default version for the command python on Linux (Ubuntu 12.04 (Precise Pangolin))?
Anaconda adds the path to your .bashrc, so it is found first. You can add the path to your default Python instance to .bashrc or remove the path to Anaconda if you don't want to use it.
You can also use the full path /usr/bin/python in Bash to use the default Python interpreter.
If you leave your .bashrc file as is, any command you run using python will use the Anaconda interpreter. If you want, you could also use an alias for each interpreter.
You will see something like export PATH=$HOME/anaconda/bin:$PATH in your .bashrc file.
So basically, if you want to use Anaconda as your main everyday interpreter, use the full path to your default Python or create an alias. If you want it the other way around, remove the export PATH=.... from bashrc and use full path to Anaconda Python interpreter.
Having tried all the suggestions so far, I think modifying the export statement in file ~/.bashrc, as Piotr Dobrogost seems to suggest, is the best option considering the following:
If you remove the whole statement, you have to use full paths for Conda binaries.
Using Conda 4.4.10 links in the directory anaconda/bin/ point to binaries in the same directory, not the system ones in /usr/bin.
Using this approach you get the system programs for all that have been previously included in $PATH and also the ones specific to anaconda without using full paths.
So in file ~/.bashrc instead of
# Added by the Anaconda3 4.3.0 installer
export PATH="/home/user/anaconda3/bin:$PATH"
one would use
export PATH="$PATH:/home/user/anaconda3/bin"
I faced the same issue and you can do the following.
Go into your .bashrc file and you will find a similar sort of line:
export PATH=~/anaconda3/bin:$PATH
You comment it out and instead type out:
alias pyconda='~/anaconda3/bin/python3'
Or whatever your path is. This worked out for me.
In the year 2020, Conda adds in a more complicated block of code at the bottom of your .bash_profile file that looks something like this:
# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/Users/spacetyper/opt/miniconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
eval "$__conda_setup"
else
if [ -f "/Users/spacetyper/opt/miniconda3/etc/profile.d/conda.sh" ]; then
. "/Users/spacetyper/opt/miniconda3/etc/profile.d/conda.sh"
else
export PATH="/Users/spacetyper/opt/miniconda3/bin:$PATH"
fi
fi
unset __conda_setup
# <<< conda initialize <<<
To use the default Python install by default: Simply move this section of code to the very top of your .bash_profile file.
To give yourself the option of using the Conda installed Python: Add this line below the Conda code block above.
alias pyconda="/Users/spacetyper/opt/miniconda3/bin/python3"
Now you should be able to call the system Python install with python and the Conda install with pyconda.
at 2020, like the #spacetyper mentioned, it acted differently. I've found a handy solution for that from this question: How do I prevent Conda from activating the base environment by default?
To disable automatic base activation:
conda config --set auto_activate_base false
it'll create a ./condarc in home directory after running the first time.
I found that, though I remove export=.../anaconda3/bin:$PATH, there is still .../anaconda3/envs/py36/bin(my virtual environment in Anaconda) in PATH, and the shell still uses Anaconda Python.
So I export PATH=/usr/bin:$PATH (/usr/bin is where system Python reside). Though there is already /usr/bin inPATH, we make it searched before the path of Anaconda, and then the shell will use the system Python when you key python, python3.6, pip, pip3 ....
You can get back to Anaconda by using an alias like mentioned above, or default to Anaconda again by comment export PATH=/usr/bin:$PATH.
There are python, python2 and python2.7 shortcuts in both the /home/username/anaconda/bin/ and /usr/bin/ directory. So you can delete any one of them from one folder and use that for the other.
I mean, if you delete the python2 shortcut from the Anaconda directory, you will have the Python for Anaconda version and
python2 for the default version in the terminal.
I use Anaconda sparingly to build cross-platform packages, but I don't want to use it as my daily driver for Python. For Anaconda, Ruby, and Node.js projects I've adopted to use environment sand-boxing, which essentially hides functionality behind a function away from your path until you specifically need it. I first learned about it from these two GitHub repositories:
https://github.com/benvan/sandboxd
https://github.com/maximbaz/dotfiles
I have a file of sandboxing functions that looks like this:
.zsh/sandboxd.zsh:
#!/bin/zsh
# Based on
# https://github.com/maximbaz/dotfiles/.zsh/sandboxd.zsh
# which was originally adapted from:
# https://github.vom/benvan/sandboxd
# Start with an empty list of all sandbox cmd:hook pairs
sandbox_hooks=()
# deletes all hooks associated with cmd
function sandbox_delete_hooks() {
local cmd=$1
for i in "${sandbox_hooks[#]}";
do
if [[ $i == "${cmd}:"* ]]; then
local hook=$(echo $i | sed "s/.*://")
unset -f "$hook"
fi
done
}
# Prepares the environment and removes hooks
function sandbox() {
local cmd=$1
# NOTE: Use original grep, because aliased grep is using color
if [[ "$(type $cmd | \grep -o function)" = "function" ]]; then
(>&2 echo "Lazy-loading '$cmd' for the first time...")
sandbox_delete_hooks $cmd
sandbox_init_$cmd
else
(>&2 echo "sandbox '$cmd' not found.\nIs 'sandbox_init_$cmd() { ... }' defined and 'sandbox_hook $cmd $cmd' called?")
return 1
fi
}
function sandbox_hook() {
local cmd=$1
local hook=$2
#echo "Creating hook ($2) for cmd ($1)"
sandbox_hooks+=("${cmd}:${hook}")
eval "$hook(){ sandbox $cmd; $hook \$# }"
}
.zshrc
In my .zshrc I create my sandbox'd function(s):
sandbox_hook conda conda
This command turns the normal conda executable into:
conda () {
sandbox conda
conda $#
}
An added bonus of using this technique is that it speeds up shell loading times because sourcing a number of wrapper scripts (e.g. nvm, rvm, etc.) can slow your shell startup time.
It also bugged me that Anaconda installed its Python 3 executable as python by default, which breaks a lot of legacy Python scripts, but that's a separate issue. Using sandboxing like this makes me explicitly aware that I'm using Anaconda's Python instead of the system default.
Anaconda 3 adds more than a simple line in my .bashrc file.
However, it also backs up the original .bashrc file into a .bashrc-anaconda3.bak file.
So my solution was to swap the two.
For my case, when I had
alias python='/usr/bin/python3.6'
in the ~/.bashrc, it always called python3.6 inside and outside of Anaconda Virtual Environment.
In this setting, you could set the Python version by python3 in each Virtual Environment.