LoginSignup
27
30

More than 1 year has passed since last update.

Linuxサーバログイン時の/etc/bashrc、/etc/profile、~/.bashrc、~/.bash_profile等の読み込み順序が気になったので調べてみた

Last updated at Posted at 2021-07-22

「LinuCレベル1」の試験勉強をしていると、bashの設定ファイルの読み込み順序について、以下のような表で説明されていました。

全員が参照 ユーザー個別で参照
ログイン時に読み込み /etc/profile 1. ~/.bash_profile
2. ~/.bash_login
3. ~/.profile
bash起動時に読み込み Debian系: /etc/bash.bashrc
RedHat系: /etc/bashrc
~/.bashrc

この読み込み順序のルールについてはなんとなく知ってはいたんですが。。。

  • /etc/profile~/.bash_profile はどちらが先に読み込まれるの?
  • ホームディレクトリ配下で ~/.bash_login というファイルは見たことがないけど、このファイルの読み込み順序はどうなってるの?
  • RedHat系とDebian系で違いはあるの?

といった点が気になってしまったので、実際に検証してみました。


今回の動作確認環境

  • Vagrant 2.2.14
  • CentOS 8
  • Ubuntu21.10 (Impish Indri)

CentOS8の場合

RedHat系OSの検証環境としてCentOS8を利用します。

まず、既存の各設定ファイルの開始行に「ファイル名:start」、最終行に「ファイル名:end」と出力されるように追記してみました。

$ sudo sed -i '1i echo "/etc/profile:start"' /etc/profile
$ sudo sed -i '$a echo "/etc/profile:end"' /etc/profile
$ sudo sed -i '1i echo "/etc/bashrc:start"' /etc/bashrc 
$ sudo sed -i '$a echo "/etc/bashrc:end"' /etc/bashrc
$ sed -i '1i echo "~/.bash_profile:start"' ~/.bash_profile 
$ sed -i '$a echo "~/.bash_profile:end"' ~/.bash_profile 
$ sed -i '1i echo "~/.bashrc:start"' ~/.bashrc 
$ sed -i '$a echo "~/.bashrc:end"' ~/.bashrc 

上記の修正を行った状態でログインしてみると、以下のように表示されました。

$ bash --login
/etc/profile:start
/etc/bashrc:start
/etc/bashrc:end
/etc/profile:end
~/.bash_profile:start
~/.bashrc:start
/etc/bashrc:start
/etc/bashrc:end
~/.bashrc:end
~/.bash_profile:end

startend の入れ子状態の表示結果から

  • /etc/profile の中で /etc/bashrc を読み込んでいる。
  • ~/.bash_profile の中で ~/.bashrc を読み込んでいる。
  • ~/.bashrc の中で /etc/bashrc を読み込んでいる。

という仮説が立てられます。

順にファイルの中身を見ていきましょう。
まずは /etc/profile ですが、以下のように /etc/bashrc が読み込まれていました。

/etc/profile
if [ -n "${BASH_VERSION-}" ] ; then
        if [ -f /etc/bashrc ] ; then
                # Bash login shells run only /etc/profile
                # Bash non-login shells run only /etc/bashrc
                # Check for double sourcing is done in /etc/bashrc.
                . /etc/bashrc
       fi
fi

~/.bash_profile では以下の箇所で ~/.bashrc が読み込まれていました。

~/.bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

~/.bashrc は以下の箇所で /etc/bashrc が読み込まれていました。

~/.bashrc
# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi

調査の結果、読み込み順序としてはこのようになりました。

  1. /etc/profile
  2. /etc/bashrc
  3. ~/.bash_profile
  4. ~/.bashrc
  5. /etc/bashrc

