.bashrcと.bash_profileの違い


450

違いは何だ.bashrc.bash_profile、私はどちらを使うべきか?



あなたも含まれ、より完全な説明をしたい場合は.profile:この質問を見ていsuperuser.com/questions/789448/...
Flimm

この答えはまた、いくつかの側面カバーstackoverflow.com/questions/415403/...を
セルゲイVoronezhskiy

回答:


518

従来、Unixシステムにログインすると、システムは1つのプログラムを起動していました。そのプログラムはシェル、つまり他のプログラムを起動するように設計されたプログラムです。これはコマンドラインシェルです。別のプログラムを起動するには、その名前を入力します。デフォルトのシェルであるBourneシェル~/.profileは、ログインシェルとして起動されたときにコマンドを読み取ります。

BashはBourneのようなシェルです。~/.bash_profileログインシェルとして呼び出されたときからコマンドを読み取り、そのファイルが存在しない場合は、~/.profile代わりに読み取りを試みます¹ 。

GUI環境内で端末エミュレーターを起動するなどして、いつでもシェルを直接呼び出すことができます。シェルがログインシェルでない場合は、読み取りません~/.profile。bashをインタラクティブシェル(スクリプトを実行しないため)~/.bashrcとして起動すると、読み取りが行われます(ログインシェルとして呼び出された場合を除き、読み取り~/.bash_profileまたは読み取りのみ)~/.profile

したがって:

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

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

  • ~/.bash_profileの代わりに使用できますが~/.profile、bashのみが読み取り、他のシェルは読み取りません。(これは主に、初期化ファイルを複数のマシンで動作させたい場合で、ログインシェルがすべてのマシンでbashではない場合です。)これは~/.bashrc、シェルが対話型である場合に含める論理的な場所です。次のコンテンツをお勧めします~/.bash_profile

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

現代の大学では、に関連する複雑さが追加されてい~/.profileます。グラフィカル環境でログインする場合(つまり、パスワードを入力するプログラムがグラフィックモードで実行されている場合)、を読み取るログインシェルは自動的に取得されません~/.profile。グラフィカルログインプログラム、後で実行するウィンドウマネージャーまたはデスクトップ環境、およびこれらのプログラムをディストリビューションがどのように構成したか~/.profileによって、読み取りが行われる場合と行われない場合があります。そうでない場合は、通常、ログイン時に起動する環境変数とプログラムを定義できる別の場所がありますが、残念ながら標準の場所はありません。

環境変数の定義を入れる~/.bashrcか、常にターミナルでログインシェルを起動するかの推奨事項があります。どちらも悪いアイデアです。これらのアイデアのいずれかで最も一般的な問題は、環境変数が、アイコン、メニュー、またはキーボードショートカットで直接起動されたプログラムではなく、ターミナルから起動されたプログラムでのみ設定されることです。

¹ 完全を期すために、リクエストにより:.bash_profile存在しない場合、bashはに.bash_loginフォールバックする前に試行し.profileます。それが存在することを忘れないでください。


11
良い投稿の場合は+1。また、「ログイングラフィカルvsログインシェル」に関するセクションを追加していただきありがとうございます...〜/ .profileが常にグラフィカル/シェルで実行されると思っていた問題がありました...しかし、ユーザーがログインしたときは実行されませんグラフィカルログイン経由。その謎を解いてくれてありがとう。
トレバーボイドスミス

4
@Gilles:すべての端末でログインシェルを実行するのが悪い考えである理由について、例を挙げて詳細に説明してもらえますか?これはデスクトップLinuxの問題ですか?(OS Xターミナルでは毎回ログインシェルを実行し、副作用に気付いたことはありません(通常iTermを使用しますが)。しかし、私は気にしない多くの環境変数を考えることができません。ターミナル(たぶんHTTP_PROXY?))。
アイコノクラスト

