ログインシェルはどこで定義されていますか?


16

sudo -i/-s ここの違いを読んでいました。コマンドを使用した後shopt、all(sudo su/sudo -i/sudo -s)は$SHELL同じ結果を提供しますが、shoptコマンドの結果は異なります。

それでは、ログインシェルと非ログインシェルはどのように定義されていますか?

どこからshopt結果を得ますか?

なぜ関係ないの$SHELLですか?

須藤す

givinv@87-109:~$ sudo su
root@87-109:/home/givinv# 
root@87-109:/home/givinv# 
root@87-109:/home/givinv# shopt -q login_shell && echo 'Login shell' || echo 'No login shell'
No login shell
root@87-109:/home/givinv# echo $SHELL
/bin/bash
root@87-109:/home/givinv# 
root@87-109:/home/givinv# exit
givinv@87-109:~$ 

sudo -i

givinv@87-109:~$ sudo -i
root@87-109:~# 
root@87-109:~# shopt -q login_shell && echo 'Login shell' || echo 'No login shell'
Login shell
root@87-109:~# echo $SHELL
/bin/bash
root@87-109:~# 

sudo -s

root@87-109:~# sudo -s
root@87-109:~# shopt -q login_shell && echo 'Login shell' || echo 'No login shell'
No login shell
root@87-109:~# echo $SHELL
/bin/bash
root@87-109:~# 

7
一つの問題は、「ログインシェル」は二つの意味を持っていることである:それは(読むよう具体的なことを行い、特定の方法で起動シェルのインスタンスの1 .profileまたは同等物)、および2.それはするはずのシェルのAのログインで開始で定義されている、/etc/passwdまたは同等のユーザー。$SHELL後者を含む場合、shopt出力は前者を処理します。通常、(2)のシェルがログイン時に起動されると、(1)に必要な特定の方法で起動されるため、意味の混同が生じます。
ムール

1
@muruの説明は良いものです。たとえば、リモートマシンからコンピュータにSSH接続する場合。システムの/ usr / sbin / sshd $SHELLは、/ etc / passwdエントリで定義されているシェルによってフォークされ(そして、擬似端末に接続されます)ます。このシェルはログインシェルであり、でテストできますif [[ -o login ]]; then echo "I am a login shell"; fi。ログインシェルであるため、新しいセッションに適したタスクを実行します。たとえば、~/.zprofile環境変数を設定する可能性のあるソースまたは類似のもの、およびこの時点で実行するカスタムシェルコード
the_velour_fog

回答:


17

TL; DR

  • ログインシェルはどこで定義されていますか?で/etc/passwd
  • あるsudo su/ sudo su -/ sudo -i/ sudo -s同じ?いいえ、それらはすべてシェルを生成しますが、異なる方法および異なるコンテキストで生成されます。
  • 何を$SHELLするの?の場合と同じように、デフォルトのシェルを指定するだけです/etc/passwd

実際の回答

まず第一に、それshoptがbash固有であることを言及することが重要です。たとえば、私はmkshシェルユーザーでありshopt、持っていないように、持ってkshいません。

次に、正確に何login_shellを表すことになっていますか?からman bash

login_shell

ログインシェルとして起動された場合、シェルはこのオプションを設定します

それが重要なポイントです。sudo -i、あなたが読んだ以前の回答から既に知っているように、最初のログインをシミュレートすることになっています。その ため、このオプションのshoptレポートlogin_shell onを作成します。これはsudo -i、ログインプロセス中にのみ表示されるはずのファイル(対話型シェルから取得されないファイル)をシェルに強制的に移動させるかのように考えてください。

それ以外の場合、シェルのインスタンスをすでに実行しているため、そもそもログインシェルにすることはできず、オプションの目的は異なります。(に設定されているデフォルトのシェルを表すことを意図しています)変数をsudo -s読み取り、root権限で実行するだけです。これは、or またはor (使用する方)を実行するのと同じです。$SHELL/etc/passwdsudo $SHELLsudo mkshsudo bash

私はmkshユーザーだと言ったことを覚えていますか?これをみて:

$ bash --posix
bash-4.3$ sudo -s
[sudo] password for xieerqi: 

DIR:/xieerqi|01:53|skolodya@ubuntu:
$ id 
uid=0(root) gid=0(root) groups=0(root)

DIR:/xieerqi|01:53|skolodya@ubuntu:
$ echo $-
imsU

表示されているのは、シェルにsudo -sジャンプしbashたもので、mksh設定した固有のプロンプトが表示されています。そしてもちろん、これはログインアクションではないためbash、シェルが非ログインシェルインスタンスとして生成されたことを報告します。ただし、私の場合は、そこに$-文字lがなく、ログインシェルインスタンスである場合に文字が表示されます。

