bash初期化ファイル読み込みの順番 まとめ

#疑問
普段何気なく使っている `.bashrc` ですが、bashの場合下記のファイルもスタートアップの時に使えます。

.bash_login
.bash_profile
.bashrc
.profile

一体何が違うのでしょうか？

忙しい人のために、先に まとめておきます。

#まとめ

bashは、

- ログインシェルとして起動された場合、
    - /etc/profile をまず読み込む
    - その後、以下のファイルを順番に探して、最初に見つけたファイル**のみ**を起動スクリプトとして読み込む。
        - ~/.bash_profile
        - ~/.bash_login
        - ~/.profile
    - .bashrcは、読み込まない
        - でも、デフォルトでインストールされる`.profile`で、`.bashrc`も読み込むように設定されている
- ログインシェル以外で起動された場合は、
    - /etc/bash/bashrc をまず読み込む
    - ~/.bashrcを読み込む

#マニュアルを見てみる
とりあえず、マニュアルを見てみると・・・

>When bash is invoked as an interactive login shell, or as a  non-inter‐
active  shell with the --login option, it first reads and executes com‐
mands from the file /etc/profile, if that file exists.   After  reading
that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile,
in that order, and reads and executes commands from the first one  that
exists  and  is  readable.  The --noprofile option may be used when the
shell is started to inhibit this behavior.

まとめると、こんな感じみたいです。

- login shell として起動された場合
    + /etc/profile を読み込む
    - ~/.bash_profile があったら読んで終わり
    - ~/.bash_login があったら読み込んで終わり
    - ~/.profile　を読み込む

つまり、/etc/profile は必ず読み込まれますが、~/　にある３つのファイルは、最初に見つかったファイル以外は読み込まれません。

ちなみに、.bashrc は、

>When  an  interactive  shell that is not a login shell is started, bash
reads and executes commands from  /etc/bash.bashrc  and  ~/.bashrc,  if
these  files  exist.  This may be inhibited by using the --norc option.
The --rcfile file option will force bash to read and  execute  commands
from file instead of /etc/bash.bashrc and ~/.bashrc.

- login shell　じゃない場合
    - /etc/bash.bashrc　を読み込む
    - ~/.bashrc　を読み込む

つまり、両方のファイルが読み込まれます。

#新たな疑問

ここで、「あら？」と思いました。　いつもログインすると　.bashrc が、ちゃんと実行されているからです。

しかし、マニュアルによると、ログインの時には`~/.bashrc‘は読み込まれないと読み取れます。


先に、結論を書くと

```bash:~/.profile
# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
	. "$HOME/.bashrc"
    fi
fi
```

ubuntuを使っているのですが、デフォルトでこのような`.profile`が設定されているようです。

この問題を調べるのに、bashのソースまで追いかけてみたのですが、結局関係ありませんでした。

ちなみに、

```c:shell.c
   1077 #if defined (NON_INTERACTIVE_LOGIN_SHELLS)
   1078   if (login_shell && posixly_correct == 0)
   1079 #else
   1080   if (login_shell < 0 && posixly_correct == 0)
   1081 #endif
   1082     {
   1083       /* We don't execute .bashrc for login shells. */
   1084       no_rc++;
   1085 
   1086       /* Execute /etc/profile and one of the personal login shell
   1087          initialization files. */
   1088       if (no_profile == 0)
   1089         {
   1090           maybe_execute_file (SYS_PROFILE, 1);
   1091 
   1092           if (act_like_sh)      /* sh */
   1093             maybe_execute_file ("~/.profile", 1);
   1094           else if ((maybe_execute_file ("~/.bash_profile", 1) == 0) &&
   1095                    (maybe_execute_file ("~/.bash_login", 1) == 0))              /* bash */
   1096             maybe_execute_file ("~/.profile", 1);
   1097         }
   1098 
   1099       sourced_login = 1;
   1100     }
 ```
1978 or 1080行目は、ログインシェルで、さらにposixモードではない場合という意味です。posixモードの時は `＄ENV` でｒｃファイルを指定するようです。

1092行目は、bsh として起動されている場合は、`~/.profile`のみを読み込み、bashとして起動されている場合は、上記の3つのファイルを順番に調べて、最初に見つけたファイル *のみ* を読み込みます。

つまり、マニュアル通りｗ

結局 なんだよなぁ・・・ という感じでしたが、普段あまり見ない`bash`ソースも（ほんのちょこっとですが...汗）読めたので良しとしましょう。

#おまけ
ちなみに、`/etc/profile`では、下記の通り`/etc/profile.d/`に置いてあるスクリプトを実行するようになっているので、システムワイドで設定をしたい場合は、`/etc/profile.d/`にファイルを作っておくと、自動的にログインの時に読み込まれるようになっています。 `なんちゃら.d`にまとめるのは最近の流行りみたいです。

```bash:/etc/profile
for i in /etc/profile.d/*.sh ; do
    if [ -r "$i" ]; then
        if [ "${-#*i}" != "$-" ]; then
            . "$i"
        else
            . "$i" >/dev/null 2>&1
        fi
    fi
done
```

おしまい・・・・・