.bash_profileがあるとMacPortsでインストールしたパッケージが見えなくなる

概要

.bash_profileを作成したところ、MacPortsでインストールしたパッケージが見えなくなって困っていたのですが、ようやく解決しました。

直接の原因は.bash_profileを作成したことで.profileが読み込まれなくなり、それによってMacPortsがインストールしたパッケージへのPATHが反映されなくなったためです。

しかし、元を辿れば.profile・.bash_profile・.bashrcといったファイル群の依存関係を正しく理解していなかったことが原因です。また、これらの依存関係はUnix系OS全般に共通する振る舞いでもあるため、この機会に整理してみました。



検証環境

Mac OS X 10.6.8
GNU bash version 3.2.48(1)-release (x86_64-apple-darwin10.0)
CentOS release 5.6 (Final)
GNU bash version 3.2.25(1)-release (x86_64-redhat-linux-gnu)



問題

.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

# MacPorts Installer addition on 2010-05-05_at_23:11:58: adding an appropriate PATH variable for use with MacPorts.
export PATH=/opt/local/bin:/opt/local/sbin:$PATH
# Finished adapting your PATH environment variable for use with MacPorts.

そこで、.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