How can I check I'm not in a virtualenv before sourcing virtualenvwrapper commands in bash?

StackOverflow https://stackoverflow.com/questions/19376356

  •  30-06-2022
  •  | 
  •  

質問

I am sourcing virtualenvwrapper so that I can use virtualenvwrapper functions in a bash script, as in the following simplified example:

Running do_some ve_name branch_name calls:

#! /bin/bash
# some script that takes parameters

source /etc/bash_completion.d/virtualenvwrapper # the magic of sourcing
workon $1 # pick a venv
cd /some/project/path
git checkout $2 # pick a branch
python do_something.py

This works (and I don't mind dropping out of the virtual environment once it ends, in fact I prefer it). However, if I am already in a virtual environment I get the following:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: No module named virtualenvwrapper.hook_loader
virtualenvwrapper.sh: There was a problem running the initialization hooks. If Python could not import the module virtualenvwrapper.hook_loader, check that virtualenv has been installed for VIRTUALENVWRAPPER_PYTHON=/home/username/.virtualenvs/ve_name/bin/python and that PATH is set properly.
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: No module named virtualenvwrapper.hook_loader
    Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: No module named virtualenvwrapper.hook_loader

So let's just assume that I will occassionally forget to deactivate my current virtualenv. I tried resolving this as follows:

#! /bin/bash
# some advanced script that takes parameters

deactivate
source /etc/bash_completion.d/virtualenvwrapper # the magic of sourcing
workon $1 # pick a venv
...

But whether or not I am currently in a virtualenv, I get the following error (and it doesn't deactivate if I am accidentally in a virtualenv, which is the problem I want to solve):

/path/to/scripts/do_some: line 4: deactivate: command not found

So, how can I protect against already being in a virtualenv before sourcing virtualenvwrapper commands?

役に立ちましたか?

解決 2

If I understand it correct, the function workon is defined by the virtualenvwrapper. You could check if the function is defined before attempting to source the wrapper.

Replace your source command with the following:

[[ $(type -t workon) == "function" ]] || source /etc/bash_completion.d/virtualenvwrapper

他のヒント

You might also try using the VIRTUAL_ENV environment variable as well. I found this to be a clearer solution after viewing this, so I thought I'd leave a note in case this is reaching others searching for similar solutions.

E.g.,

if [ ${VIRTUAL_ENV} ]
    then
        # do some stuff
fi

Here's the relevant portion of the deactivate function in the activate script:

# (inside deactivate function)
unset VIRTUAL_ENV
if [ ! "$1" = "nondestructive" ] ; then
# Self destruct!
    unset -f deactivate
fi

Here's how that gets set when you originally source the file:

# (runs when you source the activate file)
VIRTUAL_ENV="/path/to/venv/dir"
export VIRTUAL_ENV

This may not solve the original question (didn't test), but it's helpful for a large subset of cases where you just need to know if you're in a virtualenv or not.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top