前述の表では「ログイン時に読み込み」と「ユーザー個別で参照」の箇所に ~/.bash_login~/.profile が記載されていますが、CentOSの一般ユーザーのホームディレクトリ配下にこれらのファイルは存在しません。
man bash を見てみると、 INVOCATION つまり各設定ファイルの「呼び出し」に関する箇所に、以下のような記載を見つけました。
説明によると ~/.bash_profile~/.bash_login~/.profile の順に検索して最初に見つかったファイルを読み込んで実行するようです。

INVOCATION
       〜省略〜
       When bash is invoked as an interactive login shell, or as a  non-interactive
       shell with the --login option, it first reads and executes commands 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.

man bash に書かれていた内容を検証するために ~/.bash_profile を以下のようにリネームし、擬似的に ~/.bash_profile を未存在の状態にして、 ~/.bash_login を作成します。

$ mv ~/.bash_profile ~/.bash_profile.backup
$ echo 'echo "~/.bash_login:start"' > ~/.bash_login
$ echo 'echo "~/.bash_login:end"' >> ~/.bash_login

上記の対応を行った状態でログインしてみると、以下のように ~/.bash_login が読み込まれました。

$ bash --login
/etc/profile:start
/etc/bashrc:start
/etc/bashrc:end
/etc/profile:end
~/.bash_login:start
~/.bash_login:end

~/.bash_profile が存在しない状態での読み込み順序はこのような結果になりました。

  1. /etc/profile
  2. /etc/bashrc
  3. ~/.bash_login

次に ~/.bash_login を以下のようにリネームし、擬似的に ~/.bash_login を未存在の状態にして、 ~/.profile を作成します。

$ mv ~/.bash_login ~/.bash_login.backup
$ echo 'echo "~/.profile:start"' > ~/.profile
$ echo 'echo "~/.profile:end"' >> ~/.profile

上記の対応を行った状態でログインしてみると、以下のように ~/.profile が読み込まれました。

$ bash --login
/etc/profile:start
/etc/bashrc:start
/etc/bashrc:end
/etc/profile:end
~/.profile:start
~/.profile:end

~/.bash_profile~/.bash_login が存在しない状態での読み込み順序はこのような結果になりました。

  1. /etc/profile
  2. /etc/bashrc
  3. ~/.profile

これらの結果から ~/.bash_profile が存在しない場合は、一般ユーザーのbash起動時の設定である ~/.bashrc はログイン時に自動的に読み込まれないようなので、 ~/.bash_profile と同様の動きにするには ~/.bash_login~/.profile の中で以下のように ~/.bashrc を読み込む記述が必要であることがわかりました。

if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

ここまではログイン時の動作を検証しましたが、bash起動時の動作も確認しておきましょう。
bashを起動してみると、以下のような表示になりました。

$ bash
~/.bashrc:start
/etc/bashrc:start
/etc/bashrc:end
~/.bashrc:end

ログイン時に読み込まれるファイル群が登場しないので当然と言えば当然ですが、読み込み順序としてはこのような結果です。

  1. ~/.bashrc
  2. /etc/bashrc

Ubuntu21.10 (Impish Indri)の場合

Debian系OSの検証環境としてUbuntu21.10を利用します。

CentOS8の場合と同様に、既存の各設定ファイルの開始行と最終行を以下のように修正します。

$ sudo sed -i '1i echo "/etc/profile:start"' /etc/profile
$ sudo sed -i '$a echo "/etc/profile:end"' /etc/profile
$ sudo sed -i '1i echo "/etc/bash.bashrc:start"' /etc/bash.bashrc
$ sudo sed -i '$a echo "/etc/bash.bashrc:end"' /etc/bash.bashrc
$ sed -i '1i echo "~/.bashrc:start"' ~/.bashrc 
$ sed -i '$a echo "~/.bashrc:end"' ~/.bashrc
$ sed -i '1i echo "~/.profile:start"' ~/.profile 
$ sed -i '$a echo "~/.profilee:end"' ~/.profile 

上記の修正を行った状態でログインしてみると、以下のように表示されました。

