Envaderを利用して、PATHとは何かを学ぶ。

30代後半、未経験からIT業界のエンジニア転職へ挑戦している、kobakichiです。

今回は、PATHを通す、の意味とその使い方について学んだので、自分なりにまとめようと思います。
正直今まで、PATHとは何か？PATHを通すとは何なのか？について何となく、フワッとした理解しかなかったので、Envaderを通して理解を深める事ができました。

## 初めに
今回学習するにあたり利用したのは、環境構築が不要で、オンラインでLinuxが学べる学習サービス、Envaderを利用しました。

`Envader`について気になる方がいましたら、リンクを貼っておきますので参考までにどうぞ。

[Envader](https://envader.plus/)

[コース一覧](https://envader.plus/course)

[今回使用したシナリオ](https://envader.plus/course/1/scenario/1011)


## PATHとは

Linux環境を触っていると、絶対に避けて通れないのがこの`PATH`についての理解だと思っています。

相対パスや絶対パスなどもありますが、今回の`PATH`については環境変数に設定されている`PATH`の事です。

この環境変数`PATH`が何を意味しているのかですが、シェルがコマンドを実行する際に**コマンドの実行ファイルを探しにいくための道筋と順番**を示しています。

`ls`とコマンドを叩くとカレントディレクトリにあるファイルが表示されますが、裏側ではこの`PATH`に記載されている道筋と順番を見ながら`ls`コマンドのパスを探しに行って、その実行ファイルを実行してくれている事になります。

こちらの記事がすごい分かりやすかったです。
[PATHを通すとは？ (Mac OS X)](https://qiita.com/soarflat/items/09be6ab9cd91d366bf71)

### PATHを実際に見てみる。

環境変数`PATH`を確認するには、`echo $PATH`で表示させる事ができます。

```bash
envader@172-19-1-2:~$ echo $PATH/sbin:/usr/sbin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
```

これが環境変数`PATH`に登録されている、コマンドを実行するときに探しに行く**パスの順番と道筋**になります。
これを**コマンド検索パス**とも表現できるそうです。

パスの表示は`:`で一区切りになっているので、上記をもう少し見やすくすると下記のように分解してみる事ができます。

```bash
/sbin #最初にコマンドを探すのはここ
/usr/sbin #なければここを探す
/usr/local/bin #なければここ
/usr/bin #下に続く
/bin
/usr/local/games
/usr/games
```

こうすると少し分かりやすいかなと思います。
コマンドを叩いたら、シェルがこの上から順番にそのコマンドの実行ファイルがある場所まで探しに行く。というシステムなんですね！

### コマンド実行ファイルがどこにあるのかの確認方法

実際に`ls`と叩いた際に、`PATH`に登録されているコマンド検索パスをシェルが探しにいくのですが、実際にコマンドの実行ファイルがどこに格納されているのか見てみましょう。

確認するには、`which`コマンドを使用します。

```bash
envader@172-19-1-2:~$ which ls
/bin/ls
```
これが`ls`コマンドの実行ファイルが格納されているパスになります。
`ls`と叩くと、シェルがこの`/bin/ls`までファイルを検索して実行している。という事になりますね。

ちなみにこの`/bin`ディレクトリの中身を確認してみると、たくさんのコマンドが格納されていました。

```bash
envader@172-19-1-2:/bin$ ls
bash   dmesg          gzip      mount          rmdir       tempfile      zcmp
cat    dnsdomainname  hostname  mountpoint     run-parts   touch         zdiff
chgrp  domainname     kill      mv             sed         true          zegrep
chmod  echo           ln        nisdomainname  sh          umount        zfgrep
chown  egrep          login     original       sh.distrib  uname         zforce
cp     false          ls        pidof          sleep       uncompress    zgrep
dash   fgrep          lsblk     ps             stty        vdir          zless
date   findmnt        mkdir     pwd            su          wdctl         zmore
dd     grep           mknod     rbash          sync        which         znew
df     gunzip         mktemp    readlink       tailf       ypdomainname
dir    gzexe          more      rm             tar         zcat
```

こんな感じで、各コマンドを叩くと`PATH`に書いてあるコマンド検索パスを通じて、コマンドの実行ファイルを探しに行く。という事なんですね〜。

### 注意点
コマンド検索パスには優先順位があり、もしも同じ名前のコマンド実行ファイルが**複数のコマンド検索パス**に存在していた場合には`PATH`に書いてある左側から順番に実行されるそうです。

```bash
echo $PATH/sbin:/usr/sbin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
```
これだと`/sbin`から順番に実行されるという事ですね。
`/sbin`と`/usr/sbin`に同じ名前の実行ファイルがあった場合には、`/sbin`が実行されるため、注意が必要です。

なんかうまくいかないな〜、と言った場合にはパスの優先度が原因のときもあるそうなので、細かいところですがこう言った順番を頭に入れておくのも必要ですね。

## PATHを追加してみる。
コマンド検索パスを追加したい！となった場合には、`export`コマンドを使用します。

一度`echo $PATH`で現在のコマンド検索パスを再度表示してみます。

```bash
envader@172-19-8-2:~$ echo $PATH
/bin/original/:/sbin:/usr/sbin:/usr/local
/bin:/usr/bin:/bin:/usr/local/games:/usr/games
```

次に、`export`コマンドを使用して、`/home/sample`のPATHを通します。

`export`コマンドを使用することで、
> - 環境変数を表示する事
> - 環境変数を設定する事
> - 環境変数を削除する事

ができるようになります。

コマンドサンプル
```bash
export PATH=$PATH:追加したいコマンド検索パス

#こちらのやり方でも同じ意味になります。少し大変ですが。
export PATH=/bin/original:/sbin:/usr/sbin:/usr/local
/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/home/sample
```
実際にやってみると下のようになります。

```bash
envader@172-19-8-2:~$ export PATH=$PATH:/home/sample
```

再度`echo $PATH`で追加されているか確認します。

```bash
envader@172-19-8-2:~$ echo $PATH
/bin/original:/sbin:/usr/sbin:/usr/local
/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/home/sample
```

末尾に`/home/sample`が追加されていますね。


### コマンド検索パスの順番を変更しながらPATHを追加する

先ほどもご紹介しましたが、コマンド検索パスには優先順位があり、`PATH`に記述されている左側から順にコマンドを探しにいきます。
なので、追加するパスの優先順位を上げたい時には以下のように書く事で、優先順位を上げて`PATH`に記述する事ができます。

```bash
export PATH=追加したいコマンドパス:$PATH
```

実際にやってみましょう。

```bash
envader@172-19-2-2:~$ export PATH=/usr/sample:$PATH

envader@172-19-2-2:~$ echo $PATH
/usr/sample:/bin/original:/sbin:/usr/sbin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
```
ちゃんと指定した`/usr/sample`が最初に追加されているのが分かりますね！


## まとめ

今回はEnvaderを使用して、PATHについての理解を深めました。

- 環境変数`PATH`とは、**コマンド検索パス**とも表現でき、シェルがコマンドを実行する際に**コマンドの実行ファイルを探しに行くための道筋と順番**を表している。
- コマンドを実行するときには、コマンド検索パスに記述されている左側から順に検索され、実行される。
- `export`コマンドを使って、環境変数を表示、設定、削除する事ができる。

最後まで読んでいただきありがとうございました。


## 参考にさせていただいた記事一覧

[PATHを通すとは？ (Mac OS X)](https://qiita.com/soarflat/items/09be6ab9cd91d366bf71)

[PATHを通すために環境変数の設定を理解する (Mac OS X)](https://qiita.com/soarflat/items/d5015bec37f8a8254380)

[Pathを通すとは、環境変数とは](https://qiita.com/fuwamaki/items/3d8af42cf7abee760a81#%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0%E3%81%A8path)

[【Linuxコマンド】exportで環境変数を設定する方法](https://www.sejuku.net/blog/53034)

[export - 環境変数を定義・リスト表示する - Linuxコマンド](https://webkaru.net/linux/export-command/)

[【 export 】コマンド――環境変数やシェル変数を設定する](https://atmarkit.itmedia.co.jp/ait/articles/1801/12/news015.html#:~:text=%E3%80%8Cexport%E3%80%8D%E3%81%AF%E3%80%81%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0,%E5%A4%89%E6%95%B0%E3%80%8D%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%20%E2%80%BB1%E3%80%82)