36

一个函数应该如何bash测试它是否在 Python virtualenv 中运行?

想到的两种方法是:

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

或者

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

(注意:$INVENV如果我们在 virtualenv 中,则希望为 1,否则为 0,这会迫使上述向后看的测试。)

有什么不那么骇人听闻的吗?

4

3 回答 3

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

编辑:正如@ThiefMaster 在评论中提到的那样,在某些情况下(例如,当启动一个新的 shell 时——可能在tmuxscreen从活动的 virtualenv 中)这个检查可能会失败(但是,从 virtualenv 中启动新的 shell 可能会导致其他也有问题,不推荐)。

于 2013-03-16T20:20:04.563 回答
19

实际上,我刚刚发现了一个类似的问题,从中可以很容易地得出这个问题的答案:

Python:确定是否在 virtualenv 中运行

例如,shell 脚本可以使用类似的东西

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

(感谢 Christian Long 展示了如何使这个解决方案也适用于 Python 3。)

编辑:这是一个更直接(因此更清晰和更清洁)的解决方案(从 JuanPablo 的评论中得到提示):

INVENV=$(python -c 'import sys; print ("1" if hasattr(sys, "real_prefix") else "0")')
于 2013-03-16T21:28:41.390 回答
1

如果您使用 virtualenvwrappers,则运行的前/后脚本可以为您设置 INVENV。

或者我做什么,将以下内容放入您的 .bashrc 中,并在您的工作目录(用于 django)中创建一个名为 .venv 的文件,以便在您 cd 进入目录时自动加载虚拟环境

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
于 2013-03-16T20:40:10.000 回答