対話型シェルと非対話型シェルの基本的な違いを理解しています。しかし、ログインシェルと非ログインシェルを正確に区別するものは何ですか?
非ログインインタラクティブシェルの使用例はありますか?
対話型シェルと非対話型シェルの基本的な違いを理解しています。しかし、ログインシェルと非ログインシェルを正確に区別するものは何ですか?
非ログインインタラクティブシェルの使用例はありますか?
回答:
ログインシェルは、対話型セッションにログインするときにユーザーIDで実行される最初のプロセスです。ログインプロセスは、シェルに慣例に従ってログインシェルとして振る舞うように指示します:引数0(通常はシェル実行可能ファイルの名前)を-
追加し、文字を追加します(たとえば-bash
、通常はbash
。環境変数の設定など:/etc/profile
および~/.profile
従来のBourneシェルの場合~/.bash_profile
、bash †の場合/etc/zprofile
、~/.zprofile
zsh †の場合/etc/csh.login
、~/.login
cshの場合など。
テキストコンソールにログインするか、SSH経由で、またはを使用してログインsu -
すると、対話型ログインシェルが表示されます。(Xディスプレイマネージャーで)グラフィカルモードでログインすると、ログインシェルは取得されず、セッションマネージャーまたはウィンドウマネージャーが取得されます。
非対話型のログインシェルを実行することはまれですが、プロファイルファイルの読み取りを手配するために、ディスプレイマネージャーを使用してログインするときに、Xの設定によっては実行されない場合があります。他の設定(これはディストリビューションとディスプレイマネージャーに依存します)を読み取り/etc/profile
、~/.profile
明示的に読み取るか、読み取らないでください。非対話型ログインシェルを取得する別の方法は、端末ではない標準入力を介して渡されるコマンドを使用してリモートでログインすることですssh example.com <my-script-which-is-stored-locally
(たとえばssh example.com my-script-which-is-on-the-remote-machine
、非対話型、非ログインシェルを実行します)。
既存のセッションのターミナル(画面、Xターミナル、Emacsターミナルバッファ、別のシェル内のシェルなど)でシェルを起動すると、対話型の非ログインシェルになります。そのシェルは、シェルの設定ファイル(読むかもしれない~/.bashrc
として呼び出さbashのためのbash
、/etc/zshrc
および~/.zshrc
zshのため、/etc/csh.cshrc
および~/.cshrc
CSHのため、で示されるファイルENV
として呼び出されたときに、このようなダッシュ、kshの、およびbashのようにPOSIX / XSI準拠のシェルの変数をsh
、$ENV
設定している場合と、~/.mkshrc
mkshなど)。
シェルがスクリプトまたはコマンドラインで渡されたコマンドを実行するとき、それは非対話型、非ログインシェルです。このようなシェルは常に実行されます。プログラムが別のプログラムを呼び出すと、シェルで小さなスクリプトを実際に実行して他のプログラムを呼び出すことは非常に一般的です。いくつかのシェルは、この場合、スタートアップファイルを読み込む(bashはで示されるファイルに実行BASH_ENV
変数、zshの実行/etc/zshenv
と~/.zshenv
)を、これは危険です:シェルはコンテキストのすべての種類に呼び出すことができます、あなたはそれがないかもしれない何かできることはほとんどありません何かを壊します。
†少し簡略化しています。詳細についてはマニュアルを参照してください。
bash
非対話型ログインシェルとして実行する方法の例を教えていただけますか?
echo $- | bash -lx
FOO
が環境変数(つまり、を.profile
含むexport FOO=something
)の場合、を含むすべてのサブプロセスで使用できますfoo.sh
。あなたが変更した場合.profile
にexport FOO=something_else
、その後./foo.sh
、まだ印刷されますsomething
、あなたが次にログインしたときまで。
ログインシェルにいるかどうかを確認するには:
prompt> echo $0
-bash # "-" is the first character. Therefore, this is a login shell.
prompt> echo $0
bash # "-" is NOT the first character. This is NOT a login shell.
Bashでは、以下も使用できますshopt login_shell
。
prompt> shopt login_shell
login_shell off
(またはon
ログインシェル内)。
情報はman bash
(呼び出しの検索)にあります。抜粋は次のとおりです。
ログインシェルは、引数ゼロの最初の文字が-であるシェル、または--loginオプションで開始されたシェルです。
これは自分でテストできます。SSHを使用するときはいつでも、ログインシェルを使用しています。例えば:
prompt> ssh user@localhost
user@localhost's password:
prompt> echo $0
-bash
ログインシェルを使用することの重要性は、すべての設定/home/user/.bash_profile
が実行されることです。興味がある場合は、もう少し情報があります(からman bash
)
「bashが対話型ログインシェルとして、または--loginオプションを使用した非対話型シェルとして呼び出されると、最初に/ etc / profileファイルが存在する場合、そのファイルからコマンドを読み取って実行します。そのファイルを読み取った後、探し
~/.bash_profile
、~/.bash_login
、および~/.profile
、そのためには、および読み込み、存在し、読み取り可能である。シェルはこの動作を抑制するために開始されたとき--noprofileオプションを使用することができる最初の1からのコマンドを実行します。」
ログインシェルタイプをチェックするTimothyの方法と組み合わせて、Gillesのすばらしい答えを詳しく説明します。
自分で物事を見たい場合は、以下のスニペットとシナリオを試してください。
シェルが(非)インタラクティブかどうかを確認する
if tty -s; then echo 'This is interactive shell.'; else echo 'This is non-interactive shell.'; fi
シェルが(非)ログインであるかどうかの確認
の出力がでecho $0
始まる場合は-
、ログインシェルです(echo $0
出力例:)-bash
。それ以外の場合は、非ログインシェルです(echo $0
出力例:)bash
。
if echo $0 | grep -e ^\- 2>&1>/dev/null; then echo "This is login shell."; else echo "This is non-login shell."; fi;
上記の2つを組み合わせて、両方の情報を一度に取得しましょう。
THIS_SHELL_INTERACTIVE_TYPE='non-interactive';
THIS_SHELL_LOGIN_TYPE='non-login';
if tty -s; then THIS_SHELL_INTERACTIVE_TYPE='interactive'; fi;
if echo $0 | grep -e ^\- 2>&1>/dev/null; then THIS_SHELL_LOGIN_TYPE='login'; fi;
echo "$THIS_SHELL_INTERACTIVE_TYPE/$THIS_SHELL_LOGIN_TYPE"
ssh ubuntu@34.247.105.87
Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.4.0-1083-aws x86_64)
ubuntu@ip-172-31-0-70:~$ THIS_SHELL_INTERACTIVE_TYPE='non-interactive';
ubuntu@ip-172-31-0-70:~$ THIS_SHELL_LOGIN_TYPE='non-login';
ubuntu@ip-172-31-0-70:~$ if tty -s; then THIS_SHELL_INTERACTIVE_TYPE='interactive'; fi;
ubuntu@ip-172-31-0-70:~$ if echo $0 | grep -e ^\- 2>&1>/dev/null; then THIS_SHELL_LOGIN_TYPE='login'; fi;
ubuntu@ip-172-31-0-70:~$ echo "$THIS_SHELL_INTERACTIVE_TYPE/$THIS_SHELL_LOGIN_TYPE"
interactive/login
ubuntu@ip-172-31-0-70:~$ bash -c 'THIS_SHELL_INTERACTIVE_TYPE='non-interactive'; THIS_SHELL_LOGIN_TYPE='non-login'; if tty -s; then THIS_SHELL_INTERACTIVE_TYPE='interactive'; fi; if echo $0 | grep -e ^\- 2>&1>/dev/null; then THIS_SHELL_LOGIN_TYPE='login'; fi;
echo "$THIS_SHELL_INTERACTIVE_TYPE/$THIS_SHELL_LOGIN_TYPE"'
interactive/non-login
ssh ubuntu@34.247.105.87 < checkmy.sh
Pseudo-terminal will not be allocated because stdin is not a terminal.
Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.4.0-1083-aws x86_64)
non-interactive/login
ssh ubuntu@34.247.105.87 'THIS_SHELL_INTERACTIVE_TYPE='non-interactive'; THIS_SHELL_LOGIN_TYPE='non-login'; if tty -s; then THIS_SHELL_INTERACTIVE_TYPE='interactive'; fi; if echo $0 | grep -e ^\- 2>&1>/dev/null; then THIS_SHELL_LOGIN_TYPE='login'; fi; echo "$THIS_SHELL_INTERACTIVE_TYPE/$THIS_SHELL_LOGIN_TYPE"'
non-interactive/non-login
-t
スイッチを使用してリモートでssh経由でコマンドを実行する-t
スイッチを使用してsshを介してリモートでコマンドを実行する場合、明示的に対話型シェルを要求できます。
ssh ubuntu@34.247.105.87 -t 'THIS_SHELL_INTERACTIVE_TYPE='non-interactive'; THIS_SHELL_LOGIN_TYPE='non-login'; if tty -s; then THIS_SHELL_INTERACTIVE_TYPE='interactive'; fi; if echo $0 | grep -e ^\- 2>&1>/dev/null; then THIS_SHELL_LOGIN_TYPE='login'; fi; echo "$THIS_SHELL_INTERACTIVE_TYPE/$THIS_SHELL_LOGIN_TYPE"'
interactive/non-login
注:リモートでコマンドを実行するlogin shell
ことの詳細については、こちらのトピックをご覧ください。