Conda:激活环境时会发生什么?
Conda: what happens when you activate an environment?
运行 source activate <env-name>
如何更新 $PATH 变量?我一直在查看 CONDA-INSTALLATION/bin/activate
脚本,但不明白 conda 如何更新我的 $PATH 变量以包含最近激活的环境的 bin 目录。没有在哪里可以找到 conda 用来添加我的 $PATH 变量的代码。
免责声明:我不是 conda 开发人员,也不是 Bash 专家。下面的解释是基于我对代码的跟踪,希望我没看错。此外,在撰写此答案时,以下所有链接都是指向主提交的永久链接 (7cb5f66
)。 Behavior/lines 可能会在未来的提交中发生变化。当心:前方很深的兔子洞!
注意,此解释是针对命令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 link):
. "$_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 link):
_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
function and since the first argument starts with shell.
, it imports the main
function from conda.activate
. This function creates an instance of the Activator
class (defined in the same file) and runs the execute
method.
execute
方法处理参数和 stores the passed environment name into an instance variable, then decides that the activate
command has been passed, so it runs the activate
method。
进入兔子洞的又一步... activate
方法调用 build_activate
method, which calls another function to process the environment name to find the environment prefix (i.e., which folder the environment is in). Finally, the build_activate
method adds the prefix
to the PATH
via the _add_prefix_to_path
method. Finally, the build_activate
method returns a dictionary 需要 运行 "activate" 环境的命令。
还有更深的一步...从 build_activate
方法编辑的字典 return 被 _yield_commands
method, which are passed into the _finalize
method. The activate
method returns the value from running the _finalize
method 处理成 shell 命令,其中 return s 临时文件的名称。临时文件包含设置所有适当环境变量所需的命令。
现在,退出,在activate.main
函数中,execute
方法的return值(即临时文件的名称)是printed to stdout.此临时文件名存储在 Bash 变量 ask_conda
中 _conda_activate
Bash 函数中,最后,临时文件由 eval
Bash函数。
呸!我希望我做对了一切。正如我所说,我不是 conda 开发人员,也不是 Bash 专家,所以请原谅我使用的任何不是 100% 正确的解释快捷方式。请发表评论,我很乐意修复它!
我还应该注意,在 conda >=4.4 中激活环境的推荐方法是 conda activate env-name
,这是如此复杂的原因之一 - 激活主要在 Python 中处理现在,而(我认为)以前它或多或少直接在 Bash/CMD.
中处理
运行 source activate <env-name>
如何更新 $PATH 变量?我一直在查看 CONDA-INSTALLATION/bin/activate
脚本,但不明白 conda 如何更新我的 $PATH 变量以包含最近激活的环境的 bin 目录。没有在哪里可以找到 conda 用来添加我的 $PATH 变量的代码。
免责声明:我不是 conda 开发人员,也不是 Bash 专家。下面的解释是基于我对代码的跟踪,希望我没看错。此外,在撰写此答案时,以下所有链接都是指向主提交的永久链接 (7cb5f66
)。 Behavior/lines 可能会在未来的提交中发生变化。当心:前方很深的兔子洞!
注意,此解释是针对命令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 link):
. "$_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 link):
_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
function and since the first argument starts with shell.
, it imports the main
function from conda.activate
. This function creates an instance of the Activator
class (defined in the same file) and runs the execute
method.
execute
方法处理参数和 stores the passed environment name into an instance variable, then decides that the activate
command has been passed, so it runs the activate
method。
进入兔子洞的又一步... activate
方法调用 build_activate
method, which calls another function to process the environment name to find the environment prefix (i.e., which folder the environment is in). Finally, the build_activate
method adds the prefix
to the PATH
via the _add_prefix_to_path
method. Finally, the build_activate
method returns a dictionary 需要 运行 "activate" 环境的命令。
还有更深的一步...从 build_activate
方法编辑的字典 return 被 _yield_commands
method, which are passed into the _finalize
method. The activate
method returns the value from running the _finalize
method 处理成 shell 命令,其中 return s 临时文件的名称。临时文件包含设置所有适当环境变量所需的命令。
现在,退出,在activate.main
函数中,execute
方法的return值(即临时文件的名称)是printed to stdout.此临时文件名存储在 Bash 变量 ask_conda
中 _conda_activate
Bash 函数中,最后,临时文件由 eval
Bash函数。
呸!我希望我做对了一切。正如我所说,我不是 conda 开发人员,也不是 Bash 专家,所以请原谅我使用的任何不是 100% 正确的解释快捷方式。请发表评论,我很乐意修复它!
我还应该注意,在 conda >=4.4 中激活环境的推荐方法是 conda activate env-name
,这是如此复杂的原因之一 - 激活主要在 Python 中处理现在,而(我认为)以前它或多或少直接在 Bash/CMD.