Issue #219 invalid

Can't deactivate active virtualenv from bash script

created an issue

I'm writing a bash script that attempts to do a global install of virtualenv and virtualenvwrapper if they don't already exist. This was my original idea to make sure we don't install the packages to an active virtualenv:

if [[ ! -z $VIRTUAL_ENV ]]; then

pip install virtualenv virtualenvwrapper

The problem is, if you are currently inside of a virtualenv activated with workon <env>, bash reports

deactivate: command not found

Well, you might think you could just source the file that defines deactivate:

if [[ ! -z $VIRTUAL_ENV ]]; then
  if [[ -r /usr/local/bin/ ]]; then
    source /usr/local/bin/

pip install virtualenv virtualenvwrapper

Except that within the context of an active virtualenv (e.g. when [[ ! -z $VIRTUAL_ENV ]] would be true), you don't have access to the virtualenvwrapper module. Now I see

/path/to/virtualenv/bin/python: No module named virtualenvwrapper

Any ideas on how to get around this catch-22?

Comments (4)

  1. Doug Hellmann repo owner

    Shell functions aren't exported to subshells (and scripts) by default, but you can use a variation of the "export" command to export them. Sourcing won't help, since deactivate is defined when workon is run (actually when the activate script for the env is run as part of that).

    What case do you have where the script is being run inside a virtualenv?

  2. michaelxor reporter

    It's unlikely that the script will be run inside a virtualenv, this was more a precaution to prevent that scenario.

    This is part of a dotfiles project and it's intended to bootstrap a python environment for a new machine. After the virtualenvwrapper install, a default virtualenv is created and provisioned with a bundled requirements.txt file. Here's a link to the full script:

    Some custom utility functions are not included but hopefully their purpose is clear. The idea is that this script would provision the machine the first time it's run, but be able to keep the default virtualenv up to date if it's run periodically after that. I discovered the issue when testing some changes to this script while a virtualenv was active (noticing that deactivate failed).

    Thanks for the input. After reading your comment I verified that this won't work with a standard virtualenv (independent of virtualenvwrapper) either, so it looks like this is a non-issue.

    If you have any tips on a clean way to deactivate a virtualenv inside of a script (without editing virtualenv / virtualenvwrapper source code), it would be greatly appreciated!

    Edit: my current working solution is to abort on detecting an active virtualenv

  3. Doug Hellmann repo owner

    Rather than using workon, if you source the activate script in the environment you'll have the deactivate function in the local shell and can call that directly.

  4. Log in to comment