2467

I'm using virtualenv and the virtualenvwrapper. I can switch between virtualenv's just fine using the workon command.

me@mymachine:~$ workon env1
(env1)me@mymachine:~$ workon env2
(env2)me@mymachine:~$ workon env1
(env1)me@mymachine:~$ 

How do I exit all virtual environments and work on my system environment again? Right now, the only way I have of getting back to me@mymachine:~$ is to exit the shell and start a new one. That's kind of annoying. Is there a command to work on "nothing", and if so, what is it? If such a command does not exist, how would I go about creating it?

Timur Shtatland
  • 12,024
  • 2
  • 30
  • 47
Apreche
  • 30,042
  • 8
  • 41
  • 52
  • 8
    There is a command to workon "nothing" - it displays all your available virtual environments, which is pretty nifty. Just type "workon" with no arguments and hit enter. The command to leave is "deactivate", as answered below. – Dannid Oct 07 '14 at 20:47
  • Does closing the shell deactivate all the environments used the shell session. Just wanted to get an idea if it modifies the path env variable of the windows and just leaves it like that once the shell is closed ? – Mukesh Mahadev Apr 26 '21 at 07:54
  • 1
    @MukeshMahadev Yes, activation is only for the current shell. – Apreche Apr 26 '21 at 13:50

16 Answers16

3959

Usually, activating a virtualenv gives you a shell function named:

$ deactivate

which puts things back to normal.

I have just looked specifically again at the code for virtualenvwrapper, and, yes, it too supports deactivate as the way to escape from all virtualenvs.

If you are trying to leave an Anaconda environment, the command depends upon your version of conda. Recent versions (like 4.6) install a conda function directly in your shell, in which case you run:

conda deactivate

Older conda versions instead implement deactivation using a stand-alone script:

