zshでcondaコマンドが使えない問題

#10/06/2020に追記しました
この記事の内容はシェルの知識が皆無だったときに闇雲に試した結果を書いたものなので，あまり良くない方法で実現していましたそのため，本記事の最後に，一番良いと思われる方法を加筆しました．
結論から言うと，zsh起動時に以下のコマンドを使って環境変数を設定することで使えるようになります(このパスは若干異なることがあると思います)．

```zsh
$ source ~/opt/anaconda3/etc/profile.d/conda.sh
```
また，ターミナルを開くたびにこのコマンドを打つのが面倒な場合は，

```zsh
$ echo "source ~/opt/anaconda3/etc/profile.d/conda.sh" >> ~/.zshrc
```
とすればいいです．

何故こうすればいいのかなど，もう少し詳しい内容を知りたい場合は，記事全体を読んでもらえればと思います．

#前置き
MacにAnacondaをインストールしたにも関わらずcondaコマンドが使えなかったので，その解決法を書いておきます．
condaコマンドを使おうとしたら以下のようにエラーが出ました．
<img width="600" alt="スクリーンショット 2019-12-02 14.38.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505262/41db50b5-20b0-d326-3dc4-12c48fef638f.png">
なぜデフォルトのbashではなくて，zshを使っているのかと問われれば，はっきりとは覚えていません．
ただ，初めてターミナルをちゃんと使いだそうとした際に，教えてくれた知人がzshの設定をしてくれたのでzsh派になったような気がします．色々と調べてみるとzshの方が良さそうだという記事を見つけたので，そのまま使っています．
また，2019年10月からリリースされたmacOS Catalinaではデフォルトのシェルがzshに変わった[^1]ので，もしかしたら需要のある話かもしれません．
正直shellの知識は皆無なので，間違ったことを書いていたらご指摘いただけると助かります．

