開発者であれば最初はきっと沼る、PATHと.zshrc周りを調べまくったので備忘録

# 挨拶
絶賛期末テスト期間のGoです!!

テスト期間になるといつも現実逃避で普段はやらないことに時間を注いでしまします。

今回は、今までなんとなくの理解で止まっていた

- それ`path`が通ってないんじゃない？
- `~/.zshrc`を書き換えればOK

の謎を調べて色々いじってみたら理解が進んだ気がするので、
備忘録的な意味を込めてアウトプットしたいと思います。(本当は今こんなことをしてる場合じゃないのに。。。）

# 目標
- ~/.z* ファイルを理解する
- 実行ファイルとPATHの関係を理解する
- 自分でshellスクリプトを書いてpathを通してみる

# 前提
この記事では、シェルに`zsh`を利用しています。
それ以外のシェルを利用している方は、いい感じに読み進めていただけるとありがたいです。

# .zファイルとはなんぞや
zshの設定ファイルを、個人的に総称して.zファイルと呼んでいます。

要するに、`.zprofile`とか、`.zshrc`っていうあいつらです。

環境変数やPATHを通すとき、適当な記事を探してコピペしていた僕にとっては、
これらのファイルの存在を知ってはいたものの、何が違うのかわかりませんでした。

さらっと何が違うかを言ってしまうと、**読み込まれる順番**が違います。

1. zshenv (最初に読み込まれる。影響範囲大。基本は書き込まない）
1. zprofile(ログインシェルの時に一度だけ呼ばれる)
1. zshrc(いつも(*)読み込まれる。一般的に書き込む場所。)
1. zlogin(zprofileとの併用をしない)
1. zlogout(シェルからexitするときに読み込まれる）

(*) ログインシェルとインタラクティブシェルの場合に読み込まれる。

このような順番で読み込まれます。
ここにもある通り、基本的に検索すると出てくるような

```
export PATH=$PATH:通したいパス
```

は、shellで実行するでもよいし、永続化したい(shellからログアウトしても反映させ続けたい）場合は`.zshrc`に書き込んでいく形になります。(ファイルに書き込む場合、exportは不必要らしいです。)

また、
- プロンプトの表示をイケてる感じにしたい
- terminalをカラフルに見やすくしたい
- コマンドの補完の設定をいじりたい

なども基本的には`.zshrc`をいじっていくことになります。
zshのshell設定を書き込むのが基本こちらですね。

詳しい内容に関してはこちらがわかりやすかったので、ご参考ください。

https://wiki.archlinux.jp/index.php/Zsh

or

https://qiita.com/muran001/items/7b104d33f5ea3f75353f

# PATHとは何なのか
色々調査をした結果の自分なりのまとめなのでニュアンスが違ったら申し訳ないのですが。

**PATHとは、実行ファイルとコマンド入力を紐づける環境変数**

という認識が個人的にしっくりきています。

zshユーザーの皆さんはこのような出力を見たことあるのではないでしょうか？

```
go: ~/ % hello.sh
zsh: command not found: hello.sh
```
コマンドがないよというエラーですね。

純粋にtypoであったり、新しい言語の環境構築や、なんらかの実行ファイルをインストールしてきた時にPATHが通っていないとこのようなエラーが出力されます。

この原因を理解するためには、PATHという環境変数について詳しくなるのが手取り早いと思います。

ご自身の環境で、

```
echo $PATH
```

と実行すると

```
/user/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
```

と出力されると思います。

ちなみにこれはmacのデフォルトで、過去にPATHをいじっている方であればもっと長い出力が得られると思います。「：」が区切り文字で表されているので、このような正規表現で綺麗に出力することもできます。

```
go: ~/ % echo $PATH | sed -e 's/:/\n/g'
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin
```

要するに、$PATHの中身には5つのパスが設定されていることがわかります。

これらのファイルはそれぞれ

- /bin …基本的なコマンド
- /sbin …管理者用コマンド
- /usr/bin …アプリケーション用の基本的なコマンド
- /usr/sbin …アプリケーション用の管理者用コマンド
- /usr/local/bin …追加したアプリ用のコマンド

の役割がありますが、

具体的に中身を見てみるともっと理解が深まります。


![スクリーンショット 2022-07-24 18.37.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/845778/69588a5e-07ec-26c7-b42d-9cb74936b4da.png)

これは、`/bin/`の中身ですが、見覚えのある実行コマンドがいくつかあるのではないでしょうか。`ls`とか。`echo`とか。

これらは全て実行ファイルであり、shellでこれらの実行ファイルを入力すると、このディレクトリに格納されているファイルが実行されます。

なので、`/bin/ls`というコマンドは`ls`と同じ意味になります。
なぜ`ls`コマンドだけで実行できるかというと、PATHが通っているからです。

どのような実行ファイルも、実行権限があれば、フルパスをコマンド入力することで実行することはできますが、
毎回フルパスを打つのは面倒なのでPATHという便利な環境変数が存在しています。

# PATHの読み込まれる順番
これは`echo $PATH`で表示される順になります。
例えば、`ls`コマンドを実行した場合、まず、`/usr/local/bin`ディレクトリの中に、`ls`というファイルがあるかを確認します。

なければ、次々PATHに設定されているディレクトリを確認し、`/bin`にls実行ファイルがあるので、これが実行されます。

最後までファイルが存在しないときに、**command not found**が出力されるのです。

さて、それでは、実際に実行ファイルを作成してPATHを通してみましょう！


# hands-on
実際に手を動かしみます！

## 実行ファイルを作成する
ホームディレクトリに`shell`ディレクトリを作成して、`hello.sh`という実行ファイルを作成する。

```
mkdir ~/shell
echo "echo This is hello shell!" > ~/shell/hello.sh
```

これで実行ファイルが作成できたので、フルパスを入力して実行してみましょう。

```
/Users/{{ユーザー名}}/shell/hello.sh
```

ユーザー名がわからない人はtab補完で探してみてください。また、実行権限のエラーが出る人は、
`chmod 777 ~/shell/hello.sh`
を試してから再度実行してみてください。


## PATHを通して見る
理想は、hello.shで実行できることです。
PATHを通すコマンドは`export PATH=$PATH:通したいパス`なので、今回は`export PATH=$PATH:/Users/ユーザ名/shell/`と入力します。

$PATHには環境変数が格納されています。なので、今までのPATHに追記する形で、コロンを区切り文字として実行形式のファイルが格納されている箇所を記載しています。

これで、hello.shを実行するだけでechoが出力されるはず！




## PATHを永続化させる(.zshrc)に書き込む
ただ、この方法だと、一度ターミナルを閉じてしまうと（shellからログアウトすると）、通っていたPATHが消えてしまします。

毎回shellを開くたびにexportするのが面倒なため、.zshrcに書き込んでいきます。（ようやくこいつが役に立ちます！！！）

冒頭でも確認した通り、.zshrcファイルは、zshシェルが起動するときに読み込まれるファイルであるので、ここに`export PATH=$PATH:/Users/ユーザ名/shell/`と入力することで、毎回PATHを通す必要がなくなります。


# 最後に
長らくPATHに苦しめられてきましたが、時間をとることで今まで何をしていたかがわかるようになりました。

ですが、間違いなくテスト期間にやることではないですね。

ローカルPCのPATHの整理は、期末テストが終わってからにしようと思います。

ご精読ありがとうございました。

# 参考
https://knmts.com/become-engineer-2/
https://utatane-cheers.hatenablog.com/entry/2017/11/26/131959