source deactivate
Brandon Rhodes
  • 83,755
  • 16
  • 106
  • 147
  • 206
    The “deactivate” command is not a binary, nor a script that you “source”; it is a shell alias that gets defined dynamically in your current shell by the “activate” script. – Brandon Rhodes Feb 06 '13 at 22:28
  • 7
    @Apreche In the meantime (almost four years later) this appears to have been [added](http://virtualenvwrapper.readthedocs.org/en/latest/command_ref.html#deactivate) to the documentation. – gertvdijk Mar 14 '13 at 14:26
  • 8
    Would be much more intuitive if it were called "workoff" or "unworkon". Or if "workon" were called "activate". Thank goodness for alias. – kkurian Jun 18 '13 at 17:54
  • 7
    @kkurian — you should suggest that on the issue tracker for `virtualenvwrapper` and maybe Doug Hellmann would consider it! Note, for those who might read these comments later, that `workon` is **NOT** a native `virtualenv` command (which is what the original question is about) but a `virtualenvwrapper` command! – Brandon Rhodes Jun 29 '13 at 23:42
  • 2
    @BrandonRhodes to be exact, it is not an alias, it's a function – igor Sep 17 '13 at 15:00
  • 28
    Guess what the actual virtualenv command inside of "workon" is called? ...(spoiler warning)... ...(spoiler warning)... ...(spoiler warning)... ...(spoiler warning)... activate! – FutureNerd Mar 20 '14 at 05:18
  • 2
    What a f**cked up way of doing things!! Why is Python deciding that the word `deactivate` only belongs to it? – Snowcrash May 05 '22 at 13:59
  • Groan again. The second time I've encountered this. – Snowcrash Nov 18 '22 at 11:33
129

Use:

$ deactivate 

If this doesn't work, try

$ source deactivate

Anyone who knows how Bash source works will think that's odd, but some wrappers/workflows around virtualenv implement it as a complement/counterpart to source activate. Your mileage may vary.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
DarkRider
  • 1,445
  • 1
  • 9
  • 4
  • 17
    `deactivate` is a function that gets created when you source the `activate` file. Your suggestion to do `source deactivate` doesn't make sense at all, as there is no file named `deactivate` – Anthon Apr 12 '15 at 08:14
  • 15
    This doesn't deserve the downvotes. See edit of selected response: source deactivate is for the anaconda environment. – Doug Bradshaw Nov 13 '15 at 19:52
  • 5
    It "deserves" downvotes for not meeting the SO **answer** quality standards. It's more of a comment than an answer. But, because of the 79 reputation of the poster, we should be nice and give good feedback. – Bruno Bronosky Mar 17 '17 at 15:22
  • @Abdul I have demonstrated how you can improve your answer quality in Revision 2 at http://stackoverflow.com/posts/29586756/revisions – Bruno Bronosky Mar 17 '17 at 15:30
  • this is very unhelpful if you don't have a deactivate command in your shell. I don't really understand why this would help the problem. There is no deactivate script in the virtual env. – bgenchel Feb 28 '18 at 06:26
  • @Anthon However, "source deactivate" works for me but "deactivate" doesn't – Statham Apr 08 '18 at 08:20
  • @Statham are you running that non-standard Anaconda installer? – Anthon Apr 08 '18 at 10:16
  • @Anthon yeah, I have both anaconda2 and anaconda3 on my computer, so i have to run that, and maybe that's the reason – Statham Apr 09 '18 at 08:01
66

I defined an alias, workoff, as the opposite of workon:

alias workoff='deactivate'

It is easy to remember:

[bobstein@host ~]$ workon django_project
(django_project)[bobstein@host ~]$ workoff
[bobstein@host ~]$
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Bob Stein
  • 16,271
  • 10
  • 88
  • 101
37

To activate a Python virtual environment:

$cd ~/python-venv/
$./bin/activate

To deactivate:

$deactivate
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Amitesh Ranjan
  • 1,162
  • 1
  • 12
  • 9
28

Running deactivate [name of your environment] is able to exit/deactivate from your python environment.

Example with python3.6 Windows 10 in PowerShell:

PS C:\Users\kyrlon\Desktop> py -m venv env1
PS C:\Users\kyrlon\Desktop> .\env1\Scripts\activate
(env1) PS C:\Users\kyrlon\Desktop> deactivate env1
PS C:\Users\kyrlon\Desktop> py -m venv env1

Example with python3.9 on Linux Ubuntu 20.04 LTS Desktop:

kyrlon@pc1:~$ python3 -m venv venv1
kyrlon@pc1:~$ source venv1/bin/activate
(venv1) kyrlon@pc1:~$ deactivate venv1
kyrlon@pc1:~$
kyrlon
  • 1,065
  • 2
  • 8
  • 16
  • I had a curious situation where I couldn't deactivate, so solution wise I just closed the terminal in that situation. However, thanks for mentioning that explicitly naming the python venv also works. I don't if it would have worked, since I can't reproduce the original issue, but I just tested that this works on its own on Python 3.11 as well – Ahmad Bilal Aug 29 '23 at 11:54
10

I found that when within a Miniconda3 environment I had to run:

conda deactivate

Neither deactivate nor source deactivate worked for me.

CephBirk
  • 6,422
  • 5
  • 56
  • 74
  • 2
    `deactivate` was for `virtualenv`, and `source deactivate` is for old conda on Linux. `conda deactivate` is a good cross-platform way for conda envs (not virtualenvs) – Tomasz Gandor Feb 13 '20 at 14:10
9

You can use virtualenvwrapper in order to ease the way you work with virtualenv.

Installing virtualenvwrapper:

pip install virtualenvwrapper

If you are using a standard shell, open your ~/.bashrc or ~/.zshrc if you use Oh My Zsh. Add these two lines:

export WORKON_HOME=$HOME/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh

To activate an existing virtualenv, use command workon:

$ workon myenv
(myenv)$

In order to deactivate your virtualenv:

(myenv)$ deactivate

Here is my tutorial, step by step on how to install virtualenv and virtualenvwrapper.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
levi
  • 22,001
  • 7
  • 73
  • 74
  • 2
    I see little difference compared to built-in virtualenv – Nam G VU Sep 08 '16 at 11:35
  • 1
    @NamGVU Notice the `workon` command, it works from any directory. – igauravsehrawat Sep 28 '16 at 07:44
  • 1
    As mentioned in another post's comment (and Stackoverflow doesn't have a practical way to point to it) you cannot use `deactivate` in a shell script without first sourcing the script that defines this function (in that case you will have that _command not found..._ error) – Mariano Ruiz Feb 25 '19 at 14:33
  • @levi I think it is "deactivate myenv" instead (not simple "deactivate") – ppuschmann Oct 14 '22 at 10:42
9

For my particular case, I go to to the working directory

CD /myworkingdirectory

Then I activate my env like this:

my-env/scripts/activate

From this same working folder (/myworkingdirectory) to deactivate, I tried this but it does nothing:

my-env/scripts/deactivate

This does work:

deactivate
Nick.Mc
  • 18,304
  • 6
  • 61
  • 91
8

Using the deactivate feature provided by the venv's activate script requires you to trust the deactivation function to be properly coded to cleanly reset all environment variables back to how they were before— taking into account not only the original activation, but also any switches, configuration, or other work you may have done in the meantime.

It's probably fine, but it does introduce a new, non-zero risk of leaving your environment modified afterwards.

However, it's not technically possible for a process to directly alter the environment variables of its parent, so we can use a separate sub-shell to be absolutely sure our venvs don't leave any residual changes behind:


To activate:

$ bash --init-file PythonVenv/bin/activate

  • This starts a new shell around the venv. Your original bash shell remains unmodified.

To deactivate:

$ exit OR [CTRL]+[D]

  • This exits the entire shell the venv is in, and drops you back to the original shell from before the activation script made any changes to the environment.

