我的~/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
插件来执行此操作。 (如果这里的答案黯淡无光,我可能会这样做。
答案 0 :(得分:8)
在.bashrc或.zshrc中添加以下内容
const myObjectArray = template.map(t => new t(model));
即使有人进入子文件夹,此代码也不会停用virtualenv。灵感来自@agnul和@Gilles的答案。
此外,为了增加安全性,请考虑direnv。
答案 1 :(得分:5)
在你的.zshrc
中加入这样的东西function cd() {
if [[ -d ./venv ]] ; then
deactivate
fi
builtin cd $1
if [[ -d ./venv ]] ; then
. ./venv/bin/activate
fi
}
修改:正如评论cd
中所述 - 进入当前虚拟环境的子文件夹会停用它。一个想法可能是仅在cd
成为新的env时停用当前的env,例如
function cd() {
builtin cd $1
if [[ -n "$VIRTUAL_ENV" && -d ./venv ]] ; then
deactivate
. ./venv/bin/activate
fi
}
仍然可以改进,可能会把它变成一个“提示命令”或文件夹名称上的attempting some prefix matching来检查路径上的某个虚拟环境,但我的shell-fu还不够好。 / p>
答案 2 :(得分:3)
您可以使用direnv而不是编写自定义脚本。它不是特定于zsh的解决方案(为此,您可以尝试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
现在您应该在virtualenv中。您可以通过运行pip freeze
进行测试以查看是否已安装特定于virtualenv的软件包。停用
$ cd ..
direnv: unloading
答案 3 :(得分:2)
第一个是“ 轻量级”,而第二个是“ 简单,高质量的软件”,分别听取每个作者的意见,并讨论另一个人的项目。因此,在我看来,它们都是不错的选择,两者都可以尝试!
无论如何,两者均已在zsh
外壳上进行了测试。
特别是,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
”如果目录包含.env
文件,则当您cd
进入目录时,它将自动执行。启用后(将AUTOENV_ENABLE_LEAVE
设置为非空字符串),如果目录包含一个.env.leave
文件,当您离开该文件时,它将自动执行。”
请查看https://github.com/inishchith/autoenv以获得更详细的说明!...
答案 4 :(得分:1)
最远的一种选择(在2019年以后)是在您的virtualenvwrapper
~/.zshrc
plugins
例如:
plugins=(
git pip python brew virtualenvwrapper
)
答案 5 :(得分:1)
对于任何使用(或考虑使用)pyenv 的人来说,使用 pyenv-virtualenv 中描述的 here 插件可以非常方便地实现这一点。
基本上,您只需将 .python-version
文件添加到指定 virtualenv 名称的目录中。
答案 6 :(得分:0)
这是我的解决方案,
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
}
答案 7 :(得分:0)
为后人:我使用@MS_的解决方案,但遇到了一个问题,其中cd
直接从一个项目迁移到另一个项目会停用旧的virtualenv,但不会激活新的virtualenv。这是解决此问题的解决方案的稍作修改的版本:
# auto activate virtualenv
# Modified solution based on https://stackoverflow.com/questions/45216663/how-to-automatically-activate-virtualenvs-when-cding-into-a-directory/56309561#56309561
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
}
答案 8 :(得分:0)
这是没有 cd'的解决方案,并且zsh设置为setop auto_cd
,您将能够在没有cd的情况下更改目录,只需键入目录名称并按Enter。
它是上述解决方案的一部分:
# auto activate virtualenv
# Modified solution based on https://stackoverflow.com/questions/45216663/how-to-automatically-activate-virtualenvs-when-cding-into-a-directory/56309561#56309561
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")
答案 9 :(得分:0)
(这里)是(另一个)自动激活虚拟环境的解决方案;它基于此处已经发布的许多答案。
这将适用于任何虚拟环境名称或目录(不仅仅是./env
,./venv
等)。还支持子目录以及cd
-进入虚拟环境(父)文件夹的符号链接。
此代码搜索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
}
我个人认为这是对许多解决方案的改进,因为它适用于任何虚拟环境
答案 10 :(得分:0)
这是我的解决方案:
/venv
部分)并验证deactivate命令是否存在
这是脚本:
function cd() {
builtin cd $1
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
是否没有覆盖您的命令(发生在我身上)
答案 11 :(得分:0)
基于@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
}
答案 12 :(得分:0)
这是仅zsh的解决方案。
这是对daveruinseverything's answer的改进,也是对MS_'s answer的改进。
我们使用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
}
答案 13 :(得分:0)
对于像我这样的 python 开发人员,我使用 this plugin 来创建、激活 python 虚拟环境,当 cd
进入 python 项目时,它也会在 cd
进入另一个目录后停用。
目前它有一个小错误,您的 ZSH 主题在停用后会恢复为默认值,并且有一个修补程序。