如何判断shell函数是否在virtualenv中运行?

46 投票
3 回答
30454 浏览
提问于 2025-04-17 19:21

一个 bash 函数应该如何判断自己是否在一个 Python 虚拟环境中运行呢?

我想到的两种方法是:

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

或者

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

(注意:我们希望 $INVENV 在虚拟环境中时为 1,不在时为 0,这就是上面那些回溯测试的原因。)

有没有什么更简单的方法呢?

3 个回答

1

如果你使用virtualenvwrapper,这里有一些在你创建或删除虚拟环境时会自动运行的脚本,它们可以帮你设置一个叫做INVENV的环境变量。

或者我通常做的是,把下面的内容放到你的.bashrc文件里,并在你的工作目录下创建一个叫做.venv的文件(如果你在做django的话),这样当你进入这个目录时,虚拟环境就会自动加载。

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
67
if [[ "$VIRTUAL_ENV" != "" ]]
then
  INVENV=1
else
  INVENV=0
fi
// or shorter if you like:
[[ "$VIRTUAL_ENV" == "" ]]; INVENV=$?

编辑: 正如@ThiefMaster在评论中提到的,在某些情况下(比如在一个活跃的虚拟环境中,从tmuxscreen中启动一个新的终端),这个检查可能会失败(不过,从虚拟环境中启动新的终端可能还会引发其他问题,我不太推荐这样做)。

18

其实,我刚刚找到一个类似的问题,从中可以很容易得出这个问题的答案:

Python:判断是否在虚拟环境中运行

比如,一个 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")')

撰写回答