Example:

[user@computer ~]$ echo $VIRTUAL_ENV
No virtualenv!

[user@computer ~]$ bash --init-file PythonVenv/bin/activate

(PythonVenv) [user@computer ~]$ echo $VIRTUAL_ENV
/home/user/PythonVenv

(PythonVenv) [user@computer ~]$ exit
exit

[user@computer ~]$ echo $VIRTUAL_ENV
No virtualenv!
Will Chen
  • 482
  • 4
  • 12
6

$ conda deactivate
or
$ source deactivate
would work.

If it doesn't work, try deactivate [name of your environment] instead.

Léo
  • 89
  • 1
  • 11
5

In MacOs ventura -

to activate -

 sudo chmod -R 755  ./venv/bin
 source venv/bin/activate    

to deactivate -

deactivate
user51
  • 8,843
  • 21
  • 79
  • 158
4

Since the deactivate function created by sourcing ~/bin/activate cannot be discovered by the usual means of looking for such a command in ~/bin, you may wish to create one that just executes the function deactivate.

The problem is that a script named deactivate containing a single command deactivate will cause an endless loop if accidentally executed while not in the venv. A common mistake.

This can be avoided by only executing deactivate if the function exists (i.e. has been created by sourcing activate).

#!/bin/bash

declare -Ff deactivate  && deactivate
DocSalvager
  • 2,156
  • 1
  • 21
  • 28
3

I use zsh-autoenv which is based off autoenv.

zsh-autoenv automatically sources (known/whitelisted) .autoenv.zsh files, typically used in project root directories. It handles "enter" and leave" events, nesting, and stashing of variables (overwriting and restoring).

Here is an example:

; cd dtree 
Switching to virtual environment: Development tree utiles
;dtree(feature/task24|✓); cat .autoenv.zsh       
# Autoenv.
echo -n "Switching to virtual environment: "
printf "\e[38;5;93m%s\e[0m\n" "Development tree utiles"
workon dtree
# eof
dtree(feature/task24|✓); cat .autoenv_leave.zsh 
deactivate

So when I leave the dtree directory, the virtual environment is automatically exited.

"Development tree utiles" is just a name… No hidden mean linking to the Illuminati in here.

Sardathrion - against SE abuse
  • 17,269
  • 27
  • 101
  • 156
3

I my case, I was able to activate virtual environment using env-name\scripts\activate and deactivate it using deactivate. However, after running update on my windows PC deactivate was no longer recognized as an internal or external command. What I used from that moment onward is env-name\scripts\deactivate and that solved the problem.

C-Bizz
  • 624
  • 9
  • 25
0

I had the same problem while working on an installer script. I took a look at what the bin/activate_this.py did and reversed it.

Example:

#! /usr/bin/python
# -*- coding: utf-8 -*-
import os
import sys

# Path to virtualenv
venv_path = os.path.join('/home', 'sixdays', '.virtualenvs', 'test32')

# Save old values
old_os_path = os.environ['PATH']
old_sys_path = list(sys.path)
old_sys_prefix = sys.prefix


def deactivate():
    # Change back by setting values to starting values
    os.environ['PATH'] = old_os_path
    sys.prefix = old_sys_prefix
    sys.path[:0] = old_sys_path


# Activate the virtualenvironment
activate_this = os.path.join(venv_path, 'bin/activate_this.py')
execfile(activate_this, dict(__file__=activate_this))


# Print list of pip packages for virtualenv for example purpose
import pip
print str(pip.get_installed_distributions())

# Unload pip module
del pip

# Deactivate/switch back to initial interpreter
deactivate()

# Print list of initial environment pip packages for example purpose
import pip
print str(pip.get_installed_distributions())

I am not 100% sure if it works as intended. I may have missed something completely.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Lord Sumner
  • 573
  • 5
  • 6
  • 2
    if deactivate resets value of environment path, system path, default prompt then your deactivate function is good approach. I like your script. Already given +1. – Ramkumar D Jun 06 '16 at 08:00
0

If you don't know how to exit some python environment I would just run

bash --norc

as there is a risk you missed deleting that code for entering to some python environment, which something such as conda/mamba already installed into your .bashrc The conda/mamba enters environments the same way you can run bash inside bash. Default installation forces base environment to be activated by default, which drives me crazy as it might break lot of things, to exit it you just type

mamba deactivate

But you can configure conda in a way that you activate it only when you use it. Then if you e.g. type

mamba activate env
(env)mamba activate base
(base)mamba activate base
(base)mamba activate xy

You will actually be in nested environment (xy) and (xy) -deactivate-> (base) -deactivate-> (base) -deactivate-> (env) -deactivate-> no conda/mamba.

So if you are in some environment, do not know how much nested it is and you want to get base environment, you can also use

mamba activate base
VojtaK
  • 483
  • 4
  • 13