前提
シェルには、その起動方法による分類が存在する
1. ログインシェル
- シェル起動時にログインを経ているかどうか、による分類
- ログインを経ていれば「ログインシェル」
- 例:ターミナルやSSHで特定ホストにログインして入った場合など
- ログインを経ずに起動しいている場合は「非ログインシェル」
- 例:シェルからbashコマンドなどで再度シェルを呼び出す場合など
- ログインを経ていれば「ログインシェル」
- 多くの場合、ターミナルで最初にホストに入るときのみ「ログインシェル」(=「一番外側のシェル」)、それ以降は「非ログインシェル」
2. インタラクティブシェル
- 対話型として起動しているかどうか、による分類
- 対話型なら「インタラクティブシェル」
- 例:ターミナル
- それ以外は「非インタラクティブシェル」
- 例:bashコマンド実行やshファイルのスクリプト実行
- 対話型なら「インタラクティブシェル」
各パターンの挙動
-
インタラクティブシェルの場合、bash_profileまたはbashrcのどちらかが実行される
-
ログインシェルの場合はbash_profileが実行される
- 最初にターミナルをつけた時などにbash_profileが呼ばれる
- 厳密には、/etc/profileが実行されたあと、.bash_profile > .bash_login > .profile のうち最初に見つかったものを実行
- 多くの場合、.bash_profile内部に.bashrc実行が記述されているので、.bashrcも実行される
-
非ログインシェルの場合はbashrcが実行される
- ターミナル内でさらにbashを対話型として呼び出した状態などにはbash_profileが呼ばれる
-
ログインシェルの場合はbash_profileが実行される
-
非インタラクティブの場合はなにも実行されない
- 実行元環境から環境変数のみ引き継がれる
作成するシェルタイプと有効になる環境変数の対応
インタラクティブ | 非インタラクティブ | |
---|---|---|
ログイン | bash_profileの内容 bashrcの内容(※) 起動元の環境変数 |
起動元の環境変数 |
非ログイン | bashrcの内容 起動元の環境変数 |
起動元の環境変数 |
※bash_profileにbashrcを実行するスクリプトが入っている場合のみ
「.bash_profile」と「.bashrc」を使い分けるなら?
-
「.bash_profile」にはそのログインセッションで1回だけ実行する処理を書く
- 環境変数などを定義するのがよい
-
「.bashrc」にはシェル起動都度実行する処理を書く
- シェル変数を定義するのが良い
- エイリアスや関数は親から引き継がれないのでここで定義
なぜか環境変数が適用されない!なんで?
-
バッチ処理など非インタラクティブな処理においてはどこに何書いても意味なし
- 起動時点で起動元の環境に設定されている環境変数か、コマンドの引数からしか連携不可
- ログインを伴わないシェル利用においては、bash_profileは意味なし
- sudo実行時は起動元の環境変数も引き継がれないので注意
(補足)「環境変数」と「シェル変数」
環境変数
- export XXX = YYY で定義されるやつ
- そのシェルから生まれた子プロセスなどに引き継がれる
シェル変数
- XXX = YYY で定義されるやつ
- 子プロセスには引き継がれない、シェルセッション内でのみ有効
参考にした記事
上記は、以下のQiita記事を参考にさせていただき、自分なりに咀嚼した結果をまとめたものです
- bashの .bash_profile と .bashrc の挙動の整理と使い分け方
https://qiita.com/ono_matope/items/feebac51afb346d9db0e