簡體   English   中英

Python - 通過 shell 腳本激活 conda env

[英]Python - Activate conda env through shell script

我希望運行一個簡單的 shell 腳本來簡化一些 conda 環境的管理。 在 linux 操作系統中通過 conda conda activate conda 環境在linux中工作正常,但在 shell 腳本中存在問題。 有人能指出我為什么會這樣嗎?

重復問題的示例:

# 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'.

錯誤消息相當有幫助 - 它告訴您 conda 未從腳本運行的子 shell 中正確設置。為了能夠在腳本中使用 conda,您需要(如錯誤消息所述)運行conda init bash (或任何你的shell)。 conda 的行為及其設置方式取決於您的 conda 版本,但 4.4+ 版本行為的原因是conda依賴於通常由 conda shell 本身設置的某些環境變量。 最重要的是, 這changelog的項目解釋了為什么您conda activatedeactivate命令不再表現得像你在4.4及以上版本的期待。

有關這方面的更多討論,請參閱 GitHub 上的官方 conda 問題


編輯:更多的研究告訴我,錯誤消息中提到的conda init函數實際上是一個新的 v4.6.0 功能,它允許快速設置環境,以便您可以使用conda activate而不是舊的source activate 但是,這樣做的原因是它添加/更改了當前 shell 的幾個環境變量,並且還更改了 RC 文件(例如: .bashrc ),並且 RC 文件更改永遠不會在當前 shell 中被拾取 - 僅在新創建的貝殼。 (當然,除非您再次使用 .bashrc )。 事實上, conda init --help說了這么多:

重要提示:運行conda init ,大多數 shell 將需要關閉並重新啟動以使更改生效

但是,你顯然已經運行conda init ,因為可以使用conda activate交互。 事實上,如果你打開你的 .bashrc,你應該能夠看到 conda 添加的幾行,教你的 shell 在哪里尋找 conda 命令。 但是,您的腳本的問題在於 .bashrc不是由運行 shell 腳本的子 shell 提供的(有關更多信息,請參閱此答案)。 這意味着即使您的非登錄交互式 shell 看到 conda 命令,您的非交互式腳本子 shell 也不會 - 無論您調用conda init多少次。

這導致了一個猜想(我自己在 Linux 上沒有 conda,所以我無法測試它)通過像這樣運行你的腳本:

bash -i shell_script.sh

您應該會看到conda activate正常工作。 為什么? -i是一個 bash 標志,它告訴 shell 您開始以交互模式運行,這意味着它將自動獲取您的 .bashrc。 這應該足以讓您在腳本中使用 conda,就像您正常使用它一樣。

我使用“源命令”來運行 shell 腳本,它的工作原理是:

source shell_script.sh

為快速解決方案bash前置以下的init腳本到您的bash腳本。

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

完畢。


對於其他 shell,請檢查您的 shell 的 init conf,將以下內容復制到 shell conf 中並將其添加到您的腳本中。

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

你也可以使用

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

獲取腳本中所需的初始化腳本。

解釋

這與conda 4.6 中引入conda init有關。

引用 conda 4.6 發布日志

Conda 4.4 允許“conda activate envname”。 問題是設置 shell 以使用這個新功能並不總是那么簡單。 Conda 4.6 添加了廣泛的初始化支持,以便比以往更多的 shell 可以使用新的“conda activate”命令。 有關更多信息,請閱讀“conda init –help”的輸出

conda 4.6 中引入conda init后,conda 僅將命令conda公開到PATH而不是“base”中的所有二進制文件。 並且在所有平台上通過conda activate env-nameconda deactivate conda activate env-name統一環境切換。

但是要使這些新命令起作用,您必須使用conda init進行額外的初始化。

問題是你的腳本文件是在一個子 shell 中運行的,而conda沒有在這個子 shell 中初始化。

參考

在 shell 腳本中使用conda activatesource activate並不總是有效,並且可能會拋出這樣的錯誤。 一個簡單的解決方法是將source ~/miniconda3/etc/profile.d/conda.sh放在腳本中的任何source ~/miniconda3/etc/profile.d/conda.sh conda activate命令之上:

source ~/miniconda3/etc/profile.d/conda.sh # Or path to where your conda is
conda activate some-conda-environment

這是對我有用的解決方案,如果共享腳本也適用。 這也解決了必須使用conda init因為在我使用過的某些集群上,系統已初始化,但conda activate仍然無法在 shell 腳本中工作。

如果要使用 shell 腳本在另一個 conda env 中運行另一個 python 文件,只需通過以下命令運行另一個文件。

os.system('conda run -n <env_name> python <path_to_other_script>')

在你的 shell 中簡單地做這樣的事情有什么問題:

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

(conda init 仍然被標記為實驗性的,因此不確定使用它是否是一個好主意)。

嘗試從 C++ 或 Python 文件激活 conda env 時,我也遇到了完全相同的錯誤。 我通過繞過 conda activate 語句並使用特定 conda env 的絕對路徑來解決它。

對我來說,我使用 conda 設置了一個名為“testenv”的環境。

我使用

whereis python | grep 'miniconda'

它返回了一個 Python 環境列表。 然后我使用以下命令運行 my_python_file.py。

~/miniconda3/envs/testenv/bin/python3.8 my_python_file.py

你也可以在 Windows 上做同樣的事情,但查找 python 和 conda python 環境有點不同。

我只是遵循了類似hong-xu 的解決方案

因此,要運行使用參數調用腳本並使用特定 conda 環境的 shell 命令:

來自 jupyter 單元格,是這樣的:

p1 = <some-value>
run = f"conda run -n {<env-name>} python {<script-name>.py} \
    --parameter_1={p1}"

!{run}

這個答案類似於@Lamma 的答案。 這對我有用->

(1)我定義了幾個變量; conda 激活函數、環境目錄和環境

conda_activate=~/anaconda3/bin/activate
conda_envs_dir=~/anaconda3/envs
conda_env=<env name>

(2)我用環境conda activate source

source ${conda_activate} ${conda_envs_dir}/${conda_env}

(3) 然后你就可以運行你的python腳本了

python <path to script.py>

這繞過了conda init要求。 我的.bashrc已經被初始化並且.bashrc文件對我不起作用。 @Lamma 的回答和上面的代碼一樣對我有用。

我沒有發現任何上述腳本有用。 如果您想在非交互模式下運行 conda,這些很好,但我想在交互模式下運行它。 如果我運行:

conda activate my_environment 

在 bash 腳本中,它只是在腳本中運行。

我發現只需在 .bashrc 中創建別名即可將目錄更改為我正在處理的特定項目,並為我設置正確的 conda 環境。 所以我包含在 .bashrc 中:

alias my_environment="cd ~/subdirectory/my_project && conda activate my_environment"

進而:

source ~/.bashrc

然后我可以在命令行輸入:

my_environment

每次我想在不同的項目上工作時,更改為正確的項目和正確的環境。

$ conda activate scratch

或者

$ source activate scratch

Github 的這個答案對我有用(我使用的是 Ubuntu,所以它不僅適用於 Windows):

eval "$(conda shell.bash hook)"
conda activate my_env

問題是當您運行 bash 腳本時,會創建一個未正確初始化的新 (linux) shell 環境。 如果您打算激活 conda 環境,然后通過腳本運行 python,您可以按照已接受的解決方案中的討論正確初始化創建的 shell 環境。

但是,如果您希望在完成此腳本后激活 conda 環境,那么這將不起作用,因為新 shell 上的 conda 環境已更改,並且您在完成腳本后退出 shell。 Think of this as running bash , then conda conda activate... then running exit to exit that bash ... More details in How to execute script in the current shell on Linux?

TL;博士

  1. 添加行#!/bin/bash作為腳本的第一行
  2. 鍵入命令source shell_script.sh. shell_script.sh . shell_script.sh

注意: . bash 中的source等效於 bash 中的源。

   #open terminal or CMD as administrator

$ cd <path Anaconda3 install>\Scripts

$ activate

$ cd .. 

$ conda activate scratch

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM