環境変数PATHを削除すると強者モードになった

# はじめに
Linuxにおける環境変数の理解を深めるために環境変数PATHを削除して遊んでみました。
もちろん自分のPCでそんなことやりたくないので、「エンベーダー」というブラウザ上でLinux環境を使えるサイトを使ってやりました。
Linux環境を手軽に試せるのでおすすめです。

[エンベーダー](https://envader.plus/)

## 環境変数PATHとは

そもそもLinuxなどシェルで使えるコマンドは実行ファイルで定義されていて`/bin`や`/usr/bin`などのディレクトリにまとめて置かれています。
それら実行ファイルの置かれているディレクトリのパスを環境変数`PATH`にまとめて定義してあります。
そのおかげでコマンドを入力すると環境変数`PATH`の中のディレクトリ内を検索して実行してくれています。

## 環境変数PATHが無かったら？

エンべーダーで実際に試してみました。
まずエンベーダーにログインして、適当なシナリオを選択してターミナルを使えるようにします。
適当に「Linux入門コース」の1を選択し、コマンド試すボタンを押すとターミナルの画面になります。

始めに現在の環境変数`PATH`を確認します。

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

このようなディレクトリが格納されているようです。

試しに`/bin`の中を見てみます。

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

これらのコマンドが`/bin`の中に定義されているのが分かりました。

では環境変数を削除してみます。`export`コマンドで`PATH`を空にしてみます。

```bash
envader@172-19-1-2:~$ export PATH=""
```
`echo`コマンドで確認すると

```bash
envader@172-19-1-2:~$ echo $PATH

```

何も入ってないのが分かります。

`ls`コマンドを実行してみます。
```bash
envader@172-19-1-2:~$ ls
-bash: ls: No such file or directory
```
そのようなファイルやディレクトリは無いと言われました。
実行するには絶対パスを指定する必要があります。

```bash
envader@172-19-1-2:~$ /bin/ls
hint.txt  sample  secret_d
```

これで実行されました。全てのコマンドの絶対パスを把握してないと使えない強者モードになりました。
けどコマンドのパスがわからなくなったらどうやって調べるのでしょう？
`which`コマンドで調べてみます。

```bash
envader@172-19-1-2:~$ /bin/which ls
envader@172-19-1-2:~$
```

そうですよね。環境変数にないのでもう調べることすらできない。
強いてやるなら`find`コマンドで当たりを付けて調べることくらいでしょうか？もちろん`find`コマンドも絶対パスで指定する必要があります。

```bash
envader@172-19-1-2:~$ /usr/bin/find /bin /usr/bin -name ls
/bin/ls
```

試しに`cd`コマンドを実行すると使えました！！
`cd`コマンドはビルトインコマンドのため環境変数無しに実行できるようです。
`help`コマンドを実行するとビルトインコマンドを確認できます。

```bash
envader@172-19-1-2:~$ help
GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)
These shell commands are defined internally.  Type `help' to see this list.
Type `help name' to find out more about the function `name'.
Use `info bash' to find out more about the shell in general.
Use `man -k' or `info' to find out more about commands not in this list.

A star (*) next to a name means that the command is disabled.

 job_spec [&]                      history [-c] [-d offset] [n] o>
 (( expression ))                  if COMMANDS; then COMMANDS; [ >
 . filename [arguments]            jobs [-lnprs] [jobspec ...] or>
 :                                 kill [-s sigspec | -n signum |>
 [ arg... ]                        let arg [arg ...]
 [[ expression ]]                  local [option] name[=value] .>
 alias [-p] [name[=value] ... ]    logout [n]
 bg [job_spec ...]                 mapfile [-d delim] [-n count] >
 bind [-lpsvPSVX] [-m keymap] [->  popd [-n] [+N | -N]
 break [n]                         printf [-v var] format [argume>
 builtin [shell-builtin [arg ...>  pushd [-n] [+N | -N | dir]
 caller [expr]                     pwd [-LP]
 case WORD in [PATTERN [| PATTER>  read [-ers] [-a array] [-d del>
 cd [-L|[-P [-e]] [-@]] [dir]      readarray [-n count] [-O origi>
 command [-pVv] command [arg ...>  readonly [-aAf] [name[=value] >
 compgen [-abcdefgjksuv] [-o opt>  return [n]
 complete [-abcdefgjksuv] [-pr] >  select NAME [in WORDS ... ;] d>
 compopt [-o|+o option] [-DE] [n>  set [-abefhkmnptuvxBCHP] [-o o>
 continue [n]                      shift [n]
 coproc [NAME] command [redirect>  shopt [-pqsu] [-o] [optname ..>
 declare [-aAfFgilnrtux] [-p] [n>  source filename [arguments]
 dirs [-clpv] [+N] [-N]            suspend [-f]
 disown [-h] [-ar] [jobspec ... >  test [expr]
 echo [-neE] [arg ...]             time [-p] pipeline
 enable [-a] [-dnps] [-f filenam>  times
 eval [arg ...]                    trap [-lp] [[arg] signal_spec >
 exec [-cl] [-a name] [command [>  true
 exit [n]                          type [-afptP] name [name ...]
 export [-fn] [name[=value] ...]>  typeset [-aAfFgilnrtux] [-p] n>
 false                             ulimit [-SHabcdefiklmnpqrstuvx>
 fc [-e ename] [-lnr] [first] [l>  umask [-p] [-S] [mode]
 fg [job_spec]                     unalias [-a] name [name ...]
 for NAME [in WORDS ... ] ; do C>  unset [-f] [-v] [-n] [name ..>
 for (( exp1; exp2; exp3 )); do >  until COMMANDS; do COMMANDS; d>
 function name { COMMANDS ; } or>  variables - Names and meanings>
 getopts optstring name [arg]      wait [-n] [id ...]
 hash [-lr] [-p pathname] [-dt] >  while COMMANDS; do COMMANDS; d>
 help [-dms] [pattern ...]         { COMMANDS ; }
 
```

なるほど、`cd`コマンド、`help`コマンド含めビルトインコマンドって色々あるんですね。

```bash
envader@172-19-1-2:~$ echo "わーい"
わーい
```

`echo`も使えますね！

ただ、ほとんどのコマンドを絶対パスを指定しないといけないなんて不便過ぎる。。。
今回は遊び半分でやってみましたが、絶対に自分の環境ではやりたくないです。

環境変数`PATH`さんに感謝です。

皆さんも、やるなら絶対に自分の環境でやらないことをお勧めします。