「シェルの設定ファイルのお勉強」 というのを書いたことがあり、その続きのようなもの。
ログイン・シェル、インタラクティブ・シェルの定義?
ログイン・シェル、インタラクティブ・シェルという言葉がある。 UNIX を使い始めたのは割と早く (まだ学部生だったかな?)、 漠然と意味は分かっていたつもり???
以前の私が何となく理解(誤解含む)していたこと |
シェルは、ターミナル等から呼び出されて、
ユーザーの相手をする(対話する)場合と、
スクリプトの面倒をみる場合があって、
前者の場合はインタラクティブ・シェルと呼ばれる。
ログイン・シェルというのは、 システムに “ログイン” したユーザーの相手をするためのシェル。 (ログインって何だろう?とは当時の私は考えなかった。 わかっているつもりだった。 今改めて定義は何かと言われると意外と難しい。) |
これによると、 ログイン・シェルというのはインタラクティブ・シェルである、 ということになるが、実はこれは間違いで、 インタラクティブ・シェルでなくても --login をつけて起動されれば、 ログイン・シェルとなる。
結局、必要条件でも十分条件でもない。ログイン・シェルであるかどうか、 インタラクティブ・シェルであるかどうか、 通りの場合がある。
ネットで、 「ログインシェルとインタラクティブシェルの違い」 というのを見つけたのだけど、多分この人は誤解していて、 ここに書いてあるのは正しくは「ログインシェルとそうでないシェル (インタラクティブ・シェルではある)の違い」 ということなのだろう。
「ログインシェル、インタラクティブシェルの見分け方(bash)」 は正しそうだ。落ち着いて見ると、タイトルだけ見て分かるのかも (「AとBの違い」, 「A, Bの見分け方」)。
ログイン・シェルか、そうでないかの見分け方
shopt login_shell というコマンドを使え、ということをいう人もいる。
bash を使っているとき |
% shopt login_shell login_shell on %あるいは % shopt login_shell login_shell off % |
zsh には shopt はなくて、代わりに setopt がある。
zsh を使っているとき |
% setopt combiningchars interactive login monitor shinstdin zle % |
それから、完全に判定できる訳ではないが、 echo $0 として、 - がついていればログイン・シェルである、という判定法もある。
注意: ログイン・シェルでも、- がついていないことがある。
以上が本当かどうかは、簡単に試せる。
普段 (zsh で) 作業しているターミナルで |
% echo $0 -zsh % zsh % echo $0 zsh % setopt combiningchars interactive monitor shinstdin zle % exit % su 誰か Password: むにゃむにゃ % echo $0 zsh % setopt combiningchars interactive monitor shinstdin zle % exit % su - 誰か Password: むにゃむにゃ % echo $0 -zsh % exit % zsh --login % echo $0 zsh % setopt combiningchars interactive login monitor shinstdin zle % exit % |
以上から分かることは
bash をログイン・シェルに登録して同様のことを |
% echo $0 -bash % bash % echo $0 bash % shopt login_shell login_shell off % exit % su 誰か % echo $0 bash % shopt login_shell login_shell off % exit % su - 誰か % echo $0 -bash % exit % bash --login % echo $0 bash % shopt login_shell login_shell on % exit |
こういう仕掛けが何の役に立つかについて、少し考えてみる。
インタラクティブ・シェルか、そうでないかの見分け方
もちろん setoptを使う、という手がある (zshの場合に限定 … 具体的には setopt | grep interactive かなあ?)。
echo $- として、 i が含まれていればインタラクティブ・シェル、という判定法もあるとか。
% echo $- 569XZilms % zsh % echo $- 569XZims % exit % su toor Password: % echo $- 569XZims % exit % su - toor Password: % echo $- 569XZilms % cat my.sh #!/bin/sh echo $- % ./my.sh hB |
(ところで、L の小文字 l ってログイン・シェルを意味しているのでは?? でもたとえそうだとしても、$0 のときと同じで、 ログイン・シェルでも l がない場合があるようだ。)
もう一つ、echo $PS1 として環境変数 PS1 をチェックする、 という方法を紹介する人もいるが (bash スクリプトで良く見かけるね)、 これは bash 限定みたいで、 zsh では “PS1: Undefined variable.” と叱られる。
参考: PS1が定義されていなければ($PS1の文字列長が0ならば) |
if [ -z "$PS1" ]; then return fi |
ログイン・シェルとそうでないインタラクティブ・シェルの違い
環境変数以外に、読む設定ファイルが異なる、というのが大きいかな。
bash がログイン・シェルとして起動されると、 /etc/profile が存在するならば読む。 続いて、~/.bash_profile, ~/.bash_login, ~/.profile の順に検索して、 最初に見つかる存在してかつ読めるもの(だけ)を読む。
bash がログイン・シェルとしてではなく、 ただのインタラクティブ・シェルとして起動されると、 ~/.bashrc を読もうとする。
~/.bash_profile の中で、 ~/.bashrc を読むように設定してあることが多い。 (そうしないと、読まれない、ということだ。)
ちなみに、インタラクティブでないシェルは、 これらの設定ファイルを読まないらしい。