2
@Brandonすべての端末でログインシェルを実行すると、環境によって提供される環境変数が上書きされます。日常の状況では、それで済ますことができますが、遅かれ早かれ、ターミナルで異なる変数を設定したいとき(例えば、プログラムの異なるバージョンを試してみるため)に噛みつきます:ログインシェルはローカル設定を上書きします。
ジル

4
ステートメント~/.bash_profileはの代わりに使用できますが、シェルが対話型である場合~/.profileも含める必要があります~/.bashrcこれらは直交する問題であるため、誤解を招く可能性があります。そこからの設定をログインシェルで有効にする場合は、使用する~/.bash_profileか、使用~/.profileするものに含める必要があるかは関係ありません~/.bashrc
ピョートルドブロゴスト

3
@Gilles確かに、しかし答えの中で文が定式化される方法は、含める必要性が真実ではなく~/.bashrc選択~/.bash_profileに関係していることを示唆して~/.profileいます。~/.bashrcログイン時にソースされるスクリプトの種類(ここでは、~/.bash_profileまたはのいずれか~/.profile)に誰かが含まれているのは~/.bashrc、ログインシェルに設定を適用する方法が、非ログインシェルに適用されるのと同じためです。
ピョートルドブロゴスト

53

この短い記事から

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

ログインまたは非ログインシェルとは何ですか?

起動時にマシンに物理的に座っているか、sshを介してリモートでコンソールからログイン(例:ユーザー名とパスワードを入力)すると、最初のコマンドプロンプトの前に設定するために.bash_profileが実行されます。

ただし、すでにマシンにログインしてGnomeまたはKDE内で新しいターミナルウィンドウ(xterm)を開いている場合は、ウィンドウコマンドプロンプトの前に.bashrcが実行されます。.bashrcは、ターミナルで/ bin / bashと入力して新しいbashインスタンスを開始するときにも実行されます。


12
わずかな更新:「実行済み」は、おそらくわずかに誤解を招く用語であり、どちらもソースになっています。実行された音は、fork / exec yadda yaddaというスクリプトとして実行されているように聞こえます。現在のシェルのコンテキストで実行されます。さらに重要なことは、.bashrcがはるかに頻繁に実行されることです。これは、bashスクリプトの実行ごとに実行されます。また、.bash_profileがない場合にも実行されます。また、あなたはのxtermの設定方法によっては、あなたが.bash_profileのソースするシェルを作成することができます
リッチHomolka

36

昔、擬似ttyが擬似ではなく、実際にタイプされていて、UNIXがモデムによってアクセスされたため、各文字が画面に印刷されるのを見ることができたため、効率が最も重要でした。効率をいくらか高めるために、メインログインウィンドウと、実際に動作するために使用した他のウィンドウという概念がありました。メインウィンドウで、新しいメールへの通知が必要です。バックグラウンドで他のプログラムを実行することもできます。

これをサポートするために、シェル.profileは「ログインシェル」専用のファイルを入手しました。これにより、セッションのセットアップ後に特別なことが行われます。Bashはこれをいくぶん拡張して、.profileの前にまず.bash_profileを調べるようにしました。これにより、bashのみをそこに置くことができます(したがって、.profileを見たBourneシェルなどを台無しにしません)。ログインしていない他のシェルは、rcファイル、.bashrc(または.kshrcなど)をソースするだけです。

これは今や少し時代錯誤です。guiウィンドウマネージャーにログインするほどメインシェルにはログインしません。他のウィンドウと異なるメインウィンドウはありません。

私の提案-この違いを心配しないでください。これは古いスタイルのUNIXを使用しているためです。ファイルの違いを排除します。.bash_profileのコンテンツ全体は次のようになります。

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

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

.bashrcは、対話型および非対話型のすべてのシェルをソースとしていることに注意してください。このコードを.bashrcの上部に配置することで、非対話型シェルのソースを短絡できます。

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


6
これは悪い考えです。私の答えをご覧ください。特に、環境変数は端末から起動されたプログラムでのみ設定され、アイコン、メニュー、またはキーボードショートカットで直接起動されたプログラムでは設定されません。
ジル

