Onde o shell de login está definido?


16

Eu estava lendo a diferença entre sudo -i/-s aqui . Depois de usar o comando shopt, note-se que todos ( sudo su/sudo -i/sudo -s) $SHELLestão fornecendo os mesmos resultados, mas os shoptresultados do comando são diferentes.

Então, como é definido o shell de login e não login?

De onde shoptobtém o resultado?

Por que não está relacionado $SHELL?

sudo su

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
Um problema é que "shell de login" tem dois significados: 1. É uma instância de um shell iniciada de uma maneira específica que faz coisas específicas (como leitura .profileou equivalentes) e 2. É o shell que deveria ser iniciado no login para um usuário, conforme definido /etc/passwdou equivalente. $SHELLcontém o último, suas shoptsaídas lidam com o primeiro. Normalmente, quando o shell em (2) é iniciado no login, ele é iniciado da maneira específica necessária para (1), daí a fusão de significados.
Muru

11
A explicação do @muru é boa. por exemplo, se você fizer o SSH no seu computador a partir de uma máquina remota. / usr / sbin / sshd no seu sistema bifurca um shell definido por $SHELL(e o conecta a um pseudo terminal) que por sua vez é definido na sua entrada / etc / passwd. Este shell é um shell de login e pode ser testado com if [[ -o login ]]; then echo "I am a login shell"; fi. sendo um shell de logon, ele executaria as tarefas apropriadas para uma nova sessão. por exemplo, fonte ~/.zprofileou similar que possivelmente
definiria

Respostas:


17

TL; DR :

  • Onde o shell de login está definido? In /etc/passwd.
  • São sudo su/ sudo su -/ sudo -i/ sudo -siguais? Não, todos eles geram uma concha, mas de maneira diferente e em contextos diferentes.
  • O que $SHELLfaz? Apenas diga ao seu shell padrão, o mesmo que em /etc/passwd.

Resposta real :

Antes de tudo, é importante mencionar que shopt é específico do bash. Por exemplo, eu sou mkshusuário de shell, e ele não tem shopt, assim como kshnão.

Em seguida, o que exatamente login_shelldeve representar? De man bash:

login_shell

O shell define esta opção se for iniciado como um shell de login

Esse é o ponto chave. sudo -i, como você já sabe da resposta anterior que leu, deve simular o login inicial. É por isso que os shoptrelatórios login_shell on para esta opção. Pense nisso como se sudo -iobriga o shell a passar por arquivos que deveriam aparecer apenas durante um processo de login (que não são originados por shells interativos).

Em outros casos, você já está executando uma instância de um shell, portanto, não pode ser o shell de login em primeiro lugar, e o objetivo das opções é diferente. sudo -sapenas lê $SHELL(que deve representar seu shell padrão como definido /etc/passwd) e a executa com privilégios de root. Isso é equivalente a fazer sudo $SHELLou sudo mkshou sudo bash(o que você usar).

Lembre-se de que eu mencionei que sou mksh usuário? Dê uma olhada neste:

$ 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

O que você vê é que sudo -spulou bashpara o meu mkshshell, com o prompt característico que defini para ele. E, é claro, como não é uma ação de login, bashele reportaria que o shell foi gerado como uma instância do shell que não é de login. No meu caso, no entanto, você vê que$- não tem uma carta llá, que estaria lá se essa fosse uma instância do shell de logon.

Finalmente, a mesma idéia se aplica a sudo sue sudo su -. Posteriormente, uma gera a instância do shell de login (ou seja, os arquivos específicos necessários para o login serão executados) e a primeira gera apenas shells interativos (ou seja, os arquivos de login não são executados).

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

Então, tecnicamente, shopt login_shellnão tem relação $SHELLalguma. Pense desta maneira: seu objetivo é mostrar como bash é executado. $SHELLdeve refletir apenas o que você atribuiu /etc/passwd.

Quanto à diferença entre o shell de login e o shell que não é de login, foi explicado pelo respeitado Gilles em unix.stackexchange.com nesta resposta .


Diversão adicional

Aqui está algo divertido que você pode tentar. Como você já deve saber, um shell de login será executado .profile(e, .bashrccomo o Ubuntu .profile está configurado para fazê-lo ), mas o não-logon será o único .bashrcarquivo em execução . Portanto, podemos testar com echoqual desses comandos executa um shell de logon e qual não, e esperamos duas linhas echopara o shell de logon e apenas uma para o não logon.

$ 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:~# 

Apropriadamente, aqueles com duas linhas de saída terão login_shelldefinido como on.


Obrigado @Serg e @Zanna. Agora sobre $SHELLe login_shell/non-login_shellfoi esclarecido. Mas de onde shoptobter detalhes? É de echo $0?
Prado

11
@prado Eu diria que sim, já que o primeiro caractere $0é usado para designar se um shell é ou não um shell de login, por isso, se você shoptverificar essa variável - com certeza, é perfeitamente aceitável. No entanto, provavelmente há mais do que aparenta. shoptprovavelmente Para esta pergunta, não tenho uma resposta difícil, já que não estou familiarizado com o código-fonte do bash tão bem.
Sergiy Kolodyazhnyy

O @prado Bash pode ser iniciado como um shell de logon, com o primeiro caractere de $ 0 -ou usando a -lopção
Muru

@prado, você pode ler sobre a invocação e as opções do bash na página de manual. por exemplo, a seção SHELL BUILTIN COMMAND diz login_shell The shell sets this option if it is started as a login shell (see INVOCATION above). The value may not be changed.que shopt login_shellparece que o bash de uma maneira permite que você descubra - programaticamente como saber como foi iniciado. a outra maneira seria[[ -o login ]]
the_velour_fog 25/11

11

Como o @Serg explica nesta resposta sobre como saber em qual shell você está executando , a SHELLvariável é apenas o shell padrão do usuário atual, conforme lido em /etc/passwd:

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

então se eu echo $SHELLsempre voltará /bin/bash:

$ zsh
% echo $SHELL
/bin/bash

Quer ou não o shell é um shell de login, é um sh ell opt ion determinada no momento do shell é iniciado. O programa shell armazena essas informações juntamente com todas as outras configurações e variáveis. O shoptcomando fornece uma maneira de ver essas informações e, se possível para a opção em questão, configurá-las ou desativá-las (esse não é o caso para o login_shellqual, é claro, depende do processo usado para iniciar o shell)

As sudoopções do programa determinam como esses diferentes tipos de shell raiz serão iniciados:

insira a descrição da imagem aqui


11
Boa explicação. Eu acho que você explicou o que shopte login_shellsupostamente representam muito melhor do que na minha resposta.
23816 Sergiy Kolodyazhnyy

@Serg obrigado :) Eu acho que sua explicação é mais completa :)
Zanna

3

man bash:

Um shell de login é aquele cujo primeiro caractere do argumento zero é a -ou iniciou com a --loginopção

man login:

O valor para $HOME, $SHELL[...] é definido de acordo com os campos apropriados na entrada da senha.

Em resumo:

  • Um shell é um shell de logon se for invocado como um shell de logon.
  • A variável de ambiente $SHELLé definida pelo loginou pelo programa que está chamando, por exemplo su. O próprio shell não o define.
  • shopt mostra as opções de shell atualmente em vigor.
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.