运行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_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 "$@"
。在这里,我们使用参数运行 conda 可执行文件shell.posix
、activate
,然后是传递给此函数的其余参数(即我们要激活的环境名称)。
又一步进入兔子洞...从这里开始,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_activate
Bash 函数中,最后,临时文件由eval
Bash 函数执行。
唷!我希望我做对了一切。正如我所说,我不是 conda 开发人员,也远非 Bash 专家,所以请原谅我采取的任何解释快捷方式不是 100% 正确的。只需发表评论,我很乐意修复它!
我还应该指出,在 conda>=4.4 中激活环境的推荐方法是conda activate env-name
,这是这如此复杂的原因之一 - 激活现在主要在 Python 中处理,而(我认为)以前它或多或少是直接在 Bash/CMD 中处理的。