勉強のメモです.
tl;dr
- bashプロセスをまたいで有効な処理は
~/.bash_profile
に書け.そうでない処理は~/.bashrc
に書け. - いかなる場合も,bashはファイルの実行に1つでも失敗するとエラーを報告する.
- ファイルがない場合はこれに含まない.
- ログインすると,
/etc/profile
があれば読み込まれ,~/.bash_profile
,(~/.bashrc
に指定されていれば~/.bashrc
),~/.bash_login
,~/.profile
のうち,この順で最初に存在したものが読み込まれる.- 終了時には
~/.bash_logout
があれば実行される.
- 終了時には
- シェルからシェルを対話的に起動すると,
~/.bashrc
が読み込まれる.rc
はrun commands
の頭字語である.
- シェルスクリプトなどで非対話的に起動すると何も読み込まれないが,
$BASH_ENV
でファイルを指定できる. - sshでログインすると,
~/.bashrc
が読み込まれる. sh
として起動すると,sh
の動作になる.
インタラクティブ・シェル,インタラクティブなログイン・シェル,非インタラクティブ・シェル
インタラクティブ(対話的)・シェルとは,-X
といった形式の引数が無く*1,-c
オプションが指定されていない状態で,標準入力と標準エラー出力が端末に接続されて起動したbash,もしくは-i
オプションをともなって起動したbashのことである.ただし,-s
オプションを伴った場合はインタラクティブ・シェルである.
一文では分かりにくいので,以下のように考える.
-i
オプションがあるなら,インタラクティブ・シェルである.-s
オプション(標準入力を実行するオプション)があるなら,インタラクティブ・シェルである.- オプションでない引数(典型的にはファイル名)があるなら,インタラクティブ・シェルではない.
-c
オプション(指定したコマンドを実行するオプション)があるなら,インタラクティブ・シェルではない.- 入力とエラー出力が両方とも端末に接続されていなければ,インタラクティブ・シェルではない.
- 以上にあてはまらなければ,インタラクティブ・シェルである.
ログインシェルは,login
によって起動されたか,--login
オプションをともなって起動したインタラクティブシェルである.インタラクティブシェルはログインシェルとは限らない.非インタラクティブシェルとはバッチファイルで起動したり,コマンドを渡されて起動するものである.
インタラクティブなログインシェルとして起動したとき(--login
オプションをともなって起動したとき)
/etc/profile
があれば実行する.~/.bash_profile
,~/.bash_login
,~/.profile
をその順通りに,最初に見付かったものを実行する.
終了時またはexit
が実行されたときには~/.bash_logout
があれば実行する.
また典型的には~/.bash_profile
の末尾には「~/.bashrc
があれば読み込む」という動作が記載されているため,~/.bash_profile
->~/.bashrc
の順で読み込まれることとなる.
インタラクティブだが非ログインシェルとして起動したとき
~/.bashrc
があれば実行する.ただし,--norc
オプションを指定したときは読み込まない.また,--rcfile FILE
によって読み込むファイルを指定したときは,~/.bashrc
に代わってそのファイルがあれば実行される(そのファイルが存在しない場合は読み込まないという動作が踏襲され,エラーにはならない).
非インタラクティブシェルとして起動したとき
典型的には,シェルスクリプトとして起動している場合である.
bashはまず$BASH_ENV
を環境変数から読み取り,その中の値を一般的な文字列について行うように展開し,得られた値が指し示すファイルを実行しようとする.例えば$BASH_ENV
が$HOME/.hoge
であったとき,$HOME
は展開され,ホームディレクトリ中の.hoge
が実行され,後に続く(典型的にはシェルスクリプトの)処理が継続される.ただし,ファイルの検索に$PATH
は利用されない.
また,--login
を指定することで前掲の動作を行う.
sh
として起動したとき
歴史的なsh
の動作を模倣しようとする.後述するようなファイルの読み込みが終了すると,bashはPOSIXモードへと遷移する.
インタラクティブ・ログインシェルまたは--login
をともなって起動したとき
/etc/profile
,~/.profile
をその順で実行しようとする.ただし,--noprofile
をともなって起動したときは実行しない.
インタラクティブ・シェルとして起動したとき
bashはまず$ENV
を環境変数から読み込み,その中の値を(bash-likeに?)展開し,得られた値が指し示すファイルを実行しようとする.
sh
の動作を模倣しているので,--rcfile
オプションは機能しない.
非インタラクティブ・シェルとして起動したとき
何も読み込まない.
POSIXモードで起動したとき
--posix
オプションを指定するとbashはPOSIXモードで起動する.POSIXモードでは,bashはまず$ENV
を環境変数から読み込み,その中の値を(bash-likeに?)展開し,得られた値が指し示すファイルを実行しようとする.他のファイルは実行されない.
リモートシェルデーモンとして起動したとき
典型的にはrshやsshの接続で起動した場合である.bashはネットワーク接続越しの起動であることを検知すると,『インタラクティブだが非ログインシェルとして起動したとき』と同様に起動する.
ただし,rshdやsshdは--norc
や--rcfile
をともなってbashを起動することは基本的にしないため,~/.bashrc
読み込みの阻害や他ファイル読み込みの強制は結果的にできない.
実際のUID/GIDと異なるUID/GIDで起動したとき
典型的にはsudo
で起動したときである.
ファイルを読み込まない.環境設定は継承されない.環境変数にSHELLOPTS
,BASHOPTS
,CDPATH
,GLOBIGNORE
が出現してもこれらを無視する.
ただし-p
オプションをともなって起動したときは通常と同様に起動するが,実効的なUIDは変化しない.
感想
そんなに難しくなかったので,zshの場合にチャレンジしたい(難しそう).
参考文献
*1:原文では"without non-option arguments"