bash – .bashrc と .bash_profile の違い

.bash-profile bash bashrc

.bashrc.bash_profileの違いは何で、どちらを使えばいいの?

  485  cfischer  2010-09-02


ベストアンサー

伝統的に、Unix システムにログインすると、システムはあなたのために一つのプログラムを起動します。そのプログラムはシェル、つまり他のプログラムを起動するように設計されたプログラムです。これはコマンドラインシェルで、名前を入力することで別のプログラムを起動します。デフォルトのシェルであるボーン・シェルは、ログイン・シェルとして起動されるとき、~/.profileからコマンドを読みます

Bash はボーンのようなシェルである。ログインシェルとして起動されたときに ~/.bash_profile からコマンドを読み込み、そのファイルが存在しない場合¹、代わりに ~/.profile を読み込もうとします

GUI環境内でターミナルエミュレータを起動するなど、いつでも直接シェルを呼び出すことができます。シェルがログインシェルでない場合は、~/.profileを読みません。対話型シェルとして bash を起動した場合 (すなわち、スクリプトを実行しない場合)、~/.bashrc を読み込みます (ログインシェルとして起動した場合を除く)

Therefore:

  • ~/.profile は、ログイン時に起動したいプログラム(グラフィカルなプログラムは別のファイルに移動します)や環境変数の定義など、セッション全体に適用されるものを置く場所です

  • ~/.bashrc は、エイリアスや関数の定義、シェルオプション、プロンプトの設定など、bash 自体にのみ適用されるものを置く場所です。(ここにキーバインディングを置くこともできますが、bash では通常 ~/.inputrc に置かれます)

  • ~/.profile の代わりに ~/.bash_profile を使うことができますが、これは bash でのみ読み込まれ、他のシェルでは読み込まれません。(これは、初期化ファイルを複数のマシンで動作させたい場合や、ログインシェルがすべてのマシンで bash を使用していない場合には、ほとんどの場合心配になります)。シェルが対話的な場合は、~/.bashrcを含めるのが論理的な場所です。私は以下の内容を ~/.bash_profile に含めることをお勧めします

    if [ -r ~/.profile ]; then . ~/.profile; fi
    case "$-" in *i*) if [ -r ~/.bashrc ]; then . ~/.bashrc; fi;; esac
    

最近の unices では、~/.profile に関連して、さらに複雑な問題があります。グラフィカルな環境でログインした場合(つまり、パスワードを入力するプログラムがグラフィックモードで動作している場合)、自動的に~/.profileを読むログインシェルが表示されるわけではありません。グラフィカルなログインプログラムや、その後に実行するウィンドウマネージャやデスクトップ環境、ディストリビューションの設定によっては、~/.profileが読み込まれるかどうかは異なります。読まれない場合は、通常は別の場所に環境変数やログイン時に起動するプログラムを定義できる場所がありますが、残念ながら標準的な場所はありません

環境変数の定義を~/.bashrcに入れるか、ログインシェルを常にターミナルで起動するかのどちらかを推奨しているのをあちこちで見かけることに注意してください。どちらも悪い考えです。どちらの方法でも最も一般的な問題は、環境変数が設定されるのはターミナル経由で起動されたプログラムの中だけであり、アイコンやメニュー、キーボードショートカットで直接起動されたプログラムの中では設定されないということです

¹ 補完のために、要望により: .bash_profile が存在しない場合、bash は .profile に戻る前に .bash_login も試します。存在を忘れても構いません。

563  Gilles ‘SO- stop being evil’  2010-09-02


この短い記事から

bash のマニュアルページによると、ログインシェルでは .bash_profile が実行され、非ログインシェルでは .bashrc が実行されます

ログインシェル、非ログインシェルとは?

コンソールからログインする場合 (例: ユーザ名とパスワードを入力する) には、起動時に物理的にマシンに座っているか、リモートで ssh を使っているかのどちらかになります

しかし、すでにマシンにログインしていて、Gnome や KDE で新しいターミナルウィンドウ (xterm) を開いている場合は、ウィンドウのコマンドプロンプトの前に .bashrc が実行されます

58  Jarvin  2010-09-02


昔、疑似 tty が疑似的なものではなく、実際には、まあ、タイプされたものであり、UNIX にはモデムでアクセスしていたので、一文字一文字が画面に印刷されているのを見ることができるほど遅かった時代には、効率性が最優先されていました。効率化のために、メインのログインウィンドウと、実際に作業をするための他のウィンドウという概念がありました。メインウィンドウでは、新しいメールの通知や、バックグラウンドで他のプログラムを実行することができるようにしたいと思います

