Python - 通过 shell 脚本激活 conda env

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/55507519/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 20:34:21  来源:igfitidea点击:

Python - Activate conda env through shell script

pythonpython-3.xanacondaconda

提问by user9074332

I am hoping to run a simple shell script to ease the management around some conda environments. Activating conda environments via conda activatein a linuxos works fine in the shell but is problematic within a shell script. Could someone point me into the right direction as to why this is happening?

我希望运行一个简单的 shell 脚本来简化一些 conda 环境的管理。通过conda activatelinuxos 中激活 conda 环境在shell 中工作正常,但在 shell 脚本中存在问题。有人可以指出我为什么会发生这种情况的正确方向吗?

Example to repeat the issue:

重复问题的示例:

# default conda env
$ conda info|egrep "conda version|active environment"
     active environment : base
          conda version : 4.6.9

# activate new env to prove that it works
$ conda activate scratch
$ conda info|egrep "conda version|active environment"
     active environment : scratch
          conda version : 4.6.9

# revert back to my original conda env
$ conda activate base 

$ cat shell_script.sh
#!/bin/bash
conda activate scratch

# run shell script - this will produce an error even though it succeeded above
$ ./shell_script.sh

CommandNotFoundError: Your shell has not been properly configured to use 'conda activate'.
To initialize your shell, run

    $ conda init <SHELL_NAME>

Currently supported shells are:
  - bash
  - fish
  - tcsh
  - xonsh
  - zsh
  - powershell

See 'conda init --help' for more information and options.

IMPORTANT: You may need to close and restart your shell after running 'conda init'.

采纳答案by Niayesh Isky

The error message is rather helpful - it's telling you that conda is not properly set up from within the subshell that your script is running in. To be able to use conda within a script, you will need to (as the error message says) run conda init bash(or whatever your shell is) first. The behaviour of conda and how it's set up depends on your conda version, but the reason for the version 4.4+ behaviour is that condais dependent on certain environment variables that are normally set up by the conda shell itself. Most importantly, this changelog entryexplains why your conda activateand deactivatecommands no longer behave as you expect in versions 4.4 and above.

错误消息相当有帮助 - 它告诉您 conda 未从脚本运行的子 shell 中正确设置。为了能够在脚本中使用 conda,您需要(如错误消息所述)运行conda init bash(或任何你的外壳)第一。conda 的行为及其设置方式取决于您的 conda 版本,但 4.4+ 版本行为的原因conda取决于通常由 conda shell 本身设置的某些环境变量。最重要的是,此变更日志条目解释了为什么您的conda activatedeactivate命令在 4.4 及更高版本中不再像您期望的那样运行。

For more discussion of this, see the official conda issueon GitHub.

有关这方面的更多讨论,请参阅GitHub 上的官方 conda 问题



Edit: Some more research tells me that the conda initfunction mentioned in the error message is actually a new v4.6.0 feature that allows a quick environment setup so that you can use conda activateinstead of the old source activate. However, the reason why this works is that it adds/changes several environment variables of your current shell and also makes changes to your RC file (e.g.: .bashrc), and RC file changes are never picked up in the current shell - only in newly created shells. (Unless of course you source .bashrc again). In fact, conda init --helpsays as much:

编辑:更多的研究告诉我,conda init错误消息中提到的功能实际上是一个新的 v4.6.0 功能,它允许快速设置环境,以便您可以使用conda activate而不是旧的source activate. 但是,这样做的原因是它添加/更改了当前 shell 的几个环境变量,并且还对 RC 文件进行了更改(例如.bashrc:),并且 RC 文件更改永远不会在当前 shell 中被拾取 - 仅在新创建的贝壳。(当然,除非您再次使用 .bashrc )。事实上,conda init --help说了这么多:

IMPORTANT: After running conda init, most shells will need to be closed and restarted for changes to take effect

重要提示:运行后conda init,大多数 shell 将需要关闭并重新启动才能使更改生效

However, you've clearly already run conda init, because you areable to use conda activateinteractively. In fact, if you open up your .bashrc, you should be able to see a few lines added by conda teaching your shell where to look for conda commands. The problem with your script, though, lies in the fact that the .bashrc is notsourced by the subshell that runs shell scripts (see this answerfor more info). This means that even though your non-login interactive shell sees the conda commands, your non-interactive script subshells won't - no matter how many times you call conda init.

