endaaman.com

2020-04-11

Tips

綺麗にcondaを使う

condaのpythonとシステムのpythonが干渉する問題

tl;dr

.~/.condarc

auto_activate_base: false

と指定するだけで、condaのPythonとシステムのPythonは干渉しなくなる。condaのPythonを使いたいときだけ

$ conda activate <env name>

を実行すればよい。なお、.bashrc(あるいは.zshrc )はconda initで追記される、

__conda_setup="$("$HOME/miniconda3/bin/conda" 'shell.bash' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
  eval "$__conda_setup"
else
  if [ -f "$HOME/miniconda3/etc/profile.d/conda.sh" ]; then
    . "$HOME/miniconda3/etc/profile.d/conda.sh"
  fi
fi
unset __conda_setup

だけでよい。

envの仕組みとか

以下LXDコンテナでUbuntu 18.04(シェルはBash、コンテナ名・ホスト名u2)を立ち上げた直後Miniconda3だけをインストールしたものを使用する

~/.condarcauto_activate_base: falseを指定すると、$PATH

ubuntu@u2:~$ echo $PATH | sed 's/:/\n/g'
/home/ubuntu/miniconda3/condabin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games

というようにcondabinだけが追加された状態となる。

ubuntu@u2:~$ ls /home/ubuntu/miniconda3/condabin
conda

この中にはcondaだけが入っている。conda環境とのやりとりはこのcondaだけを軸として行えるようになっている。

この状態でhoge envを作って環境を切り替える

(hoge) ubuntu@u2:~$ conda activate hoge
(hoge) ubuntu@u2:~$ echo $PATH | sed 's/:/\n/g'
/home/ubuntu/miniconda3/envs/hoge/bin
/home/ubuntu/miniconda3/condabin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games

/home/ubuntu/miniconda3/envs/hoge/binが追加された。この中にはhoge envのPythonやツールチェーンなどが入っており、$PATHの前半にあるので、システムのものより優先して使うことができる。

実は、conda activate$PATHをいい感じに差し替えてくれるコマンドなのである。

base envに入ってみると

ubuntu@u2:~$ conda activate base
(base) ubuntu@u2:~$ echo $PATH | sed 's/:/\n/g'
/home/ubuntu/miniconda3/bin
/home/ubuntu/miniconda3/condabin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games

/home/ubuntu/miniconda3/binが追加された。base envはデフォルトゆえにenvとして特殊であり、envs/<env name>のようなプレフィックスを持たない。

ここから conda deactivate でenvから抜けてみる。

(base) ubuntu@u2:~$ conda deactivate
ubuntu@u2:~$ echo $PATH | sed 's/:/\n/g'
/home/ubuntu/miniconda3/condabin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games

condabinだけに戻った。

ようするに、condaはconda activate baseを自動的に実行するのがデフォルトであり、それを無効にするのがauto_activate_base: falseなのである。

.bashrc.zshrcに追記されるスニペットについて

$ conda init bash$ conda init zshを実行すると、勝手に~/.bashrc~/.zshrcが書き換えられる。

以下が実際に追加されるスニペットである。

# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/home/ubuntu/miniconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
    eval "$__conda_setup"
else
    if [ -f "/home/ubuntu/miniconda3/etc/profile.d/conda.sh" ]; then
        . "/home/ubuntu/miniconda3/etc/profile.d/conda.sh"
    else
        export PATH="/home/ubuntu/miniconda3/bin:$PATH"
    fi
fi
unset __conda_setup
# <<< conda initialize <<<

このスニペットが何をしているか。

eval "$__conda_setup" を実行して、失敗したとき、"/home/ubuntu/miniconda3/etc/profile.d/conda.sh" が存在したらそれを実行して、存在しなければPATHを通す。

$__conda_setupの内容だが、簡単に言うと、

  1. conda関数を追加する
  2. $PATH$HOME/miniconda3/condabinを追加する
  3. conda activate base を実行する(※)

最後のconda activate baseを実行するかしないかは、最初に書いたauto_activate_base: の設定が影響している。

auto_activate_base: trueで有効にした状態で、$__conda_setup の中身と "/home/ubuntu/miniconda3/etc/profile.d/conda.sh" を比べてみると、

(base) ubuntu@u2:~$ conda shell.bash hook > hook.sh
(base) ubuntu@u2:~$ cat "/home/ubuntu/miniconda3/etc/profile.d/conda.sh" > rc.sh
(base) ubuntu@u2:~$ diff hook.sh rc.sh
127,128d126
<
< conda activate base

となる。もちろんauto_activate_base: falseで無効化すると、このdiffはなくなる。

おまけ:プロンプトの(base) の表示を消す

プロンプトの (hoge) ubuntu@u2:~$ の現在のenvを表す (hoge) の表示は、 ~/.condarc

changeps1: false

を指定することで消すことができる。ただ消すと現在のenvが分からなくて普通に困るので自分で表示したい。そのときに役に立つ環境変数が$CONDA_DEFAULT_ENVである。

ubuntu@u2:~$ echo $CONDA_DEFAULT_ENV

ubuntu@u2:~$ conda activate hoge
(hoge) ubuntu@u2:~$ echo $CONDA_DEFAULT_ENV
hoge

これを使って自分は

こんな感じの見た目にしている(cf. dotfiles/zshrc at master · endaaman/dotfiles)。


©2024 endaaman.com