web-dev-qa-db-ja.com

.bashrcと.bash_profileの違い

.bashrc.bash_profileの違いは何ですか?どちらを使用すればよいですか?

438
cfischer

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

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

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

したがって:

  • ~/.profileは、あなたがセッション全体に適用されるもの、例えばあなたがログインしたときに始めたいプログラム(しかしグラフィカルプログラムではなく、それらは異なるファイルに入る)を置く場所です。

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

  • ~/.bash_profile~/.profileの代わりに使用できますが、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を試します。それが存在することを忘れてお気軽に。

506
Gilles

この記事から 短い記事

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

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

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

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

52
Jarvin

昔は、疑似ttyは疑似ではなく、実際にはうまく入力されていて、UNIXがモデムによってアクセスされていたため、各文字が画面に表示されるのが遅いので、効率が最も重要でした。効率をいくらか向上させるために、メインのログインウィンドウと、実際に動作するために使用していたその他のウィンドウという概念がありました。あなたのメインウィンドウで、あなたはどんなバックグラウンドででも他のプログラムを走らせるかもしれないどんな新しいメールへの通知でも欲しいです。

これをサポートするために、シェルはファイル.profileを特に 'login shells'に供給しました。一度セッションを設定すると、これは特別なことになります。 bashはこれを多少拡張して、.profileの前に最初に.bash_profileを見るようにしました。これにより、bashだけをそこに入れることができました(したがって、.profileを見ているBourne Shellなどを台無しにすることはありません)。ログインしていない他のシェルは、単にrcファイル.bashrc(または.kshrcなど)をソースにします。

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

私の提案 - この違いについて心配しないでください、それはunixを使うという古いスタイルに基づいています。ファイルの違いを取り除きます。 .bash_profileの内容全体は、次のようになります。

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

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

.bashrcはすべてのシェル(対話式および非対話式)に対応しています。このコードを.bashrcの先頭近くに配置することで、非対話型シェルのソースを切り取ることができます。

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

35
Rich Homolka

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

HEAD OF/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
Elliptical view

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つのシナリオを説明しているだけで、非対話型スクリプトの実行時またはグラフィカルセッションの開始時にわずかに異なることが起こります。 ~/.profileを省略しました。 bash_completionスクリプトを省略しました。後方互換性の理由から、bashを/bin/shではなく/bin/bashとして呼び出すと、その動作が変わります。 zshやその他のシェルはどうですか?そしてもちろん、Linuxディストリビューションによって動作が異なります。たとえば、DebianとUbuntuには非標準バージョンのbashが付属し、Debian固有のカスタマイズがあります(s)。特に、異常なファイル/etc/bash.bashrcを探します。たとえ単一のLinuxディストリビューションに固執していても、おそらく時間とともに進化します。待ってください:macOS、FreeBSDにも触れていません...最後に、使用するシステムを管理者が設定するさらに創造的な方法に固執しているユーザーについて考えてみましょう。

このトピックに関する議論の終わりのないストリームが示すように、それは失われた原因です。新しい値を追加するだけであれば、「試行錯誤」で十分です。本当の楽しみは、modifyを別の(/ 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
3
MarcH