TL; DR :
- Onde o shell de login está definido? Em
/etc/passwd
. - Os
sudo su
/sudo su -
/sudo -i
/sudo -s
são iguais? Não, todos eles geram uma casca, mas de forma diferente e em contextos diferentes. - O que o
$SHELL
faz? Basta informar o seu shell padrão, o mesmo que em/etc/passwd
.
Resposta real :
Em primeiro lugar, é importante mencionar que shopt
é específico do bash. Por exemplo, sou usuário mksh
shell e não tem shopt
, assim como ksh
não.
Em seguida, o que exatamente login_shell
deve 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 você leu, deve simular o login inicial. É por isso que shopt
reporta login_shell on
para esta opção. Pense nisso como se sudo -i
forçasse o shell a passar por arquivos que deveriam aparecer apenas durante um processo de login (que não é obtido por shells interativos).
Em outros casos, você já está executando uma instância de um shell, portanto, ele não pode ser shell de login e a finalidade das opções é diferente. sudo -s
simplesmente lê a variável $SHELL
(que deve representar seu shell padrão como definido em /etc/passwd
) e o executa com privilégio de raiz. Isso equivale a fazer sudo $SHELL
ou sudo mksh
ou sudo bash
(o que quer que você use).
Lembre-se de que mencionei mksh
user? Dê uma olhada nisso:
$ 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 -s
saltou de bash
para meu mksh
shell, com o prompt de característica que defini para ele. E, claro, como não é uma ação de login, para bash
ele informaria que o shell foi gerado como uma instância de shell de não-login. No meu caso, no entanto, você vê que $-
não tem uma letra l
lá, o que estaria lá se fosse uma instância do shell de login.
Por fim, a mesma ideia se aplica a sudo su
e sudo su -
. Mais tarde, uma gera a instância de shell de login (ou seja, arquivos específicos que são necessários para o login ser executado) e a primeira gera somente shells interativas (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_shell
não tem relação com $SHELL
. Pense desta maneira: sua finalidade é mostrar como o bash é executado. $SHELL
deve refletir apenas o que você atribuiu em /etc/passwd
.
Quanto à diferença entre o shell de login e o shell de não-login, isso foi explicado pelo altamente respeitado Gilles em unix.stackexchange.com em esta 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 .bashrc
desde que o .profile
do Ubuntu esteja configurado para fazer isso ), mas não-logins hell irá executar apenas .bashrc
file. Assim, podemos testar com echo
qual desses comandos executa um shell de login e qual não, e esperamos duas linhas de echo
para shell de login e apenas uma para não-login.
$ 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_shell
definido como on
.