Update & 注意 (2017.5.9)
- 最初の投稿からかなりの時間が経過しましたが、いくつか修正点が見つかりましたので、それぞれ訂正の注記を入れておきました。また、ポイントのまとめを表に改めました。
- 以下の記述は次の環境で動作確認しています。
- OS X 10.11.6, Homebrew よりインストールされた Bash 4.4.12
- Ubuntu 14.04.5 LTS, Bash 4.3.11(1)-RELEASE
- macOS 10.12.4, OSデフォルトの GNU bash, version 3.2.57(1)-release
-
ログインシェルとして Bash が使用されていることを確認するには、(2018.5.16追記: Ubuntu等、左記の方法では確かめられないOSもあります。)echo $SHELL
として環境変数$SHELL
に bash の実行ファイルが指定されていることを確認します。- Bash が起動されているかどうかの確認方法の一つとしては、
ls -l /proc/$$/exe
があります。このシンボリックリンクの参照先が/bin/bash
等であるかを見ます。- RedHat 系ではBash, shいずれの時も
/usr/bin/bash
を表示してしまうので、ディストリビューション非依存なやり方については調査中です。
- RedHat 系ではBash, shいずれの時も
- Bash が起動されているかどうかの確認方法の一つとしては、
何のこっちゃ
発端は
[hogeuser@fugahost ~]$ echo $PS1
[\\u@\h \\W]\\$
というアレ(PS1
という、bashのプロンプト設定のための変数)が「うまく設定されない??なんで???」、と困ったことでした。
どうして??そもそも、~/.bashrc
と~/.bash_profile
の究極の違いって何でしょう。いろいろ検索した結果、ログインシェルとインタラクティブシェルの違いを説明しているページに行き着きました。
ポイント
[修正 2018.5.16]
シェルの種類 | 起動方法 | 起動時実行スクリプト |
---|---|---|
ログインシェル |
ssh user@host su - [user] bash --login macOS Terminal.app 新規ウインドウ/タブ tmux 新規ウインドウ |
~/.bash_profile ※1 |
インタラクティブシェル |
su [user] bash
|
~/.bashrc |
非インタラクティブシェル |
su user -c /path/to/command bash -c /path/to/command ssh user@host /path/to/command |
なし |
※1 以下でも述べていますが、ほとんどの場合~/.bash_profile
内に、~/.bashrc
を実行する記述があります。なお、ログインシェルでは .bashrc
は自動実行されません。
※2 このコマンドでは、非インタラクティブシェルすら起動しないとの指摘を頂きました。訂正が遅れに遅れていたこと、お詫びします。
以下は、上記のページの受け売りです。
ログインシェル
bash をプログラムとして起動するとき、オプション -
または --login
が付加された際にスタートするシェル。
次のようなコマンドで起動する:
sudo su -
bash --login
ssh user@host
- ログインシェルの場合、次のようなファイルが列挙した順に実行される:
/etc/profile
~/.bash_profile
~/.bash_login
~/.profile
-
~/.bashrc
はこのリストの中にないが、ほとんどの~/.bash_profile
では~/.bashrc
を呼び出して実行している。
(純粋な)インタラクティブシェル
インタラクティブシェルとは、オプション -c を付加されずに起動されるシェルで、標準入出力が(仮想)端末に接続されているもの。インタラクティブシェルの全てがログインシェルであるとは限らない。
次のようなコマンドを打つとログインシェルではなく、純粋なインタラクティブシェルが起動される:
sudo su
bash
このインタラクティブではあるがログインシェルではないシェルでは、 ~/.bashrc
のみが実行される。ただし、デフォルトでは多くの場合、 ~/.bashrc
にシステム標準のbashrc
ファイル (例: /etc/bashrc
。ディストリビューションにより異なる) をも実行するように記述されている。
-
~/.bashrc
ファイル中でecho
で画面出力させないように注意。さもないと、ssh user@host /path/to/command
などを実行した際にコマンドに関係のない文字列が出力されてしまう。-
[追記 2015.12.1]
~/.bashrc
で、ログインシェルの時だけにコマンドを実行するには次のように。
-
[追記 2015.12.1]
case $- in
*i*)
/path/to/command
;;
esac
[修正 2017.11.4] [2018.6.25 削除]ssh user@host /path/to/command
はシェルを起動しないとの指摘をいただきましたので、下記非インタラクティブシェルに入れる形で修正しました。
非インタラクティブシェル
もある**[2017.5.4 名称変更]**。このたぐいのシェルは ~/.bashrc
や ~/.bash_profile
のようなスクリプトは、何も自動的に実行しない。
非インタラクティブシェルの起動例:
su user -c /path/to/command
bash -c /path/to/command
結局、PS1=
はどこに書けばよいのか
PS1=[\u@\h \W]$
は、インタラクティブであるシェルにおいて起動時に実行されればよいわけです。ので、~/.bashrc
に記述すればよいでしょう。
そして、~/.bash_profile
に、~/.bashrc
を起動する次のような記述があるのを確認しておくことになります。
# .bashrc
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi