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

  • 本文关键字:激活 环境 Conda path conda
  • 更新时间 :
  • 英文 :


运行source activate <env-name>如何更新$PATH变量?我一直在查看CONDA-INSTALLATION/bin/activate脚本,但不明白 conda 如何更新我的 $PATH 变量以包含最近激活的环境的 bin 目录。在任何地方都找不到 conda 用来预置我的$PATH变量的代码。

免责声明:我不是 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,查看CONDA_INST_DIR/bin/activate,我们在倒数第二行和最后一行(GitHub 链接)上找到:

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

第一行在$_CONDA_ROOT/etc/profile.d目录中获取脚本conda.sh,该脚本定义_conda_activatebash 函数,我们将参数传递给该函数$@这基本上是我们传递给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 "$@"。在这里,我们使用参数运行 conda 可执行文件shell.posixactivate,然后是传递给此函数的其余参数(即我们要激活的环境名称)。

又一步进入兔子洞...从这里开始,conda 可执行文件调用cli.main函数,由于第一个参数以shell.开头,它从conda.activate导入main函数。此函数创建Activator类的实例(在同一文件中定义)并运行execute方法。

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

又一步进入兔子洞...activate方法调用build_activate方法,该方法调用另一个函数来处理环境名称以查找环境前缀(即环境所在的文件夹)。最后,build_activate方法通过_add_prefix_to_path方法将prefix添加到PATH。最后,build_activate方法返回需要运行以"激活"环境的命令字典。

再深入一步...从build_activate方法返回的字典由_yield_commands方法处理成 shell 命令,这些命令将传递到_finalize方法中。activate方法返回运行_finalize方法的值,该方法返回临时文件的名称。临时文件包含设置所有相应环境变量所需的命令。

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

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

我还应该指出,在 conda>=4.4 中激活环境的推荐方法是conda activate env-name,这是这如此复杂的原因之一 - 激活现在主要在 Python 中处理,而(我认为)以前它或多或少是直接在 Bash/CMD 中处理的。

相关内容

  • 没有找到相关文章

最新更新