#前書き
ちょっとしたプログラムを書いて実行するとき、浮かんでは放っといた(←よくない)ある疑問を調べてみたのでまとめてみた。
「なぜ、ターミナルでカレントディレクトリにあるファイルを実行するときファイルの名前だけでは実行されないのか。」
#"."と"/"の意味
UNIX系のOSではそのファイルまでの絶対パスまたは相対パスを書くことでそのファイルを実行できる。
それなら、cdでカレントディレクトリに移動したらそこのファイルはファイル名だけで実行できるのではないか。
デスクトップに置いたtestフォルダ内のhogeファイルで試してみる。
$ cd /Users/ユーザー名/Desktop/test
$ hoge
-bash: hoge: command not found
うまくいかない。メッセージを見ると「hogeなんてコマンド見つからないよ」と言われている。コマンドは実行するファイルを指示することなので、「hogeなんてファイル見つからないよ」と言われているようなものである。
ここで、このファイル名の頭に**"./"**(ドットスラッシュ)をつけてみる。
$ ./hoge
hogehoge
実行されてちゃんとhogehogeと返してくれた。それには理由がある。
まず、UNIX系のOSでは**"."(ドット)に「カレントディレクトリ」**の意味がある。
それに**「ディレクトリの区切り」を意味する"/"**(スラッシュ)をつけることで、上記はhogeへの相対パスを書いていることになるのだ。
よって./hogeはうまく実行されたのである。
記号 | 意味 |
---|---|
. |
カレントディレクトリ。 ..と2つ並ぶと1つ階層が上のディレクトリを示す。 |
/ |
ディレクトリの区切り。 1番最初に書かれている/だけ**ルート(最上位の階層)**という特別な意味を持つ。 |
#なぜ、ファイル名だけでは実行できないのか
###それは、PATHに登録されていないから
./をつければ実行できる理由は分かったが、なぜカレントディレクトリのファイルはファイル名だけでは実行できないのか。
それは、UNIX系OSではファイル名だけで実行するとそのファイルを探しに環境変数のPATHを参照しにいくからである。
PATHとは**「実行ファイルがある場所の絶対パスが保存されている」**OSが持つ変数であり、カレントディレクトリのパスはそこには含まれていない。
そのため、カレントディレクトリのファイルはファイル名のみでは実行できないのである。
PATHに登録されているパスは以下のコマンドで確認できる。
$ printenv PATH
/usr/bin:/bin:/usr/sbin:/sbin
実行してみるといくつかのパスが:で区切られて表示される。
これらの場所にあるファイルのみがファイル名のみで実行できるようになっているのである。
printenvもこのパスの場所にちゃんとファイルが存在する。
それはwhichというコマンドで以下のように確認できる。何もいじってなければ以下のような結果になるはずだ。当然whichも存在する。
$ which printenv
/usr/bin/printenv
$ which which
/usr/bin/which
少し話がずれてしまったので戻そう。
つまり、どうしてもあるファイルをファイル名のみで実行したいときは、そのファイルがある場所のパスをPATHに登録することでファイル名のみでも実行できるようになる。
これが世に言う「パスを通す」である。
これについては以下の記事がとても分かりやすいので紹介したい。
###カレントディレクトリをPATHに登録すればいいんじゃない?(ダメです)
さて、勘の良い方はここまでで"."をPATHに登録すればカレントディレクトリのファイルをファイル名のみで実行できるようになると思われるだろうがそれは正しい、がおすすめはできない。それにより困ることがあるのだ。
簡単なものだと、PATHに登録されている別のファイルと名前がかぶることが考えられる。
名前がかぶってしまうと登録の順番によってはその時呼び出したいファイルが呼び出せなくなってしまう。
もっと深刻なものだと、セキュリティの問題がある。
カレントディレクトリのファイルなら何でもOKということは、ターミナルを開いてすぐのカレントディレクトリであるホームディレクトリでもファイル名のみで実行できるということだ。
それの何が困るのか。
例えば、ホームディレクトリによく使うコマンドの名前(cdなど)をつけた悪意があるファイルをクラッカーが置いたとする。
すると、本来のユーザは何も考えずにそれを実行してしまう可能性があるのだ。
よって、何も考えずに"."をPATHに登録してはいけない。
このようにちゃんとした理由があり、カレントディレクトリのファイルはファイル名のみで実行できないようになっていることが分かった。
#参考サイト
"パスが通っていない"場所の実行ファイル
・ http://ftp.lumica.co.jp/_operation/path_through.html#target_nopathexec01
カレントディレクトリのプログラムを実行するには
・ https://atmarkit.itmedia.co.jp/flinux/rensai/linuxtips/040execcaprog.html
セキュリティの考察
・ https://linuxjf.osdn.jp/JFdocs/Path-12.html
パスを通す
・ https://linuc.org/study/knowledge/349/
#あとがき 兼 自己紹介
初めまして、manaeと申します。
ここまで記事を読んでいただきありがとうございます。少し長くなってしまいました。
Birdmanという会社でDevice Developerをしております。コロナ禍入社の2年目です。
Qiitaではふとした疑問について調べたことや、勉強した技術について記事にまとめていこうと思っております。
まだまだ初心者なので間違っていることがありましたらご指摘いただけると幸いです。何卒よろしくお願いいたします。