これをサポートするために、シェルは特に ‘login shells’ にあるファイル .profile をソースにしました。これは特別な、セッションに一度だけのセットアップを行います。Bash はこれを拡張して、.profile の前に .bash_profile を最初に見るようにしました。この方法では、bash のみを入れることができます (Bourne シェルなども .profile を見るようになります)。他のシェルは、ログインしていない場合は、rc ファイルである .bashrc (または .kshrc など) をソースにするだけです

これは今となっては時代錯誤です。gui ウィンドウマネージャにログインするのと同じように、メインシェルにログインすることはありません。他のウィンドウと何ら変わらないメインウィンドウはありません

私の提案 – この違いを気にする必要はありません。ファイル内の違いを削除してください。.bash_profile の内容全体がそうであるべきです

[ -f $HOME/.bashrc ] && . $HOME/.bashrc

そして、実際に設定したいものはすべて.bashrcに入れます

.bashrc は対話型、非対話型を問わず、すべてのシェルにソースが供給されていることを覚えておいてください。.bashrc の先頭付近に以下のコードを記述することで、非インタラクティブなシェルのソースを短絡させることができます

[[ $- != *i* ]] && return

39  Rich Homolka  2010-09-02


このShreevatsaRの優れたブログ記事を見てみてください。ここでは抜粋していますが、ブログ記事に行くと、”ログインシェル “のような用語の説明、フローチャート、およびZshのための同様のテーブルが含まれています

Bashの場合、以下のように動作します。適当なカラムを読み下す。Aを実行し、次にBを実行し、次にCを実行する。B1,B2,B3は、見つかったファイルの最初のものだけを実行することを意味します

+----------------+-----------+-----------+------+
|                |Interactive|Interactive|Script|
|                |login      |non-login  |      |
+----------------+-----------+-----------+------+
|/etc/profile    |   A       |           |      |
+----------------+-----------+-----------+------+
|/etc/bash.bashrc|           |    A      |      |
+----------------+-----------+-----------+------+
|~/.bashrc       |           |    B      |      |
+----------------+-----------+-----------+------+
|~/.bash_profile |   B1      |           |      |
+----------------+-----------+-----------+------+
|~/.bash_login   |   B2      |           |      |
+----------------+-----------+-----------+------+
|~/.profile      |   B3      |           |      |
+----------------+-----------+-----------+------+
|BASH_ENV        |           |           |  A   |
+----------------+-----------+-----------+------+
|                |           |           |      |
+----------------+-----------+-----------+------+
|                |           |           |      |
+----------------+-----------+-----------+------+
|~/.bash_logout  |    C      |           |      |
+----------------+-----------+-----------+------+

20  Flimm  2016-07-13


ETC/PROFILEの先頭のためのより良いコメント

上記の Flimm さんの素晴らしい回答をもとに、私は Debian の /etc/profile の先頭にこの新しいコメントを挿入しました (あなたのディストロに合わせて調整する必要があるかもしれません)

# For BASH: Read down the appropriate column. Executes A, then B, then C, etc.
# The B1, B2, B3 means it executes only the first of those files found.  (A)
# or (B2) means it is normally sourced by (read by and included in) the
# primary file, in this case A or B2.
#
# +---------------------------------+-------+-----+------------+
# |                                 | Interactive | non-Inter. |
# +---------------------------------+-------+-----+------------+
# |                                 | login |    non-login     |
# +---------------------------------+-------+-----+------------+
# |                                 |       |     |            |
# |   ALL USERS:                    |       |     |            |
# +---------------------------------+-------+-----+------------+
# |BASH_ENV                         |       |     |     A      | not interactive or login
# |                                 |       |     |            |
# +---------------------------------+-------+-----+------------+
# |/etc/profile                     |   A   |     |            | set PATH & PS1, & call following:
# +---------------------------------+-------+-----+------------+
# |/etc/bash.bashrc                 |  (A)  |  A  |            | Better PS1 + command-not-found
# +---------------------------------+-------+-----+------------+
# |/etc/profile.d/bash_completion.sh|  (A)  |     |            |
# +---------------------------------+-------+-----+------------+
# |/etc/profile.d/vte-2.91.sh       |  (A)  |     |            | Virt. Terminal Emulator
# |/etc/profile.d/vte.sh            |  (A)  |     |            |
# +---------------------------------+-------+-----+------------+
# |                                 |       |     |            |
# |   A SPECIFIC USER:              |       |     |            |
# +---------------------------------+-------+-----+------------+
# |~/.bash_profile    (bash only)   |   B1  |     |            | (doesn't currently exist)
# +---------------------------------+-------+-----+------------+
# |~/.bash_login      (bash only)   |   B2  |     |            | (didn't exist) **
# +---------------------------------+-------+-----+------------+
# |~/.profile         (all shells)  |   B3  |     |            | (doesn't currently exist)
# +---------------------------------+-------+-----+------------+
# |~/.bashrc          (bash only)   |  (B2) |  B  |            | colorizes bash: su=red, other_users=green
# +---------------------------------+-------+-----+------------+
# |                                 |       |     |            |
# +---------------------------------+-------+-----+------------+
# |~/.bash_logout                   |    C  |     |            |
# +---------------------------------+-------+-----+------------+
#
# ** (sources !/.bashrc to colorize login, for when booting into non-gui)