##condaコマンド
[この記事](https://www.python.jp/install/anaconda/conda.html)には，
> Anaconda には conda コマンドがインストールされており、パッケージのインストールや、実行環境の作成・切り替えなどを行えます。

とあります．
また，Anaconda全体については[この記事](https://qiita.com/ozaki_physics/items/985188feb92570e5b82d#https://qiita.com/yampy/items/4e89cd97179bbd20f726)が分かりやすいです．
簡単に言うと，Anacondaの仮想環境に新しいライブラリをインストールする際にはcondaコマンドというものを使うということです．実際今回引っかかったのもそのためでした．

##shellについて
> ユーザは直接コンピュータとやり取りするのではなく、ユーザはシェルを通してコンピュータ（カーネル）にコマンドを送り、シェルを通して結果を受け取るというようにシェルを介してコンピュータを操作します。

shellについての知識は皆無なので，詳しい説明は[この記事](http://www.webdesignleaves.com/pr/plugins/mac_terminal_basics_03.html)に譲ります．
今回重要なのは「環境設定ファイル」という項目で，
>ユーザー固有の環境設定は、~/.bash_profile、もしくは ~/.bashrc というファイルへ必要に応じてユーザが記述することが可能です。

とあるように[^2]，コマンドを使うための環境変数の設定は .bash_profile、もしくは .bashrcというファイルに書かれています．これらが読み込まれることで，shell(この場合はbash)の設定(pathを通すなど)が出来上がっています．

zshについてはもっと複雑に色々なファイルが絡んでいるようですが，とりあえず今回登場する環境設定ファイルの対応関係は以下のような認識でいいかと思います．(かなりガバガバな認識)

| 読み込み       |       bash |    zsh    |
|:-----------------|-----------:|:-------------:|
| ログイン時         |   .bash_profile |   .zprofile  |
| shell起動時      |   .bashrc     |   .zshrc     |


###参考記事
- [Pathを通すとは、環境変数とは](https://qiita.com/fuwamaki/items/3d8af42cf7abee760a81)
- [.bash_profileと.bashrcについて](https://qiita.com/shyamahira/items/260862743e4c9794b5d2)
- [zshの設定ファイルの読み込み順序と使い方Tipsまとめ](https://qiita.com/muran001/items/7b104d33f5ea3f75353f)


#解決策
前提知識はここまでにして，実際に行なった解決策を書いていくことにします．
色々調べてみてもこの問題はあまり起こらないらしく，普通はAnacondaをインストールすればcondaコマンドが使えるようです．
というわけで試しに，zshからbashに切り替えてcondaコマンドが使えるのかを見てみます．
shellの切り替えは，[この記事](https://www.howtogeek.com/444596/how-to-change-the-default-shell-to-bash-in-macos-catalina/)にあるように，以下のようにコマンドを打ってからターミナルを立ち上げ直します．

```shell:zsh

➜ chsh -s /bin/bash
➜ # chsh -s /bin/zsh    #逆に bash ->zsh に切り替えるときはこれ
```

すると，以下のようにcondaコマンドが使えることが分かります．
<img width="500" alt="スクリーンショット 2019-12-02 14.49.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505262/552595a9-8fd8-53ec-7b88-cd6b5235fa27.png">

コマンドが使えないということは，pathが通っていないということです．
bashにはcondaコマンドのpathが通っているのに対し，zshには通っていないのだと考えられます．

というわけで，とりあえず.bashrcを開いてみます．すると，このように書いてあります．
<img width="500" alt="スクリーンショット 2019-12-02 12.47.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505262/bf0336c4-4e71-bb85-e575-aacd4d0c1891.png">
また，.bash_profileを開いてみると，
<img width="500" alt="スクリーンショット 2019-12-02 13.12.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505262/037697b4-4f8f-89e9-44bf-b344fc08f3ed.png">
のように書いてあります．
Anacondaによって，condaに関するpathが自動的に通された形跡が残っていますね．


では.zprofileの中身はどうでしょう．
<img width="500" alt="スクリーンショット 2019-12-02 13.16.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505262/4f91a75e-3d1e-a7ea-c876-63d877cb0fc2.png">
.bash_profileにあるようなcondaに関する記述がありません．
また，.zshrcの中身についても特にcondaに関する記述はありませんでした．

つまり，Anacondaをインストールした際，bashには自動的にcondaに関するpathが通るのに対し，zshには通っていなかったということになりそうです．
shellファイルでのpathの通し方はイマイチ分かりませんが，[この記事](https://medium.com/@sumitmenon/how-to-get-anaconda-to-work-with-oh-my-zsh-on-mac-os-x-7c1c7247d896)にあるように，bashの書き方をコピペすればzshでも通用するようです．ただ，この記事は.bash_profileの内容を.zshrcにコピペしているようですが，対応関係を考えると.zprofileに書く方が素直だと思います．(圧倒的に自信がない)
(再掲)

| 読み込み       |       bash |    zsh    |
|:-----------------|-----------:|:-------------:|
| ログイン時         |   .bash_profile |   .zprofile  |
| shell起動時      |   .bashrc     |   .zshrc     |
よって，.bash_profileと.bashrcの主従関係をそのまま保存するように.zprofileと.zshrcにコピペしてしまいましょう[^3]．

- .zprofile <- .bash_profile
<img width="700" alt="スクリーンショット 2019-12-02 14.42.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505262/dd5b378c-fb81-5991-3027-99dce579d9e7.png">

- .zshrc <- .bashrc
<img width="700" alt="スクリーンショット 2019-12-02 15.13.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505262/242282f9-91d2-ea54-a988-0e0b57d36f0d.png">



これらを保存した後に再びシェルを立ち上げ直すと，このようにcondaが使えるようになっていることが分かります．
<img width="470" alt="スクリーンショット 2019-12-02 15.11.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505262/f772ce8b-fa28-eee6-f71d-6dea0cf183b4.png">
これで，晴れてcondaコマンドが使えるようになりました．

#補足
- 色々調べているうちに，[この記事](https://stackoverflow.com/questions/31615322/zsh-conda-pip-installs-command-not-found)の"22"番の回答にも辿り着きました．  
この記事では，以下のような文を.zshrcに追加することで，.zshrcの読み込みの際に.bash_profileを読み込むことでpathを通すという方法を取っているようです[^4]．つまり，.bash_profileに書かれている記述を利用して，zshにもpathを通しているということです．

```zsh:.zshrc
source ~/.bash_profile
```
確かに，上で書いたようなコピペを行なっていることと機能的には変わらないですし，これでcondaコマンドは使えるようになるのですが，流石に二つのshellを混ぜて使うことは今後のために良くないと思うので，.zprofileや.zshrcをいじってpathを通した方がいいと思います．

#追記（01/31/2020）
[このサイト](https://www.python.jp/install/anaconda/macos/install.html)の一番下に，
> 利用しているシェルがbashの場合は、自動的に conda が利用できるように設定され、デフォルトのConda環境である base が有効になります。
zshなど、bash以外のシェルを利用している場合は、以下のようにcondaコマンドを設定します。

とありました．（PythonJapanの公式ドキュメントなので，これが最も信頼性が高そうです．）
要するに，"source ~/anaconda3/etc/profile.d/conda.sh"というpathを ~/.zshrc に通しているということですね．(このpathは微妙に異なっている可能性があるので，自分で調べましょう．)
では ~/.zprofile は関係ないのかと思って，上のコピペ部分を消して再度ログインし直してみたところ，それでもcondaを使うことができました．長々と書いてしまいましたが，結局は下のコマンド一発で解決する話だったのですね$\dots$(まあ勉強になったということで$\dots$)

```bash
# bashの場合
$ echo "source ~/anaconda3/etc/profile.d/conda.sh" >> ~/.bashrc

# zshの場合
$ echo "source ~/anaconda3/etc/profile.d/conda.sh" >> ~/.zshrc

# fishの場合
$ echo "source ~/anaconda3/etc/fish/conf.d/conda.fish" >> ~/.config/fish/config.fish
```

#追記 (10/06/2020)
上に書いたことは，**シェル起動時に自動的にcondaの環境変数にソースを通して，conda環境を使えるようにする**方法です．
しかし，bashを使うにしろzshを使うにしろ，シェルを立ち上げたときに自動的にcondaの環境変数を使えるようにしていると，他のソフトウェア環境を使いたいときに，環境変数どうしがもしかしたら干渉してしまうかもしれないそうです．(例えばROS melodic環境とconda環境は相性が悪いらしいので，ROS melodicを使おうとしたときにcondaが邪魔して上手く動かないという話を聞きました．)つまり，上の追記のように ~/.bashrc や ~/.zshrc に書き込んでしまってシェル起動時にconda環境を自動的に許すのではなく，毎回上のsourceコマンドで明示的にconda環境を起動してあげた方がいいらしいです．確かに，condaにしろ他の環境にしろ，シェル起動時にあらゆる環境が自動でオンになってしまうより，その都度選択的にオンにする方が変な干渉も起こらずにいいのかもしれません．
よって，上の書き込みはせずに，毎回sourceコマンドでcondaをオンにしてから使うことが推奨されます．

というわけで，今回のようにzshを使う場合も，**この記事内で書いたように ~/.zprofile や ~/.zshrc の中身をいじるのではなく，condaを使いたい場合はシェル起動時に毎回**

```zsh
$ source ~/opt/anaconda3/etc/profile.d/conda.sh
```
**を叩くようにして，明示的にconda環境の環境変数をオンにするようにしましょう**(このパスは環境によって若干異なると思うので，それぞれ確認しましょう) 今までの努力は何だったんだ...
これによって，シェルを立ち上げた直後はcondaは使えないですが，上のコマンドを通した時にはcondaが使えるようになります．

##bashの場合は？
zshやfishの場合は，このようにすれば，conda環境を明示的に使用できることがわかったと思います．
しかし逆にbashの場合は，anacondaダウンロード時に自動で ~/.bashrcにconda関連の記述が書き込まれる仕様になっているため，自動的にconda環境が使えるようになっています．これは，上記のように環境変数の干渉の観点からありがた迷惑ですよね．
この場合は，~/.bashrc に自動で書き込まれてしまったconda関連の記述部分を別のファイル(例えばsetup.bash)に作り直して(bashrcからはその部分は削除しましょう)，condaを使いたいときのみ

```zsh
$ source (指定のディレクトリ)/setup.bash
```
のようにして毎回叩くようにしましょう．
そうすると，bashの場合も明示的にconda環境の使用をオン/オフできるようになり，他のソフトウェアと干渉する可能性が減っていいです．


[^1]: [参考記事](https://www.theverge.com/2019/6/4/18651872/apple-macos-catalina-zsh-bash-shell-replacement-features)
[^2]: Macの場合，初期状態では ~/.bashrc や ~/.bash_profile は存在しないので，必要に応じて作成する必要があります．今回既に存在していたのは，Anacondaをインストールしたことによって自動的に作成されていたかららしいです．
[^3]: コマンドラインで cat .bash_profile >> .zprofile と実行してもいいらしいです．
[^4]: sourceコマンドについては，[このサイト](https://www.atmarkit.co.jp/ait/articles/1712/21/news015.html)を参照