最後に、同じ考え方がsudo suとに適用されsudo su -ます。後でログインシェルインスタンスが生成され(ログインに必要な特定のファイルが実行されます)、前者は対話型シェルのみが生成されます(ログインファイルは実行されません)。

bash-4.3$ sudo su
[sudo] password for xieerqi: 
root@eagle:/home/xieerqi# shopt login_shell
login_shell     off
root@eagle:/home/xieerqi# exit
bash-4.3$ sudo su -
[sudo] password for xieerqi: 
$ shopt login_shell
login_shell     on

技術的にshopt login_shellは、まったく関係あり$SHELLません。このように考えてください。その目的は、bashの実行方法を示すことです。$SHELLで割り当てたもののみを反映することになっています/etc/passwd

ログインシェルと非ログインシェルの違いについては、この回答でunix.stackexchange.comの尊敬されるGillesによって説明されています


追加の楽しみ

試してみてください。すでにご存知かもしれませんが、ログインシェルは実行されます.profile.bashrcUbuntuの実行.profile は構成されているため)が、非ログインhellは.bashrcファイルのみを実行します。したがってecho、これらのコマンドのいずれでログインシェルを実行し、どれを実行しないかをテストできます。ログインシェルには2行、echo非ログインには1 行のみが必要です。

$ echo "echo 'hi,i am .profile'"  >> .profile
$ echo "echo 'hi, i am .bashrc'" >> .bashrc
$ sudo -i
hi, i am .bashrc
hi,i am .profile
$ sudo su
hi, i am .bashrc
root@eagle:~# sudo su -
hi, i am .bashrc
hi,i am .profile
$ sudo -s
hi, i am .bashrc
root@eagle:~# 

適切なことに、出力が2行あるものはにlogin_shell設定されonます。


@Sergと@Zannaに感謝します。さて$SHELLlogin_shell/non-login_shell明確になった。しかし、どこからshopt詳細を入手できますか?からecho $0ですか?
プラド

1
@pradoの最初の文字は$0シェルがログインシェルであるかどうかを指定するために使用されるため、shoptその変数を確認する場合- はい、それは完全に受け入れられます。しかし、おそらく目に見える以上のものがあります。shoptおそらく、この質問については、bashのソースコードにあまり詳しくないので、難しい答えはありません。
セルギーKolodyazhnyy 16年

@prado Bashは、$ 0の最初の文字をbe -にするか、-lオプションを使用することにより、ログインシェルとして起動できます。
ムル

@pradoのmanページで、bashの呼び出しとオプションについて読むことができます。たとえば、SHELL BUILTIN COMMANDのセクションではlogin_shell The shell sets this option if it is started as a login shell (see INVOCATION above). The value may not be changed.shopt login_shellbashを使用して、それがどのように開始されたかをプログラムで確認する方法を見つけることができる1つの方法のように思えます。別の方法は[[ -o login ]]
-the_velour_fog

11

@Serg がこのシェルで実行中のシェルを確認する方法について説明しているようにSHELL変数は読み取り元の現在のユーザーのデフォルトシェルにすぎません/etc/passwd

$ grep zanna /etc/passwd
zanna:x:1000:1000:Zanna,,,:/home/zanna:/bin/bash

だから私がecho $SHELLそれが常に返される場合/bin/bash

$ zsh
% echo $SHELL
/bin/bash

かどうかシェルは、ログインシェルであるshのエルオプトイオンシェルが開始された時点で決定します。シェルプログラムは、他のすべての設定と変数とともにこの情報を保存します。このshoptコマンドは、この情報を表示し、可能であれば問題のオプションについて設定または設定解除する方法を提供します(login_shellもちろん、これは、シェルの起動に使用されるプロセスに依存する場合ではありません)

sudoプログラムのオプションは、rootシェルのこれらの異なるタイプが開始される方法を決定します。

ここに画像の説明を入力してください


1
良い説明。私の答えでは、あなたは何shoptを説明しており、login_shellそれをはるかによく表すと思われます。
セルギーKolodyazhnyy 16年

@Sergありがとう:)あなたの説明はもっと徹底的だと思います:)
Zanna

3

man bash

ログインシェルは、引数ゼロの最初の文字がであるシェル-、または--loginオプションで開始されるシェルです。

man login

[...] の値は$HOME$SHELLパスワードエントリの適切なフィールドに従って設定されます。

要するに:

  • ログインシェルとして起動された場合、シェルはログインシェルです。
  • 環境変数$SHELLlogin、たとえば、起動プログラムによって、または起動プログラムによって設定されsuます。シェル自体は設定しません。
  • shopt 現在有効なシェルオプションを表示します。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.