How can a shell function know if it is running within a virtualenv?

Question:

How should a bash function test whether it is running inside a Python virtualenv?

The two approaches that come to mind are:

[[ "$(type -t deactivate)" != function ]]; INVENV=$?

or

[[ "x$(which python)" != "x$VIRTUAL_ENV/bin/python" ]]; INVENV=$?

(Note: wanting $INVENV to be 1 if we’re inside a virtualenv, and 0 otherwise, is what forces the backward-looking tests above.)

Is there something less hacky?

Asked By: kjo

||

Answers:

if [[ "$VIRTUAL_ENV" != "" ]]
then
  INVENV=1
else
  INVENV=0
fi
// or shorter if you like:
[[ "$VIRTUAL_ENV" == "" ]]; INVENV=$?

EDIT: as @ThiefMaster mentions in the comments, in certain conditions (for instance, when starting a new shell – perhaps in tmux or screen – from within an active virtualenv) this check may fail (however, starting new shells from within a virtualenv may cause other issues as well, I wouldn’t recommend it).

Answered By: robertklep

If you use virtualenvwrappers there are pre/post scripts that run that could set INVENV for you.

Or what I do, put the following in your your .bashrc, and make a file called .venv in your working directory (for django) so that the virtual env is automatically loaded when you cd into the directory

export PREVPWD=`pwd`
export PREVENV_PATH=

handle_virtualenv(){
    if [ "$PWD" != "$PREVPWD" ]; then
        PREVPWD="$PWD";
        if [ -n "$PREVENV_PATH" ]; then
            if [ "`echo "$PWD" | grep -c $PREVENV_PATH`" = "0"  ]; then
                deactivate
                unalias python 2> /dev/null
                PREVENV_PATH=
            fi
        fi

        # activate virtualenv dynamically
        if [ -e "$PWD/.venv" ] && [ "$PWD" != "$PREVENV_PATH" ]; then
            PREVENV_PATH="$PWD"
            workon `basename $PWD`
            if [ -e "manage.py" ]; then
                alias python='python manage.py shell_plus'
            fi
        fi
    fi
}

export PROMPT_COMMAND=handle_virtualenv
Answered By: Kurt

Actually, I just found a similar question, from which one can easily derive an answer to this one:

Python: Determine if running inside virtualenv

E.g., a shell script can use something like

python -c 'import sys; print (sys.real_prefix)' 2>/dev/null && INVENV=1 || INVENV=0

(Thanks to Christian Long for showing how to make this solution work with Python 3 also.)

EDIT: Here’s a more direct (hence clearer and cleaner) solution (taking a cue from JuanPablo’s comment):

INVENV=$(python -c 'import sys; print ("1" if hasattr(sys, "real_prefix") else "0")')
Answered By: kjo
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.