如何在bash
函数中测试是否运行在Python虚拟环境中?
有两种方法:
[[ "$(type -t deactivate)" != function ]]; INVENV=$?
或者
[[ "x$(which python)" != "x$VIRTUAL_ENV/bin/python" ]]; INVENV=$?
(注:希望如果我们在虚拟环境内部时
$INVENV
为1,否则为0,这就是上面的后向测试所强制要求的。)有没有更少hacky的方法?如何在bash
函数中测试是否运行在Python虚拟环境中?
有两种方法:
[[ "$(type -t deactivate)" != function ]]; INVENV=$?
或者
[[ "x$(which python)" != "x$VIRTUAL_ENV/bin/python" ]]; INVENV=$?
$INVENV
为1,否则为0,这就是上面的后向测试所强制要求的。)有没有更少hacky的方法?if [[ "$VIRTUAL_ENV" != "" ]]
then
INVENV=1
else
INVENV=0
fi
// or shorter if you like:
[[ "$VIRTUAL_ENV" == "" ]]; INVENV=$?
编辑:正如@ThiefMaster在评论中提到的,在某些情况下(例如,在活动的虚拟环境中启动新的 shell 时,可能在tmux
或screen
中),此检查可能会失败(但是,从虚拟环境内部启动新的 shell 也可能会导致其他问题,我不推荐这样做)。
$PATH
与此有何关系?或者您是想检查当前工作目录是否属于 virtualenv 的一部分? - robertklep$VIRTUAL_ENV
不在 $PATH
中,那么其他所有程序使用的 python
可执行文件将不是虚拟环境中的文件。仅仅给 $VIRTUAL_ENV
赋值并不能起到任何作用。 - kjo$VIRTUAL_ENV
赋值,它只是检查它。当它存在时,这意味着一个虚拟环境是活动的(该变量由 activate
脚本设置并由 deactivate
取消设置)。这不就是你想要的吗? - robertklep其实我刚找到一个类似的问题,从那里很容易得出这个问题的答案:
例如,一个 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")')
python -c 'import sys; print hasattr(sys, "real_prefix")'
- JuanPablopython -c 'import sys; print(sys.real_prefix)' 2>/dev/null && INVENV=1 || INVENV=0
。 - Christian Longpython3 -m venv venv
)没有sys.real_prefix
属性。这个作为替代方案是否可行? INVENV=$( python -c 'import sys ; print( 0 if sys.prefix == sys.base_prefix else 1 )' )
- BrendanSimonint()
,而不是使用 if 语句:INVENV=$(python3 -c 'import sys; print(int(hasattr(sys, "real_prefix")))')
但是,当从简单的 bash 脚本运行时,我无法确认脚本是否正在使用 venv。下面的答案使用 $VIRTUAL_ENV
变量(由 activate
脚本设置)确定了这一点。 - Dostrelithexport 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
OLDPWD
,这与你代码中的PREVPWD
是相同的东西。 - kjo
command -v
的shell内置命令。 - phk