linuxの$PATHが最初に定義される場所

これは職場で話題になった話です。
普段生活する上では全く役に立ちそうもありません。


しかし雑学に飢えている、もしくはググッてたどり着いた、あるいは内容を忘れて自分の雑記を調べている未来の自分の為に雑記にしておきます。

linuxでコマンドを打ったとき、当たり前のようにコマンドが実行されますが、その実態がどこにあるかということはあまり意識しませんし、フルパスで入力することも(滅多には)ありません。
もちろん/sbinや/binの中身ぐらいはだいたい把握していることが多いと思います。

私がが打ったそのコマンド、実態はどこにありますか?という悩みを解決してくれるのはwhichコマンドですが、システムの中に同じファイル名のプログラムがインストールされていることはよくある話です。


書き忘れましたが、bashでの話です。ほかshell愛用者の方は、適宜脳内sedをお願いします。

whichコマンドの使用例

[earth@gate ~]$ which python
/usr/local/bin/python

だけどそのシステムには同じファイル名をもつプログラムがないというわけではない

[earth@gate ~]$ find /usr/local/ -name python -type f
/usr/local/python/2.7/bin/python
/usr/local/bin/python


どういう順序でどの場所にあるプログラムを呼ぶか、ということは、環境変数'PATH'で定義されている順番によって変化します。
このあたりまでは、常識ですが、問題はその$PATHはどこで定義されたのか、という話です。



現在の環境変数$PATHを確認する方法
左側から順に探して、一番最初に見つかったプログラムがwhichコマンドで帰ってくる

[earth@gate ~]$ echo $PATH
/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/home/earth/bin


$PATHは変数ですので、代入することが出来ます。
代入して、exportすれば良いというのは、常識(bashユーザでは)です。


また、ログイン時に実行される各種プロファイルでPATHを追加できる、ということも常識ですね。


ユーザがログインしてきた場合、/etc/profileや、/etc/bash_profile、/etc/profile.d/*.sh、/etc/bashrc、ユーザのホームディレクトリにある各種ファイルによって$PATHは追加されていきます。
この点も、よく知られた話です。

ここまでは常識なので、大した話題にもならないのですが、職場で話題になったのはこの先です。


CentOSの/etc/profileから・・・

[earth@gate ~]$ cat /etc/profile
# /etc/profile

# System wide environment and startup programs, for login setup
# Functions and aliases go in /etc/bashrc

pathmunge () {
        if ! echo $PATH | /bin/egrep -q "(^|:)$1($|:)" ; then
           if [ "$2" = "after" ] ; then
              PATH=$PATH:$1
           else
              PATH=$1:$PATH
           fi
        fi
}

あれ?一番最初に読むprofileで、すでに$PATHがあるか確認してる。
もしかして、もっと前で定義しているの?ということで、隣席のおっちゃんと調べた結果、init.dの中で代入しているということがわかりました。(一緒に調べていたんですが、おっちゃんに先に見つけられてしまいました)

[earth@gate ~]$ cat /etc/init.d/functions
# -*-Shell-script-*-
#
# functions     This file contains functions to be used by most or all
#               shell scripts in the /etc/init.d directory.
#

TEXTDOMAIN=initscripts

# Make sure umask is sane
umask 022

# Set up a default search path.
PATH="/sbin:/usr/sbin:/bin:/usr/bin"
export PATH

起動スクリプトは勉強になりますね、というおはなしでした。


bashソースコードハードコートされてるみたいよ、という情報を別ソースから頂きました。
ソースコードまでは見なかった・・・。
べた書きされてるとしたら、ソースコードの方が先かもしれない。