如何在进入目录时自动激活 virtualenvs
How to automatically activate virtualenvs when cd'ing into a directory
我的 ~/Documents
中有很多项目。我几乎只在 python 工作,所以这些基本上都是 python 项目。每一个,例如~/Documents/foo
有自己的 virtualenv,~/Documents/foo/venv
(它们总是被称为 venv)。每当我在项目之间切换时,每天大约 10 次,我都会
deactivate
cd ..
cd foo
source venv/bin/activate
我已经厌倦了输入 deactivate
和 source venv/bin/activate
。 我正在寻找一种方法 cd ../foo
并为我处理 virtualenv 操作。
我熟悉VirtualEnvWrapper,我认为这有点笨拙。据我所知,它似乎将您所有的 virtualenvs 都移到了其他地方,并且增加了比它删除的复杂性更多的复杂性。 (欢迎不同意见!)
我不太熟悉 shell 脚本。如果您可以推荐一个低维护脚本添加到我的 ~/.zshrc
来完成此任务,那就足够了,但是通过快速谷歌搜索,我还没有找到这样的脚本。
我是 zsh
/oh-my-zsh
用户。 oh-my-zsh
似乎没有这方面的插件。这个问题的最佳答案是有人贡献了一个 oh-my-zsh
插件来做到这一点。 (如果这里的答案乏善可陈,我可能会这样做。
在你的 .zshrc 中加入这样的东西
function cd() {
if [[ -d ./venv ]] ; then
deactivate
fi
builtin cd
if [[ -d ./venv ]] ; then
. ./venv/bin/activate
fi
}
编辑:如评论中所述cd
-进入当前虚拟环境的子文件夹将停用它。一个想法可能是仅当 cd
进入新环境时才停用当前环境,例如
function cd() {
builtin cd
if [[ -n "$VIRTUAL_ENV" && -d ./venv ]] ; then
deactivate
. ./venv/bin/activate
fi
}
仍然可以改进,也许将其变成文件夹名称上的 "prompt command" 或 attempting some prefix matching 以检查路径上某处是否存在虚拟环境,但我的 shell- fu 不够好。
在您的 .bashrc 或 .zshrc 中添加以下内容
function cd() {
builtin cd "$@"
if [[ -z "$VIRTUAL_ENV" ]] ; then
## If env folder is found then activate the vitualenv
if [[ -d ./.env ]] ; then
source ./.env/bin/activate
fi
else
## check the current folder belong to earlier VIRTUAL_ENV folder
# if yes then do nothing
# else deactivate
parentdir="$(dirname "$VIRTUAL_ENV")"
if [[ "$PWD"/ != "$parentdir"/* ]] ; then
deactivate
fi
fi
}
即使有人进入子文件夹,此代码也不会停用 virtualenv。灵感来自 and @Gilles.
的答案
如果virtualenv是pipenv制作的,请考虑this wiki page。
此外,为了增加安全性,请考虑 direnv。
您可以使用 direnv. It's not a zsh specific solution (for that you could try zsh-autoenv) 而不是编写自定义脚本,但维护良好且易于与 zsh 一起使用。安装后,您需要将 eval "$(direnv hook zsh)"
放在 .zshrc
的末尾。那时你可以这样做:
$ source ~/.zshrc
$ cd foo
$ echo "layout python" > .envrc
direnv: error .envrc is blocked. Run `direnv allow` to approve its content.
$ direnv allow
direnv: loading .envrc
direnv: export +VIRTUAL_ENV ~PATH
现在你应该在你的虚拟环境中了。您可以通过 运行 pip freeze
进行测试以查看您的 virtualenv 特定包是否已安装。停用
$ cd ..
direnv: unloading
这是我的解决方案,其中:
- 检查是否已经处于当前活动状态
venv
,在这种情况下什么都不做
- 如果有
venv
文件夹,如果有 则停用活动文件夹
- 激活新的
venv
无论是否有旧的。
在我的 bash_aliases
中:
function cd() {
builtin cd "$@"
if [ $(dirname "$VIRTUAL_ENV") == $(pwd) ] ; then
# Already at the active virtual env
return
fi
if [[ -d ./venv ]] ; then
if type deactivate > /dev/null 2>&1 ; then
printf "Deactivating virtualenv %s\n" "$VIRTUAL_ENV"
deactivate
fi
source ./venv/bin/activate
printf "Setting up virtualenv %s\n" "$VIRTUAL_ENV"
fi
}
为了后代:我使用了@MS_ 的解决方案,但 运行 遇到了 cd
直接从一个项目到另一个项目停用旧 virtualenv 但不激活新 virtualenv 的问题。这是解决此问题的解决方案的略微修改版本:
# auto activate virtualenv
# Modified solution based on
function cd() {
builtin cd "$@"
## Default path to virtualenv in your projects
DEFAULT_ENV_PATH="./env"
## If env folder is found then activate the vitualenv
function activate_venv() {
if [[ -f "${DEFAULT_ENV_PATH}/bin/activate" ]] ; then
source "${DEFAULT_ENV_PATH}/bin/activate"
echo "Activating ${VIRTUAL_ENV}"
fi
}
if [[ -z "$VIRTUAL_ENV" ]] ; then
activate_venv
else
## check the current folder belong to earlier VIRTUAL_ENV folder
# if yes then do nothing
# else deactivate then run a new env folder check
parentdir="$(dirname ${VIRTUAL_ENV})"
if [[ "$PWD"/ != "$parentdir"/* ]] ; then
echo "Deactivating ${VIRTUAL_ENV}"
deactivate
activate_venv
fi
fi
}
这是没有 cd'ing 的解决方案,将 zsh 设置为 setop auto_cd
将能够在没有 cd 的情况下更改目录,只需键入目录名称并点击进入。
它是上述解决方案的结果:
# auto activate virtualenv
# Modified solution based on
function auto_active_env() {
## Default path to virtualenv in your projects
DEFAULT_ENV_PATH="./env"
## If env folder is found then activate the vitualenv
function activate_venv() {
if [[ -f "${DEFAULT_ENV_PATH}/bin/activate" ]] ; then
source "${DEFAULT_ENV_PATH}/bin/activate"
echo "Activating ${VIRTUAL_ENV}"
fi
}
if [[ -z "$VIRTUAL_ENV" ]] ; then
activate_venv
else
## check the current folder belong to earlier VIRTUAL_ENV folder
# if yes then do nothing
# else deactivate then run a new env folder check
parentdir="$(dirname ${VIRTUAL_ENV})"
if [[ "$PWD"/ != "$parentdir"/* ]] ; then
echo "Deactivating ${VIRTUAL_ENV}"
deactivate
activate_venv
fi
fi
}
chpwd_functions=(${chpwd_functions[@]} "auto_active_env")
这是(又)另一种自动激活虚拟环境的解决方案;它基于此处已发布的许多答案。
这将适用于 任何 虚拟环境名称或目录(不仅仅是 ./env
、./venv
等)。还支持子目录,以及 cd
-ing 到虚拟环境(父)文件夹的符号链接。
此代码搜索 pyvenv.cfg
文件而不是特定的命名目录。如果在当前文件夹的子目录中找到一个,环境将自动激活。一旦进入虚拟环境,该状态将一直保留,直到您移出父虚拟环境目录,此时环境将被停用。
将此放在您的 .bashrc
或 .bash_profile
中。
function cd() {
builtin cd "$@"
if [[ -z "$VIRTUAL_ENV" ]] ; then
# If config file is found -> activate the vitual environment
venv_cfg_filepath=$(find . -maxdepth 2 -type f -name 'pyvenv.cfg' 2> /dev/null)
if [[ -z "$venv_cfg_filepath" ]]; then
return # no config file found
fi
venv_filepath=$(cut -d '/' -f -2 <<< ${venv_cfg_filepath})
if [[ -d "$venv_filepath" ]] ; then
source "${venv_filepath}"/bin/activate
fi
else
# If the current directory is not contained
# within the venv parent directory -> deactivate the venv.
cur_dir=$(pwd -P)
venv_dir="$(dirname "$VIRTUAL_ENV")"
if [[ "$cur_dir"/ != "$venv_dir"/* ]] ; then
deactivate
fi
fi
}
我个人认为这是对此处许多解决方案的改进,因为它适用于任何虚拟环境
这是我的解决方案:
- 如果未设置 VIRTUAL_ENV,则:
- 检查我们是否在虚拟环境中
- 如果是,则激活它
- Else(定义了VIRTUAL_ENV),检查当前文件夹是否以$VIRTUAL_ENV开头(去掉
/venv
部分)并验证deactivate命令是否存在
- 停用环境
这是脚本:
function cd() {
builtin cd
if [[ -z "${VIRTUAL_ENV}" ]]; then
if [[ -d ./venv && -f ./venv/bin/activate ]]; then
source ./venv/bin/activate
fi
elif [[ ! "$(pwd)" == ${VIRTUAL_ENV:0:n-5}* && ! -z "$(command -v deactivate)" ]]; then
deactivate
fi
}
注意:您需要将此添加到.bashrc
。如果它不起作用,请检查你的 .profile
是否没有覆盖你的命令(它发生在我身上)
基于@MS_的解决方案:
function cd() {
builtin cd "$@"
## If env folder is found then activate the vitualenv
if [[ -d ./venv ]] ; then
source ./venv/bin/activate
fi
if [[ -n "$VIRTUAL_ENV" ]] ; then
## check the current folder belong to earlier VIRTUAL_ENV folder
# if yes then do nothing
# else deactivate
parentdir="$(dirname "$VIRTUAL_ENV")"
if [[ "$PWD"/ != "$parentdir"/* ]] ; then
deactivate
fi
fi
}
到目前为止最简单的选择(在 2019 年以后)是将 virtualenvwrapper
添加到您的 ~/.zshrc
plugins
例如:
plugins=(
git pip python brew virtualenvwrapper
)
第一个被认为是“轻量级”,而第二个“简单,更高质量的软件”,分别听给每个人的作者,谈论另一个人的项目。因此,在我看来,它们都是不错的选择,两者都可以尝试!
无论如何,两者都已经在 zsh
shell 上进行了测试。
特别是autoenv
使用起来真的很简单,安装后:
$ git clone git://github.com/inishchith/autoenv.git ~/.autoenv
$ echo 'source ~/.autoenv/activate.sh' >> ~/.bashrc
只要“跟着小白兔”然后试试
$ mkdir project
$ echo "echo 'whoa'" > project/.env
$ cd project
whoa
"If a directory contains a .env
file, it will automatically be executed when you cd
into it. When enabled (set AUTOENV_ENABLE_LEAVE
to a non-null string), if a directory contains a .env.leave
file, it will automatically be executed when you leave it."
查看 https://github.com/inishchith/autoenv 以获得更详细的说明!...
这是一个仅限 zsh 的解决方案。
这是对 which is an improvement over 的改进。
我们正在使用 precmd
挂钩而不是覆盖 cd
。
我们添加了另一个额外的功能。假设目录结构为
├── .venv
│ ├── bin
│ │ └── activate
├── subdir
│ ├── subdir1
│ │ ├── subdir2
│ │ │ └── test2.txt
│ │ └── test1.txt
│ └── test.txt
└── testing.py
如果你现在在 subdir2 中打开新的终端,或者直接从其他地方 cd 到 subdir2,它会激活 venv。
解决方法是:
autoload -Uz add-zsh-hook
add-zsh-hook precmd automatically_activate_python_venv
function automatically_activate_python_env() {
if [[ -z $VIRTUAL_ENV ]] ; then
activate_venv
else
parentdir="$(dirname ${VIRTUAL_ENV})"
if [[ "$PWD"/ != "$parentdir"/* ]] ; then
deactivate
activate_venv
fi
fi
}
function activate_venv() {
local d n
d=$PWD
until false
do
if [[ -f $d/.venv/bin/activate ]] ; then
source $d/.venv/bin/activate
break
fi
d=${d%/*}
# d="$(dirname "$d")"
[[ $d = *\/* ]] || break
done
}
对于像我这样的 python 开发人员,我在 cd
进入 python 项目时使用 this plugin 创建、激活 python 虚拟环境,它也会在 cd
进入另一个目录后停用。
对于使用(或考虑使用)pyenv this can be achieved very conveniently using the pyenv-virtualenv plugin as described here 的任何人。
基本上,您只需将 .python-version
文件添加到指定 virtualenv 名称的目录。
类似于但支持cd
从一个virtualenv到另一个。在这种情况下,它会停用旧的 virtualenv,然后激活新的。
function cd() {
builtin cd "$@"
if [[ ! -z "$VIRTUAL_ENV" ]] ; then
# If the current directory is not contained
# within the venv parent directory -> deactivate the venv.
cur_dir=$(pwd -P)
venv_dir="$(dirname "$VIRTUAL_ENV")"
if [[ "$cur_dir"/ != "$venv_dir"/* ]] ; then
deactivate
fi
fi
if [[ -z "$VIRTUAL_ENV" ]] ; then
# If config file is found -> activate the vitual environment
venv_cfg_filepath=$(find . -maxdepth 2 -type f -name 'pyvenv.cfg' 2> /dev/null)
if [[ -z "$venv_cfg_filepath" ]]; then
return # no config file found
fi
venv_filepath=$(cut -d '/' -f -2 <<< ${venv_cfg_filepath})
if [[ -d "$venv_filepath" ]] ; then
source "${venv_filepath}"/bin/activate
fi
fi
}
我用过direnv in the past, as others have mentioned. Lyft use aactivator for this exact scenario.
Once the venv is built it must be activated (added to $PATH). We use aactivator to automatically activate the venv each time a user enters the service directory and deactivates as they leave.
我的 ~/Documents
中有很多项目。我几乎只在 python 工作,所以这些基本上都是 python 项目。每一个,例如~/Documents/foo
有自己的 virtualenv,~/Documents/foo/venv
(它们总是被称为 venv)。每当我在项目之间切换时,每天大约 10 次,我都会
deactivate
cd ..
cd foo
source venv/bin/activate
我已经厌倦了输入 deactivate
和 source venv/bin/activate
。 我正在寻找一种方法 cd ../foo
并为我处理 virtualenv 操作。
我熟悉VirtualEnvWrapper,我认为这有点笨拙。据我所知,它似乎将您所有的 virtualenvs 都移到了其他地方,并且增加了比它删除的复杂性更多的复杂性。 (欢迎不同意见!)
我不太熟悉 shell 脚本。如果您可以推荐一个低维护脚本添加到我的
~/.zshrc
来完成此任务,那就足够了,但是通过快速谷歌搜索,我还没有找到这样的脚本。我是
zsh
/oh-my-zsh
用户。oh-my-zsh
似乎没有这方面的插件。这个问题的最佳答案是有人贡献了一个oh-my-zsh
插件来做到这一点。 (如果这里的答案乏善可陈,我可能会这样做。
在你的 .zshrc 中加入这样的东西
function cd() {
if [[ -d ./venv ]] ; then
deactivate
fi
builtin cd
if [[ -d ./venv ]] ; then
. ./venv/bin/activate
fi
}
编辑:如评论中所述cd
-进入当前虚拟环境的子文件夹将停用它。一个想法可能是仅当 cd
进入新环境时才停用当前环境,例如
function cd() {
builtin cd
if [[ -n "$VIRTUAL_ENV" && -d ./venv ]] ; then
deactivate
. ./venv/bin/activate
fi
}
仍然可以改进,也许将其变成文件夹名称上的 "prompt command" 或 attempting some prefix matching 以检查路径上某处是否存在虚拟环境,但我的 shell- fu 不够好。
在您的 .bashrc 或 .zshrc 中添加以下内容
function cd() {
builtin cd "$@"
if [[ -z "$VIRTUAL_ENV" ]] ; then
## If env folder is found then activate the vitualenv
if [[ -d ./.env ]] ; then
source ./.env/bin/activate
fi
else
## check the current folder belong to earlier VIRTUAL_ENV folder
# if yes then do nothing
# else deactivate
parentdir="$(dirname "$VIRTUAL_ENV")"
if [[ "$PWD"/ != "$parentdir"/* ]] ; then
deactivate
fi
fi
}
即使有人进入子文件夹,此代码也不会停用 virtualenv。灵感来自
如果virtualenv是pipenv制作的,请考虑this wiki page。
此外,为了增加安全性,请考虑 direnv。
您可以使用 direnv. It's not a zsh specific solution (for that you could try zsh-autoenv) 而不是编写自定义脚本,但维护良好且易于与 zsh 一起使用。安装后,您需要将 eval "$(direnv hook zsh)"
放在 .zshrc
的末尾。那时你可以这样做:
$ source ~/.zshrc
$ cd foo
$ echo "layout python" > .envrc
direnv: error .envrc is blocked. Run `direnv allow` to approve its content.
$ direnv allow
direnv: loading .envrc
direnv: export +VIRTUAL_ENV ~PATH
现在你应该在你的虚拟环境中了。您可以通过 运行 pip freeze
进行测试以查看您的 virtualenv 特定包是否已安装。停用
$ cd ..
direnv: unloading
这是我的解决方案,其中:
- 检查是否已经处于当前活动状态
venv
,在这种情况下什么都不做 - 如果有
venv
文件夹,如果有 则停用活动文件夹
- 激活新的
venv
无论是否有旧的。
在我的 bash_aliases
中:
function cd() {
builtin cd "$@"
if [ $(dirname "$VIRTUAL_ENV") == $(pwd) ] ; then
# Already at the active virtual env
return
fi
if [[ -d ./venv ]] ; then
if type deactivate > /dev/null 2>&1 ; then
printf "Deactivating virtualenv %s\n" "$VIRTUAL_ENV"
deactivate
fi
source ./venv/bin/activate
printf "Setting up virtualenv %s\n" "$VIRTUAL_ENV"
fi
}
为了后代:我使用了@MS_ 的解决方案,但 运行 遇到了 cd
直接从一个项目到另一个项目停用旧 virtualenv 但不激活新 virtualenv 的问题。这是解决此问题的解决方案的略微修改版本:
# auto activate virtualenv
# Modified solution based on
function cd() {
builtin cd "$@"
## Default path to virtualenv in your projects
DEFAULT_ENV_PATH="./env"
## If env folder is found then activate the vitualenv
function activate_venv() {
if [[ -f "${DEFAULT_ENV_PATH}/bin/activate" ]] ; then
source "${DEFAULT_ENV_PATH}/bin/activate"
echo "Activating ${VIRTUAL_ENV}"
fi
}
if [[ -z "$VIRTUAL_ENV" ]] ; then
activate_venv
else
## check the current folder belong to earlier VIRTUAL_ENV folder
# if yes then do nothing
# else deactivate then run a new env folder check
parentdir="$(dirname ${VIRTUAL_ENV})"
if [[ "$PWD"/ != "$parentdir"/* ]] ; then
echo "Deactivating ${VIRTUAL_ENV}"
deactivate
activate_venv
fi
fi
}
这是没有 cd'ing 的解决方案,将 zsh 设置为 setop auto_cd
将能够在没有 cd 的情况下更改目录,只需键入目录名称并点击进入。
它是上述解决方案的结果:
# auto activate virtualenv
# Modified solution based on
function auto_active_env() {
## Default path to virtualenv in your projects
DEFAULT_ENV_PATH="./env"
## If env folder is found then activate the vitualenv
function activate_venv() {
if [[ -f "${DEFAULT_ENV_PATH}/bin/activate" ]] ; then
source "${DEFAULT_ENV_PATH}/bin/activate"
echo "Activating ${VIRTUAL_ENV}"
fi
}
if [[ -z "$VIRTUAL_ENV" ]] ; then
activate_venv
else
## check the current folder belong to earlier VIRTUAL_ENV folder
# if yes then do nothing
# else deactivate then run a new env folder check
parentdir="$(dirname ${VIRTUAL_ENV})"
if [[ "$PWD"/ != "$parentdir"/* ]] ; then
echo "Deactivating ${VIRTUAL_ENV}"
deactivate
activate_venv
fi
fi
}
chpwd_functions=(${chpwd_functions[@]} "auto_active_env")
这是(又)另一种自动激活虚拟环境的解决方案;它基于此处已发布的许多答案。
这将适用于 任何 虚拟环境名称或目录(不仅仅是 ./env
、./venv
等)。还支持子目录,以及 cd
-ing 到虚拟环境(父)文件夹的符号链接。
此代码搜索 pyvenv.cfg
文件而不是特定的命名目录。如果在当前文件夹的子目录中找到一个,环境将自动激活。一旦进入虚拟环境,该状态将一直保留,直到您移出父虚拟环境目录,此时环境将被停用。
将此放在您的 .bashrc
或 .bash_profile
中。
function cd() {
builtin cd "$@"
if [[ -z "$VIRTUAL_ENV" ]] ; then
# If config file is found -> activate the vitual environment
venv_cfg_filepath=$(find . -maxdepth 2 -type f -name 'pyvenv.cfg' 2> /dev/null)
if [[ -z "$venv_cfg_filepath" ]]; then
return # no config file found
fi
venv_filepath=$(cut -d '/' -f -2 <<< ${venv_cfg_filepath})
if [[ -d "$venv_filepath" ]] ; then
source "${venv_filepath}"/bin/activate
fi
else
# If the current directory is not contained
# within the venv parent directory -> deactivate the venv.
cur_dir=$(pwd -P)
venv_dir="$(dirname "$VIRTUAL_ENV")"
if [[ "$cur_dir"/ != "$venv_dir"/* ]] ; then
deactivate
fi
fi
}
我个人认为这是对此处许多解决方案的改进,因为它适用于任何虚拟环境
这是我的解决方案:
- 如果未设置 VIRTUAL_ENV,则:
- 检查我们是否在虚拟环境中
- 如果是,则激活它
- Else(定义了VIRTUAL_ENV),检查当前文件夹是否以$VIRTUAL_ENV开头(去掉
/venv
部分)并验证deactivate命令是否存在- 停用环境
这是脚本:
function cd() {
builtin cd
if [[ -z "${VIRTUAL_ENV}" ]]; then
if [[ -d ./venv && -f ./venv/bin/activate ]]; then
source ./venv/bin/activate
fi
elif [[ ! "$(pwd)" == ${VIRTUAL_ENV:0:n-5}* && ! -z "$(command -v deactivate)" ]]; then
deactivate
fi
}
注意:您需要将此添加到.bashrc
。如果它不起作用,请检查你的 .profile
是否没有覆盖你的命令(它发生在我身上)
基于@MS_的解决方案:
function cd() {
builtin cd "$@"
## If env folder is found then activate the vitualenv
if [[ -d ./venv ]] ; then
source ./venv/bin/activate
fi
if [[ -n "$VIRTUAL_ENV" ]] ; then
## check the current folder belong to earlier VIRTUAL_ENV folder
# if yes then do nothing
# else deactivate
parentdir="$(dirname "$VIRTUAL_ENV")"
if [[ "$PWD"/ != "$parentdir"/* ]] ; then
deactivate
fi
fi
}
到目前为止最简单的选择(在 2019 年以后)是将 virtualenvwrapper
添加到您的 ~/.zshrc
plugins
例如:
plugins=(
git pip python brew virtualenvwrapper
)
第一个被认为是“轻量级”,而第二个“简单,更高质量的软件”,分别听给每个人的作者,谈论另一个人的项目。因此,在我看来,它们都是不错的选择,两者都可以尝试!
无论如何,两者都已经在 zsh
shell 上进行了测试。
特别是autoenv
使用起来真的很简单,安装后:
$ git clone git://github.com/inishchith/autoenv.git ~/.autoenv
$ echo 'source ~/.autoenv/activate.sh' >> ~/.bashrc
只要“跟着小白兔”然后试试
$ mkdir project
$ echo "echo 'whoa'" > project/.env
$ cd project
whoa
"If a directory contains a .env
file, it will automatically be executed when you cd
into it. When enabled (set AUTOENV_ENABLE_LEAVE
to a non-null string), if a directory contains a .env.leave
file, it will automatically be executed when you leave it."
查看 https://github.com/inishchith/autoenv 以获得更详细的说明!...
这是一个仅限 zsh 的解决方案。
这是对
我们正在使用 precmd
挂钩而不是覆盖 cd
。
我们添加了另一个额外的功能。假设目录结构为
├── .venv
│ ├── bin
│ │ └── activate
├── subdir
│ ├── subdir1
│ │ ├── subdir2
│ │ │ └── test2.txt
│ │ └── test1.txt
│ └── test.txt
└── testing.py
如果你现在在 subdir2 中打开新的终端,或者直接从其他地方 cd 到 subdir2,它会激活 venv。
解决方法是:
autoload -Uz add-zsh-hook
add-zsh-hook precmd automatically_activate_python_venv
function automatically_activate_python_env() {
if [[ -z $VIRTUAL_ENV ]] ; then
activate_venv
else
parentdir="$(dirname ${VIRTUAL_ENV})"
if [[ "$PWD"/ != "$parentdir"/* ]] ; then
deactivate
activate_venv
fi
fi
}
function activate_venv() {
local d n
d=$PWD
until false
do
if [[ -f $d/.venv/bin/activate ]] ; then
source $d/.venv/bin/activate
break
fi
d=${d%/*}
# d="$(dirname "$d")"
[[ $d = *\/* ]] || break
done
}
对于像我这样的 python 开发人员,我在 cd
进入 python 项目时使用 this plugin 创建、激活 python 虚拟环境,它也会在 cd
进入另一个目录后停用。
对于使用(或考虑使用)pyenv this can be achieved very conveniently using the pyenv-virtualenv plugin as described here 的任何人。
基本上,您只需将 .python-version
文件添加到指定 virtualenv 名称的目录。
类似于cd
从一个virtualenv到另一个。在这种情况下,它会停用旧的 virtualenv,然后激活新的。
function cd() {
builtin cd "$@"
if [[ ! -z "$VIRTUAL_ENV" ]] ; then
# If the current directory is not contained
# within the venv parent directory -> deactivate the venv.
cur_dir=$(pwd -P)
venv_dir="$(dirname "$VIRTUAL_ENV")"
if [[ "$cur_dir"/ != "$venv_dir"/* ]] ; then
deactivate
fi
fi
if [[ -z "$VIRTUAL_ENV" ]] ; then
# If config file is found -> activate the vitual environment
venv_cfg_filepath=$(find . -maxdepth 2 -type f -name 'pyvenv.cfg' 2> /dev/null)
if [[ -z "$venv_cfg_filepath" ]]; then
return # no config file found
fi
venv_filepath=$(cut -d '/' -f -2 <<< ${venv_cfg_filepath})
if [[ -d "$venv_filepath" ]] ; then
source "${venv_filepath}"/bin/activate
fi
fi
}
我用过direnv in the past, as others have mentioned. Lyft use aactivator for this exact scenario.
Once the venv is built it must be activated (added to $PATH). We use aactivator to automatically activate the venv each time a user enters the service directory and deactivates as they leave.