Conda:激活环境时会发生什么?

问题描述 投票:0回答:1

运行

source activate <env-name>
如何更新$PATH变量?我一直在查看
CONDA-INSTALLATION/bin/activate
脚本,但不明白 conda 如何更新我的 $PATH 变量以包含最近激活的环境的 bin 目录。我在哪里可以找到 conda 用于添加 $PATH 变量的代码。

path conda
1个回答
23
投票

免责声明:我不是 conda 开发人员,也不是 Bash 专家。以下解释是基于我对代码的追踪,希望我能理解。此外,下面的所有链接都是撰写此答案时主提交的永久链接(

7cb5f66
)。行为/线路可能会在未来的提交中发生变化。当心:前方有深兔子洞!

请注意,此解释是针对命令

source activate env-name
的,但在 conda>=4.4 中,激活环境的推荐方法是
conda activate env-name
。我认为如果有人使用
conda activate env-name
,您应该了解我们进入
cli.main
函数的部分的解释。

对于 conda >=4.4,<4.5, looking at

CONDA_INST_DIR/bin/activate
,我们在倒数第二行和最后一行找到(GitHub 链接):

. "$_CONDA_ROOT/etc/profile.d/conda.sh" || return $?
_conda_activate "$@"

第一行在

conda.sh
目录中获取脚本
$_CONDA_ROOT/etc/profile.d
,该脚本定义了
_conda_activate
bash 函数,我们将参数
$@
传递给该函数,这基本上是我们传递给
 的所有参数activate
脚本。

沿着兔子洞进行下一步,我们查看

$_CONDA_ROOT/etc/profile.d/conda.sh
并找到(GitHub链接):

_conda_activate() {
# Some code removed...
    local ask_conda
    ask_conda="$(PS1="$PS1" $_CONDA_EXE shell.posix activate "$@")" || return $?
    eval "$ask_conda"

    _conda_hashr
}

关键是那行

ask_conda=...
,特别是
$_CONDA_EXE shell.posix activate "$@"
。在这里,我们使用参数
shell.posix
activate
运行 conda 可执行文件,然后运行传递给该函数的其余参数(即我们要激活的环境名称)。

又进入了兔子洞……从这里开始,conda 可执行文件调用

cli.main
函数,并且由于第一个参数以
shell.
开头,因此它从
main
导入
conda.activate
函数。此函数创建
Activator
类的实例(在同一文件中定义)并 运行
execute
方法

execute
方法处理参数并将传递的环境名称存储到实例变量中,然后确定已传递
activate
命令
,因此它运行
activate
方法

又一步进入兔子洞...

activate
方法调用
build_activate
方法
,该方法调用另一个函数来处理环境名称以查找环境前缀(即环境位于哪个文件夹中) 。最后,
build_activate
方法通过
prefix
方法
PATH添加到
_add_prefix_to_path
。最后,
build_activate
方法返回需要运行以“激活”环境的命令的字典

再深入一步...从

build_activate
方法返回的字典由
_yield_commands
方法
处理为 shell 命令,然后传递到
_finalize
方法中。
activate
方法返回运行
_finalize
方法
的值,该方法返回临时文件的名称。临时文件包含设置所有适当的环境变量所需的命令。

现在,退出,在

activate.main
函数中,
execute
方法的返回值(即临时文件的名称)被打印到 stdout。该临时文件名存储在
ask_conda
Bash 函数中的 Bash 变量
_conda_activate
中,最后,临时文件由
eval
Bash 函数执行。

唷!我希望我一切都做对了。正如我所说,我不是 conda 开发人员,也远非 Bash 专家,所以请原谅我所采取的任何并非 100% 正确的解释快捷方式。只需发表评论,我很乐意修复它!

我还应该注意到,在 conda >=4.4 中激活环境的推荐方法是

conda activate env-name
,这是如此复杂的原因之一 - 激活现在主要在 Python 中处理,而(我认为)以前是或多或少直接在 Bash/CMD 中处理。

© www.soinside.com 2019 - 2024. All rights reserved.