朝から昼寝

ITや身近な小ネタをちょこちょこ整理

ログインシェル、インタラクティブシェルの見分け方(bash)

概要

スクリプトやツールを使用する際、ログインシェルか、インタラクティブシェルかを考慮しないといけないことがあります。
本記事では、現在実行中のシェルがログインシェルかどうか、インタラクティブシェルかどうかを確認する方法についてまとめます。
対象はbash(GNU Bash)です。

本記事の目的

  • 現在実行中のシェルがログインシェルかどうか、インタラクティブシェルかどうかを確認する


目次

基本

ログインシェルかどうかの見分け方

shoptコマンド

shoptコマンドの結果、オプションlogin_shellが"on"の場合、現在実行中のシェルはログインシェルとして起動されています。

(ログインシェルとして起動されている場合)  
$ shopt login_shell
login_shell     on
  • "off"の場合は、非ログインシェルです。
  • shoptをオプション指定せず実行しても確認できますが、他のオプションも一緒に表示されます。

詳細は、4.3.2 The Shopt Builtinに記載があります。

変数$0の確認

$0(Special Parametersの1つ)を確認し、シェル名(bash)の前に-があれば、現在実行中のシェルはログインシェルとして起動されています。

(ログインシェルとして起動されている場合)  
$ echo $0
-bash ←bashの前に"-"あり
  • 注意点として、シェル名(bash)の前に-が無くても、ログインシェルである場合があります。
    例えば、bash --loginbash -lでログインシェルとして起動された場合は、$0のシェル名(bash)の前に-はありません。
  • 対して、前述のshoptの場合は、bash --loginbash -lで起動しても"login_shell on"と表示されます。
    よって、ログインシェルかどうかを判定する際は、$0でなくshoptを使用する方が無難でしょう。
  • 変数$0には、引数無しでbashを起動した場合に引数0(詳細は後述)が格納されます。

詳細は、3.4.2 Special Parametersに記載があります。

インタラクティブシェルかどうかの見分け方

変数$-の確認

$-(Special Parametersの1つ)を確認し、iがあれば、現在実行中のシェルはインタラクティブシェルとして起動されています。

(インタラクティブシェルとして起動されている場合)  
$ echo $-
himBHs ←"i"が含まれている
  • 変数$-にはbashを起動するときに指定されたオプションフラグが格納されます。

詳細は、3.4.2 Special Parametersに記載があります。

変数$PS1の確認

$PS1(shell variablesの1つ)に値が格納されていれば、現在実行中のシェルはインタラクティブシェルとして起動されてい(ると概ね判断でき)ます。

(インタラクティブシェルとして起動されている場合)  
$ echo $PS1
[\u@\h \W]\$ ←プロンプト文字列(primary prompt string)が含まれている
  • $PS1は書き換え可能な変数なので、$PS1に値が格納されていたとしても、インタラクティブシェルであると言い切れるものではありません(ただ上記のようにターミナルでecho $PS1を対話的に実行している時点で、ほぼインタラクティブですが)。
  • インタラクティブシェルかどうかを判定する際は、$PS1でなく通常は書き換えできない$-を使用する方が無難でしょう。

詳細は、3.4.2 Special Parametersに記載があります。

詳細

"ログインシェル"とは

本記事では、bashの起動方法としての"ログインシェル"について記載しています。

/etc/passwdの第7フィールド(shell、ログイン時に起動されるシェルの指定)のことではありません。

ざっくり言うと(厳密ではありません)、ログイン時(login)に起動されるシェルがログインシェルです。

例えば、sshログイン、su -sudo -iによりログインシェルが起動されます。

もう少し詳しく

ログインシェルは、起動時の引数0(argv[0]、argument zero)の最初の文字が-であるシェル、もしくは、--login(-l)オプションを指定して起動されたシェルのことです。

A login shell is one whose first character of argument zero is ‘-’, or one invoked with the --login option.
6.1 Invoking Bash

以下、"引数0"のあたりについて補足します。

実行対象のプログラム自体(ここではbashのこと)と、それを実行するときの呼び出し方(引数0)は、通常同一です(bashを起動するときは"bash"で呼び出す)。
しかし、bash(プログラム)を実行する際、その呼び出し方(引数0)として"bash"でなく"-bash"を指定する場合があります。
bashは、この引数0の先頭に-があると、ログインシェルとして起動します。

具体的には、bashに含まれるビルトインコマンドの1つであるexecコマンドは、-lオプションにより引数0の先頭に-を追加してコマンドを実行することができます。つまり、exec -l bashにより、bash実行時の引数0として"-bash"を指定することになります。

システムへのログイン時に実行されるloginは、この処理を行うことでログインシェルとして起動しているようです。

If the -l option is supplied, the shell places a dash at the beginning of the zeroth argument passed to command. This is what the login program does.
builtinのexecコマンド

他に、exec -a -bash bashも同様の意味です。

execコマンド自体についてのより詳細な内容は見当たりませんが、exec系の関数が参考になると思います。

なお、bash --login(-l)は、インタラクティブシェルの場合exec -l bashと同等の意味です。

"インタラクティブシェル"とは

本記事では、bashの起動方法としての"インタラクティブシェル"について記載しています。

ざっくり言うと(厳密ではありません)、ターミナル経由で対話的に入力、出力するシェルがインタラクティブシェルです。

ターミナルに[user@host /dir]$のようなプロンプトが表示されたシェル環境があればインタラクティブシェルです。

もう少し詳しく

インタラクティブシェルは、以下のいずれかに該当するシェルです。

  • オプションでない引数(スクリプトファイル等)が指定されていない、かつ-cオプションが指定されていない、かつ入力と出力が端末に接続されている(isatty関数で判断)
  • -iオプションが指定されている

インタラクティブシェルの起動時に-sオプションを指定すると、positional parameters($0~$9)を設定できます。

参考URI

GNU Bash

関連記事(シェル、umask等)