概要
.bash_profileを作成したところ、MacPortsでインストールしたパッケージが見えなくなって困っていたのですが、ようやく解決しました。
直接の原因は.bash_profileを作成したことで.profileが読み込まれなくなり、それによってMacPortsがインストールしたパッケージへのPATHが反映されなくなったためです。
しかし、元を辿れば.profile・.bash_profile・.bashrcといったファイル群の依存関係を正しく理解していなかったことが原因です。また、これらの依存関係はUnix系OS全般に共通する振る舞いでもあるため、この機会に整理してみました。
問題
.bash_profileがないときは/opt/local/bin/rubyが見える。
$ which ruby
/opt/local/bin/ruby
しかし.bash_profileがあると/usr/bin/rubyを見てしまう。
$ which ruby
/usr/bin/ruby
.bash_profileのある/なしでPATHが書き換わっている?
解決方法
.profileに次のような記述がありました。おそらくMacPortsが追記したものですが、.bash_profileがあると.profileが読み込まれなくなり、この記述が反映されなくなったことが原因でした。
FILE: ~/.profile
export PATH=/opt/local/bin:/opt/local/sbin:$PATH
そこで、.bash_profileの先頭にsource ~/.profile
を追記することで解決しました。
FILE: ~/.bash_profile
source ~/.profile
.profile・.bash_profile・.bashrcといったファイルの依存関係
ログインしたときに呼び出されるファイル
ログインするとまず/etc/profileが呼び出され、次に残り3つのうちのどれか1つが呼び出されます。
/etc/profile |
全ユーザーに共通の環境変数と起動プログラムを記述します。 |
~/.bash_profile |
ユーザー固有の環境変数と起動プログラムを記述します。 |
~/.bash_login |
~/.bash_profileが存在しないとき、代わりに呼び出されます。 |
~/.profile |
~/.bash_profile・~/.bash_loginともに存在しないとき、代わりに呼び出されます。 |
プロセスとしてbashを起動したときに呼び出されるファイル
プロセスとしてbashを起動すると~/.bashrcが呼び出されますが、通常、その先頭で/etc/bashrcを呼び出しています。
~/.bashrc |
ユーザー固有のエイリアスと関数を記述します。 |
/etc/bashrc |
~/.bashrcに呼び出しが記述されています。 |
.bash_profileと.bashrcの使い分け
子プロセスに引き継がれる情報はログイン時に一度だけ定義すればいいので、~/.bash_profileに記述するのがよさそうです。例えば環境変数がこれに当たります。
子プロセスに引き継がれない情報はプロセスとしてbashを起動する度に定義し直す必要があるので、~/.bashrcに記述するのがよさそうです。例えばエイリアスがこれにあたります。
環境変数を~/.bashrcに記述するとどうなるか?
環境変数を含めて、すべての記述を~/.bashrcにまとめるというのもよく聞きます。実際、環境変数を~/.bashrcに記述するとどうなるのでしょうか?実験として、次の一行を~/.bashrcに追加してみました。
FILE: ~/.bashrc
export PATH=/usr/local/sbin:$PATH
子プロセスとしてbashを起動するたび、繰り返し環境変数が定義されています。害はないようですが、あまり気持ちのいいものではありません。
$ echo $PATH
/usr/local/sbin:/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin
$ bash
$ echo $PATH
/usr/local/sbin:/usr/local/sbin:/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin
$ bash
$ echo $PATH
/usr/local/sbin:/usr/local/sbin:/usr/local/sbin:/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin
エイリアスを~/.bash_profileに記述するとどうなるか?
ではエイリアスを~/.bash_profileに記述するとどうなるのでしょうか?実験として、次の一行を~/.bash_profileに追加してみました。
FILE: ~/.bash_profile
alias ymd="date +%Y%m%d%H%M%S"
子プロセスとして起動したbashではエイリアスが機能しません。
$ ymd
20120103202611
$ bash
$ ymd
bash: ymd: command not found