$ bash --login
/etc/profile:start
/etc/bash.bashrc:start
/etc/bash.bashrc:end
/etc/profile:end
~/.profile:start
~/.bashrc:start
~/.bashrc:end
~/.profilee:end

CentOS8と比較すると /etc/bashrc~/.bash_profile が存在せず、その代わりに /etc/bash.bashrc~/.profile が存在します。そういったファイル名の違いはありますが、読み込み順序としてはだいたい同じ結果となりました。

  1. /etc/profile
  2. /etc/bash.bashrc
  3. ~/.profile
  4. ~/.bashrc

CentOS8の場合と同じように、 ~/.profile を以下のようにリネームし、擬似的に ~/.profile を未存在の状態にして、 ~/.bash_profile を作成してみます。

$ mv ~/.profile ~/.profile.backup
$ echo 'echo "~/.bash_profile:start"' > ~/.bash_profile
$ echo 'echo "~/.bash_profile:end"' >> ~/.bash_profile

上記の対応を行った状態でログインしてみると、以下のように ~/.bash_profile が読み込まれました。

$ bash --login
/etc/profile:start
/etc/bash.bashrc:start
/etc/bash.bashrc:end
/etc/profile:end
~/.bash_profile:start
~/.bash_profile:end

~/.profile が存在しない状態での読み込み順序はこのような結果になりました。

  1. /etc/profile
  2. /etc/bash.bashrc
  3. ~/.bash_profile

次に ~/.bash_profile を以下のようにリネームし、擬似的に ~/.bash_profile を未存在の状態にして、 ~/.bash_login を作成します。

$ mv ~/.bash_profile ~/.bash_profile.backup
$ echo 'echo "~/.bash_login:start"' > ~/.bash_login
$ echo 'echo "~/.bash_login:end"' >> ~/.bash_login

上記の対応を行った状態でログインしてみると、以下のように ~/.bash_login が読み込まれました。

$ bash --login
/etc/profile:start
/etc/bash.bashrc:start
/etc/bash.bashrc:end
/etc/profile:end
~/.bash_login:start
~/.bash_login:end

~/.profile~/.bash_profile が存在しない状態での読み込み順序はこのような結果になりました。

  1. /etc/profile
  2. /etc/bash.bashrc
  3. ~/.bash_login

Ubuntuの場合でも、bash起動時の動作を確認しておきましょう。
bashを起動してみると、以下のような表示になりました。

$ bash
/etc/bash.bashrc:start
/etc/bash.bashrc:end
~/.bashrc:start
~/.bashrc:end

ログイン時では /etc/bash.bashrc/etc/profile から読み込まれる形になっていましたが、bash起動時にはいずれかのファイルから読み込まれるという形式ではなく ~/.bashrc よりも先に単体で読み込まれるという結果になりました。

  1. /etc/bash.bashrc
  2. ~/.bashrc

まとめ

ここまでの検証結果を元に各ファイルの読み込み順序を表にまとめてみました。

CentOS8 Ubuntu21.10 (Impish Indri)
ログイン時の読み込み順序 1. /etc/profile
2. /etc/bashrc
3. ~/.bash_profile( or ~/.bash_login or ~/.profile)
4. ~/.bashrc
5. /etc/bashrc
1. /etc/profile
2. /etc/bash.bashrc
3. ~/.profile( or ~/.bash_profile or ~/.bash_login)
4. ~/.bashrc
bash起動時の読み込み順序 1. ~/.bashrc
2. /etc/bashrc
1. /etc/bash.bashrc
2. ~/.bashrc

CentOSとUbuntuでは標準で存在するファイル名自体に違いがあることは知っていましたが、CentOSの場合は、 /etc/bashrc~/.bashrc を経由して読み込まれるけど、 Ubuntuの場合は、 /etc/bash.bashrc~/.bashrc を経由せずに読み込まれるといった違いに気づくことができました。
普段何気なくログインしている環境も、こういったところに着目してみると新たな発見があって面白いですね。

参考URL

27
30
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
30