4
@Gillesあなたがこれを主張する理由がわかりません。で.$HOME/.bashrcリッチ上記示したように、設定では.bashrc、同様のログインシェル、ひいてはデスクトップ環境で利用できるようになります。たとえば、私のFedoraシステムでgnome-sessionは、として起動される-$SHELL -c gnome-sessionので.profile、読みます。
ミケル

2
@PiotrDobrogostああ、はい、リッチの答えには別の問題があります。含む.bashrc.profileあるため、通常は、動作しない.profileで実行することができる/bin/sh(デフォルトでは、グラフィカルログインのためのUbuntuの上など)bashのではなく、そのシェルが(グラフィカル・ログイン用など)、インタラクティブではないかもしれません。
ジル

3
@Gilles re:「.profileに.bashrcを含める」ことは、推奨されたものとはまったく異なります(実際、まったく逆です)。回答が編集された(そうは表示されない)か、あなたのコメントが発言と一致しません。
マイケル

2
一般的には+1ですが、「非対話型シェルの場合は短絡...」(「[[ $- != *i* ]] && return。bashrcの上部付近:」)への推奨事項に追加します。私は.bashrc、非対話型シェルでも、特にを発行するときにenv varsを設定しssh hostname {command}て、リモートコマンドが正しく実行されるように(シェルが非対話型であっても)実行されるようにします。ただし、後で他の設定を.bashrc無視する必要があります。私は通常TERM = dumbおよび/またはunsetを確認してから、早期に救済します。
マイケル

18

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      |           |      |
+----------------+-----------+-----------+------+

複数の質問に同じ回答を投稿するよりも、質問者の特定のニーズに合わせて回答を調整できる場合が望ましいです。両方の質問の答えがまったく同じ場合は、単一の回答を投稿し、元の質問の複製として他の質問を閉じるように投票する必要があります。
木梅

1
@Mokubaiもう1つの質問は、すでにこの質問の複製としてマークされています。
フリム

@ElipticalView:何もしないように設定すると、次の行を参照します:[ -z "$PS1" ] && return?私の答えの表は、スクリプトの内容に関係なくBashによって実行されるスクリプトのリストを示しています。スクリプト自体に行がある[ -z "$PS1" ] && return場合はもちろん有効ですが、それを変更する必要があるとは思わないテーブル。
Flimm

5

/ 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は、対話的に実行されない場合は何もしないように設定されていることにも注意してください。したがって、これらの2つのファイルはインタラクティブスクリプト専用です。


4

bash自体の構成ロジックはそれほど複雑ではなく、このページの他の回答、serverfault、および多くのブログで説明されています。ただし、問題はLinuxディストリビューションがbash作成するものであり、デフォルトでbashを構成する複雑でさまざまな方法を意味します。http://mywiki.wooledge.org/DotFilesには、これらの癖のいくつかについて簡単に言及されています。Fedora 29の1つのサンプルトレースは、どのファイルが他のどのファイルをソースし、どの順序で非常に簡単なシナリオを示しているかを示しています。リモートでsshで接続してから別のサブシェルを起動します。

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テスト:

  • ログインシェルをソースとしているため、
  • 対話型のシェルをソースとしているため、
  • すでに調達されている

...そして、それらに応じて完全に異なることを行います。

上記のグラフを思い出すことができると思うなら、それは十分ではないためあまりにも悪いです:このグラフは単に1つのシナリオを説明しているだけで、非対話型スクリプトの実行時またはグラフィカルセッションの開始時にわずかに異なることが起こります。省略しました~/.profilebash_completionスクリプトを省略しました。後方互換性の理由から、bashを呼び出すとその動作/bin/sh/bin/bash変わります。zshやその他のシェルはどうですか?そしてもちろん、Linuxディストリビューションによって動作が異なります。たとえば、DebianとUbuntuには非標準バージョンのbas h が付属しており、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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.