但是,你显然已经运行conda init,因为你能够使用conda activate交互。事实上,如果你打开你的 .bashrc,你应该能够看到 conda 添加的几行,教你的 shell 在哪里寻找 conda 命令。但是,您的脚本的问题在于 .bashrc不是由运行 shell 脚本的子 shell 提供的(有关更多信息,请参阅此答案)。这意味着即使您的非登录交互式 shell 看到 conda 命令,您的非交互式脚本子 shell 也不会 - 无论您调用conda init.

This leads to a conjecture (I don't have conda on Linux myself, so I can't test it) that by running your script like so:

这导致了一个猜想(我自己在 Linux 上没有 conda,所以我无法测试它)通过像这样运行你的脚本:

bash -i shell_script.sh

you should see conda activatework correctly. Why? -iis a bash flag that tells the shell you're starting to run in interactive mode, which means it will automatically source your .bashrc. This should be enough to enable you to use conda within your script as if you were using it normally.

你应该看到conda activate工作正常。为什么?-i是一个 bash 标志,它告诉 shell 您开始以交互模式运行,这意味着它将自动获取您的 .bashrc。这应该足以让您在脚本中使用 conda,就像您正常使用它一样。

回答by qidong

I use 'source command' to run the shell script, it works:

我使用“源命令”来运行 shell 脚本,它的工作原理是:

source shell_script.sh

回答by Simba

Quick solution for bash: prependthe following init script into your Bash scripts.

为快速解决方案bash在前面加上下面的init脚本到您的bash脚本。

eval "$(command conda 'shell.bash' 'hook' 2> /dev/null)"

Done.

完毕。



For other shells, check the init conf of your shell, copy the following content within the shell conf and prepend it into your scripts.

对于其他 shell,请检查您的 shell 的 init conf,将以下内容复制到 shell conf 中并将其添加到您的脚本中。

# >>> conda initialize >>>
...
# <<< conda initialize <<<

You can also use

你也可以使用

conda init --all --dry-run --verbose

to get the init script you need in your scripts.

获取脚本中所需的初始化脚本。

Explanation

解释

This is related with the introduction of conda initin conda4.6.

这是通过引进相关conda initconda4.6。

Quote from conda 4.6 release log

引用 conda 4.6 发布日志

Conda 4.4 allowed “conda activate envname”. The problem was that setting up your shell to use this new feature was not always straightforward. Conda 4.6 adds extensive initialization support so that more shells than ever before can use the new “conda activate” command. For more information, read the output from “conda init –help”

Conda 4.4 允许“conda activate envname”。问题是设置 shell 以使用这个新功能并不总是那么简单。Conda 4.6 添加了广泛的初始化支持,以便比以往更多的 shell 可以使用新的“conda activate”命令。有关更多信息,请阅读“conda init –help”的输出

After conda initis introduced in conda4.6, conda only expose command condainto the PATHbut not all the binaries from "base". And environment switch is unified by conda activate env-nameand conda deactivateon all platforms.

conda initconda4.6中引入之后,conda 仅将命令公开 condaPATH“base”中的所有二进制文件中,而不是所有二进制文件中。环境开关由统一conda activate env-nameconda deactivate在所有平台上。

But to make these new commands work, you have to do an additional initialization with conda init.

但是要使这些新命令起作用,您必须使用conda init.

The problem is that your script file is run in a sub-shell, and condais not initialized in this sub-shell.

问题是你的脚本文件是在一个子 shell 中运行的,并且conda没有在这个子 shell 中初始化。

References

参考

回答by Lamma

Using conda activateor source activatein shell scripts does not always work and can throw error like this. An easy work around it to place source ~/miniconda3/etc/profile.d/conda.shabove any conda activatecommand in the script:

在 shell 脚本中使用conda activatesource activate并不总是有效,并且可能会抛出这样的错误。一个简单的解决方法是将它放在脚本中的source ~/miniconda3/etc/profile.d/conda.sh任何conda activate命令之上:

source ~/miniconda3/etc/profile.d/conda.sh
conda activate some-conda-environment

This is the solution that has worked for me and will also work if sharing scripts. This also get around having to use conda initas on some clusters I have worked with the system is initialised but conda activatestill wont work in a shell script.

这是对我有用的解决方案,如果共享脚本也适用。这也可以避免在conda init我使用过的某些集群上使用系统已初始化但conda activate仍然无法在 shell 脚本中工作。

回答by HAltos

What is the problem with simply doing something like this in your shell:

在你的 shell 中简单地做这样的事情有什么问题:

source /opt/conda/etc/profile.d/conda.sh

源/opt/conda/etc/profile.d/conda.sh

(The conda init is still marked as Experimental, and thus not sure if it is a good idea to use it yet).

(conda init 仍然被标记为实验性的,因此不确定使用它是否是一个好主意)。