そして、それを参照するために、他の設定ファイルのそれぞれの頭にあるこのメモ

# TIP: SEE TABLE in /etc/profile of BASH SETUP FILES AND THEIR LOAD SEQUENCE

注目すべき点は、Debian の /etc/profile はデフォルトで /etc/bash.bashrc を (含む) ソースにしていることだと思います (これは /etc/bash.bashrc が存在する場合の話です)。つまり、ログインスクリプトは両方の /etc ファイルを読み、非ログインは bash.bashrc だけを読みます

また、/etc/bash.bashrc は対話的に実行されていないときには何もしないように設定されていることにも注意してください。つまり、この二つのファイルは対話型スクリプトのためだけのものです

7  Elliptical view  2016-10-18


bashの設定ロジック自体は非常に複雑なものではなく、このページの他の回答、serverfaultや多くのブログで説明されています。しかし、問題は Linux ディストリビューションが bash をどのようなものにしているかということです。http://mywiki.wooledge.org/DotFiles は、これらの奇妙な点について簡単に触れています。これは、Fedora 29 でのサンプルトレースで、どのファイルがどの他のファイルのソースになっているか、また、非常にシンプルなシナリオでは、どのファイルがどの順番でソースになっているかを示しています

ssh fedora29
└─ -bash # login shell
├── /etc/profile
|    ├─ /etc/profile.d/*.sh
|    ├─ /etc/profile.d/sh.local
|    └─ /etc/bashrc
├── ~/.bash_profile
|    └─ ~/.bashrc
|          └─ /etc/bashrc
|
|
└─ $ bash  # non-login shell
└─ ~/.bashrc
└─ /etc/bashrc
└─ /etc/profile.d/*.sh

Fedora の最も複雑なロジックは /etc/bashrc にあります。上で見たように /etc/bashrc は bash 自体が知らないファイルです。Fedora の /etc/bashrc は、そのようなファイルが存在するかどうかをテストします

  • ログインシェルでソースを取得しています
  • それは対話型シェルによって供給されています
  • それはすでに調達済みです

…そして、それに応じて全く違うことをする

上のグラフを覚えていると思っているなら、それは残念です。~/.profileは省略しました。bash_completion スクリプトは省略しています。後方互換性の理由から、/bin/bash の代わりに /bin/sh として bash を起動すると挙動が変わります。zsh や他のシェルはどうでしょうか?例えば、Debian と Ubuntu には非標準バージョンの bash が付属していますが、Debian 固有のカスタマイズが施されています。特に変わったファイルを探します。/etc/bash.bashrc.単一の Linux ディストリビューションに固執していても、おそらく時間の経過とともに進化していくでしょう。待ってください: 私たちはまだ macOS, FreeBSD, にも触れていません。最後に、管理者が使用しなければならないシステムをさらに創造的な方法で設定していることに行き詰っているユーザのために考えてみましょう

このトピックについての議論が尽きることのない流れが示すように、それは原因を見失ったものです。新しい値を追加したいだけであれば、いくつかの「試行錯誤」で十分な傾向があります。本当の楽しみは、ある(ユーザ)ファイルの中で、すでに別の(/etc)ファイルで定義されているものを変更したいときに始まります。その時には、決して移植性のないソリューションを設計するのに時間を費やす覚悟をしてください

最後のお楽しみとして、2019年6月現在のClear Linux上の同じシンプルなシナリオの「ソースグラフ」をご紹介します

ssh clearlinux
└─ -bash # login shell
├── /usr/share/defaults/etc/profile
|    ├─ /usr/share/defaults/etc/profile.d/*
|    ├─ /etc/profile.d/*
|    └─ /etc/profile
├── ~/.bash_profile
|
|
└─  $ bash   # non-login shell
├─ /usr/share/defaults/etc/bash.bashrc
|      ├─ /usr/share/defaults/etc/profile
|      |    ├─ /usr/share/defaults/etc/profile.d/*
|      |    ├─ /etc/profile.d/*
|      |    └─ /etc/profile
|      └─ /etc/profile
└─ ~/.bashrc

5  MarcH  2019-06-24


タイトルとURLをコピーしました