OS や開発言語の〇〇PATHって何よ? ③環境変数PATH


前回のお話

  • プログラムを実行する場合、疑いの余地なく一意に決まる方法=フルパス/FQDNで呼ぶ必要があるよ。
  • フルパスでの呼び方は、可搬性に劣るので、そのままだと問題ありありだよ。
  • そこで、コマンドサーチパスの概念を導入するよ。

名前空間導入のデメリット

ディレクトリを導入すると、同一空間に複数の同一名称のファイルが存在できるようになりました。このファイルを一意に特定するにはフルパス(FQDN)という、長い文字列をコマンドとして利用する必要があります。ここまでに出てきた関連する原則は

  • コンピュータは複数存在しえるものを「勝手に類推」して使ってしまってはいけない。

です。でも実際問題

$ /usr/bin/python
$ python

は、両方同様に動作します。あれ?「フルパスいらないじゃん。」確かにそう見えます。これは、ユーザの利便性を向上させるために導入された以下のルールのおかげです。

  • コンピュータは「ユーザが指定した」パスを、順番に「実行ファイル」を探し出して、それを実行することを許される

これにより、コンピュータは以下の流れに従って、実行すべきプログラムを「探し出して」「実行」します

  • ユーザの指定したパスの中から順に、実行対象のファイルの名前を探査する。
  • 最初にマッチしたファイルを実行し、それ以上の探査は実行しない。

ちょうど以下の図のようなイメージです。

この図で、①~④のディレクトリが、調査対象として登録査定されているものとします。

$ python

①:pythonファイルは存在しないため、次のパスの探査に移る
②:pythonファイルは存在しないため、次のパスの探査に移る
③:pythonファイルが存在しているため、コンピュータは 以下と解釈して実行する。

$ /home/shupe/python/bin/python

この時既に③でプログラムが発見されているため、コンピュータは④を検索しません。

環境変数PATH

コンピュータはユーザからどうやって「ここを探せ」という情報を与えられるのでしょう?多くのOS(オペレーティングシステム)では「環境変数」という仕掛けを使います。環境変数とは、ユーザがコンピュータに「動作環境」を知らしめるための設置を保持する変数です。
環境変数の例を以下に示します。

HOME="/home/***"       ユーザのホームディレクトリ
LANG="ja_JP.UTF-8"       利用する文字コード
LOGNAME="***"            ユーザ名
SHELL="/bin/bash"        ログインシェル

どの値も、ユーザとコンピュータの「動作環境」に関する「決めごと」です。さて、前述のコマンドサーチパスもユーザとコンピュータの間の決めごとなので、当然環境変数を利用して教えてあげる必要があります。歴史的な経緯からなのか、どのOSでも環境変数 PATH を利用して設定します。。参考まで、私の環境のPATHをお見せします。

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin

PATHは : をセパレータとして複数設定することが可能であることが読み取りれます。この場合、以下の順でコマンドを探して来ます。

  1. /usr/local/sbin
  2. /usr/local/bin
  3. /usr/sbin
  4. /usr/bin
  5. /sbin

よくあるはまりポイント

よくある問題として「〇〇というコマンドが使えない。」というものがあります。

$java
コマンド 'java' が見つかりません。

この場合考えられるのは

  1. 対象のプログラムが存在しない
  2. 対象のプログラムがコマンドサーチパス上に存在しない。

1は対象のプログラムを導入する必要がありますし、パッケージャを使えばまぁ普通に動作します。2の場合は以下のコマンドで環境変数を設定する必要があります。

export PATH=<PATH/TO/TARGET/DIRECTORY>:$PATH

ここで注意すべきは 「コマンドサーチパスはディレクトリである必要がある」 ことです。
(コマンドサーチパスの役割を理解していれば当然ですね。)ときどき、初心者の皆さんはここで「ファイル」を追加したりしますので注意が必要です。

また、こんな失敗もあるあるです。

export PATH=<PATH/TO/TARGET/DIRECTORY>

これだと、従来のPATH設定をすべてつぶしてしまっているので、あらゆるコマンドを探すことができなくなるので、注意が必要です。

export PATH=$PATH:<PATH/TO/TARGET/DIRECTORY>
or
export PATH=<PATH/TO/TARGET/DIRECTORY>:$PATH

とすることで、上書き前のPATHの値を保持しますので、どちらか都合の良い方を洗濯して利用しましょう。
~/.bash_profile~/.bashrc/ を編集時にこの失敗をすると、ドツボにはまるのでご注意を。

名前解決

ここでの環境変数PATHの様に、ある論理的な名前を実際の動作環境に合わせて読み替える処理を 「名前解決」 といいます。せっかくなので覚えておきましょう。

まとめ

  • コマンドサーチパスの導入によって、ユーザの利便性は向上するよ
  • OSとユーザの決めごとは 環境変数 を使って設定するよ
  • コマンドサーチパスは環境変数 PATH を使って設定するよ
  • コマンドサーチパスの設定は注意して実行する必要があるよ。

次回は、その他の〇〇PATHについてお話します。