UNIX/Linuxの部屋 環境変数:PATH

TOP UNIX/Linuxの部屋 UNIX/Linuxコマンド一覧 用語集 新版 由来/読み方辞書 環境変数マニュアル Cシェル変数 システム設定ファイル システムコール・ライブラリ ネットワークプログラミングの基礎知識 クラウドサービス徹底比較・徹底解説




環境変数 PATH コマンド・プログラムの置いてあるディレクトリ名を設定する このエントリーをはてなブックマークに追加

最終更新


環境変数 PATH は、コマンド名のみをタイプした際、どこに置いてある実行ファイルを実行すべきかを探すための仕組みである。



PATH の役割
ls とタイプすると /bin/ls が実行されるのはパスという仕組みのおかげである。PATH の内容が
% echo $PATH
/bin:/usr/bin:/usr/local/bin
であるとき、less とタイプすると、
/bin/less
/usr/bin/less
/usr/local/bin/less
の順にプログラムが検索され、コマンドが見つかるとそれが実行される。もし /bin/less が存在すればそれが実行される。もし /bin/less がなくて、/usr/bin/less が存在すれば、/usr/bin/less が実行される。もし /usr/bin/less と /usr/local/bin/less の両方が存在すれば先に書いてある方の /usr/bin/less が実行される。

PATH を変更・追加するには (パスを通す)
単に「less」とタイプしたとき、/usr/local/bin ではなく ~/bin/less を実行したい場合、PATH を変更する。

方法1. パスの順番を変えて全体を設定しなおす
% PATH="$HOME/bin:/bin:/usr/bin:/usr/local/bin"; export PATH
→ sh・bcsh の場合
% setenv PATH $HOME/bin:/bin:/usr/bin:/usr/local/bin
→ csh・tcsh の場合
方法2. PATH の先頭に追加する
% PATH="$HOME/bin:$PATH"; export PATH
→ sh・bcsh の場合
% setenv PATH "$HOME/bin:$PATH"
→ csh・tcsh の場合
なお、PATH 内に同じディレクトリが複数箇所に出現したとしても、特に動作には問題はない (もちろん、あまりキレイではないが)。

また、PATH を変更せずに、alias で
% alias less="$HOME/bin/less"
→ sh・bcsh の場合
% alias less ~/bin/less
→ csh・tcsh の場合
と設定する手もある。

同名のコマンドが複数存在するかどうかを調べる場合は where コマンドを使う (csh・tcsh の場合)。
% where foo
/usr/bin/foo
/usr/X11R6/bin/foo
この場合は先に表示されている /usr/bin/foo が実行されることになる。

シェル変数 path を変更すると、即座に環境変数 PATH にも反映される。逆も同じである。つまり、パスを設定するには、シェル変数 path を設定してもよいし、環境変数 PATH を設定してもよいということである。

セキュリティ上の注意点: PATH に . を含めてはいけない
なお、下記のようにパスに '.' (カレントディレクトリ) を含めるのは危険である。例えば
% setenv PATH ".:/bin:/usr/bin:${HOME}/bin:/usr/local/bin"
→ csh・tcsh の場合
% PATH=".:/bin:/usr/bin:${HOME}/bin:/usr/local/bin"; export PATH
→ sh・bash の場合
と PATH の先頭に '.' を記述していたとする。そのとき、
% cd /tmp
% ls
とすると、もし /tmp/ls が存在した場合、意図せず実行してしまう。もし/tmp/ls の中身が
#!/bin/sh
/bin/rm -rf $HOME
だったとしたら、あなたのホームディレクトリのファイルは全て消えてしまうことになるわけだ。もっとタチの悪いのは、
% cd /tmp
% cat ls
#!/bin/sh
cp /bin/sh /tmp/sh-$USER >/dev/null 2>&1
chmod 4755 /tmp/sh-$USER >/dev/null 2>&1
exec /bin/ls "$@"
と書いておくと、そのユーザの権限になることができる /bin/sh ができあがり。一見、ls を実行しているように見えるので、気づきにくい。

では、PATH の先頭ではなく PATH の末尾に '.' を書くのはどうか。/tmp/ls よりも /bin/ls が先に実行されてしまうので成功率は下がるだろうが、/tmp/sl を配置して ls を sl とタイプミスするのを狙う攻撃は、何日も何ヶ月も待てば成功するかもしれない。結論としては PATH に '.' を含めるべきではない、ということだ。

セキュリティ上の注意点 その2: 空文字は . を意味する
さらにもう一点。PATH の要素に空文字があった場合、それは '.' カレントディレクトリ と同じ意味となる。例えば
% PATH="${PATH}:"; export PATH
⇒ sh・bash の場合
% setenv PATH "${PATH}:"
⇒ csh・tcsh の場合
は "${PATH}:." と同じ意味となる。「わざわざそんな書き方しないよ」と思うかもしれないが、
% setenv PATH "${PATH}:${ADD_PATH}"
% PATH="${PATH}:${ADD_PATH}"; export PATH
と書いたときに $ADD_PATH が空だったら、"${PATH}:" となってしまう。この挙動は LD_LIBRARY_PATH も同じであって、Apache httpd の CVE-2012-0883 の脆弱性がまさにこれ。"insecure ld_library_path -apache" で検索すると他にも同様に修正しているプロジェクトがたくさん見つかる。