从bash脚本中调用conda source activate

93

我试着通过一个bash脚本来激活我的conda环境。尽管脚本运行良好且脚本内看似已经改变了PATH,但是在脚本终止后某种方式它又被重置了。我可以在命令行中调用source activate test并且它可以正常工作。以下是示例及其输出。

脚本:

PycharmProjects/test » cat ./example.sh
echo "before calling source: $PATH"
source activate test
echo "after calling source: $PATH"

输出:

./example.sh
before calling source: /Use rs/me/miniconda3/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/TeX/texbin

discarding /Users/me/miniconda3/bin from PATH
prepending /Users/me/miniconda3/envs/test/bin to PATH

after calling source: /Users/me/miniconda3/envs/test/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/TeX/texbin`
但是,如果脚本执行完成后我运行 echo $PATH 命令,你会发现 $PATH 没有改变(即没有添加 /Users/me/miniconda3/envs/test/bin): PycharmProjects/test » echo $PATH /Users/me/miniconda3/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/TeX/texbin

“echo $PATH” 是在哪里说的?您是将 “example.sh” 作为脚本本身运行(即 ./example.sh)还是引用它(即 source example.sh)? - Etan Reisner
运行 example.sh 脚本(./example.sh)。脚本运行结束后,我调用了 echo $PATH,只是为了展示 $PATH 实际上并没有改变。 - matt_k
2
将其作为脚本运行时,更改会停止在运行脚本的 shell 中。这就是为什么您需要“source”激活脚本,以使其首先应用于正在运行的脚本/ shell。 - Etan Reisner
可能是如何在Bash脚本中调用virtualenv activate的重复问题。 - Etan Reisner
感谢您提供脚本修复。 - matt_k
我曾经遇到过同样的问题,最终强制我的脚本被引用。这导致了其他麻烦(例如使用set -e运行它)- 最终值得改为“普通”运行(不是被引用),并应用接受的答案。感谢您提出这个问题! - Guy Rapaport
5个回答

178

在较新的conda版本(4.6+)中,我注意到以下内容可行:

eval "$(conda shell.bash hook)"
conda activate <env-name>

7
请问一下为什么需要执行 eval "$(conda shell.bash hook)" 命令? - Jon
3
conda shell.bash hook 返回一个 bash 字符串。我猜你可以将其写入文件,然后再源化该文件,但是使用 eval 更容易/更快速。 - Anthony Scopatz
4
@AnthonyScopatz 解释了你在做什么,但没有解释为什么。使用 conda activate <env> 没有那个 eval 表达式也能正常工作,所以为什么你要这样做仍然不清楚。 - Cerin
14
当使用 conda activate 命令出现错误并提示需要运行 conda init 命令时,可以通过此处的 eval 表达式使其在不运行 conda init 的情况下正常工作。 - Allen Baron
2
获取:CommandNotFoundError:您的shell未正确配置以使用'conda activate'。 - ntg
显示剩余5条评论

43

我在运行bash shell的Mac OSX上发现以下内容可行:

#!/bin/bash
source /Users/yourname/anaconda/bin/activate your_env
python --version # example way to see that your virtual env loaded as expected

请确保使用以下命令将脚本设为可执行:

chmod +x yourscript.bash

它在我的Ubuntu 18、Conda 4.9上运行良好。比Anthony Scopatz的方法花费更少的时间。原因超出了我的理解范围。 - Mauricio Arboleda-Zapata

30

交互式 Shell

conda activate 命令是为 交互式 shell 会话而设计的。其中一种解决方案是在交互式 shell 中有意地运行脚本。可以通过 shebang(如果打算使用 ./example.sh 调用)来完成:

example.sh

#!/usr/bin/env bash -l
echo "before calling source: $PATH"
## `source activate` is deprecated
conda activate test
echo "after calling source: $PATH"

或者,通过在shell中指定标志:

## bash
bash -l example.sh

## zsh
zsh -i example.sh

所有这些都假定执行用户已经为shell运行了 conda init

使用 conda run

对于环境内的编程式执行,Conda提供了conda run命令。与其混乱地处理shell状态,不如让Conda保证在环境中执行:

crun_example.sh

echo "PATH outside environment: $PATH"

## printing shell variables is complicated by escaping
conda run -n test bash -c "echo \"PATH inside environment: \${PATH}\""

## but realistic application is usually a non-trivial script
conda run -n test python my_script.py

涉及用户界面I/O的代码通常需要一个--live-stream标志。详情请参阅conda run --help


6

0
我正在使用一台具有以下规格的工作站:
- Fedora `37` - Bash: `GNU bash, version 5.2.15(1)-release (x86_64-redhat-linux-gnu)` - conda: `23.7.2`
对于我来说,这些解决方案都没有起作用,无论是使用bash交互模式、登录模式,还是`eval "$(conda shell.bash hook)"`等等。
针对像我一样无法使这些解决方案起作用的人,我有一个解决办法:
在项目文件夹中创建一个名为`activate.sh`的bash文件,并包含以下内容:
#!/bin/bash
conda activate your_env_name

~/.bash_aliases中添加一个别名,就像这样:
alias conda-activate='test -f $PWD/activate.sh && source $PWD/activate.sh'

在您的项目文件夹中运行conda-activate
我知道这个问题是关于macOS的,但这是stackoverflow上最常被引用的问题,我认为这里是一个很好的地方来发布我的解决方案。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接