¿Dónde se define el shell de inicio de sesión?

16

Estaba leyendo la diferencia entre sudo -i/-s aquí . Después de usar el comando shopt, se observa que todos ( sudo su/sudo -i/sudo -s) $SHELLproporcionan los mismos resultados, pero los shoptresultados de los comandos son diferentes.

Entonces, ¿cómo se define de inicio de sesión de inicio de sesión y no la cáscara?

¿De dónde shoptsaca el resultado?

¿Por qué no 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:~# 
prado
fuente
77
Un problema es que "shell de inicio de sesión" tiene dos significados: 1. Es una instancia de un shell iniciado de una manera específica que hace cosas específicas (como lectura .profileo equivalentes), y 2. Es el shell que se supone que debe iniciarse al iniciar sesión para usuario, como se define en /etc/passwdo equivalente. $SHELLcontiene el último, sus shoptsalidas tratan con el primero. Típicamente, cuando el shell en (2) se inicia al iniciar sesión, se inicia de la manera específica necesaria para (1), de ahí la combinación de significados.
muru
1
La explicación de @muru es buena. por ejemplo, si ingresa SSH a su computadora desde una máquina remota. / usr / sbin / sshd en su sistema bifurcaría un shell definido por $SHELL(y lo conectaría a un pseudo terminal) que a su vez se define en su entrada / etc / passwd. este shell es un shell de inicio de sesión y se puede probar con if [[ -o login ]]; then echo "I am a login shell"; fi. Al ser un shell de inicio de sesión, realizaría las tareas apropiadas para una nueva sesión. por ejemplo, fuente ~/.zprofileo similar que posiblemente establezca variables de entorno y cualquier código de shell personalizado que desee ejecutar en este momento
the_velour_fog

Respuestas:

17

TL; DR :

  • ¿Dónde se define el shell de inicio de sesión? En /etc/passwd.
  • ¿Son sudo su/ sudo su -/ sudo -i/ sudo -siguales? No, todos generan un caparazón pero de manera diferente y en contextos diferentes.
  • ¿Qué $SHELLhacer? Solo dígale a su shell predeterminado, igual que en /etc/passwd.

Respuesta real :

En primer lugar, es importante mencionar que shoptes específico de bash. Por ejemplo, soy mkshusuario de shell y no tiene shopt, al igual kshque no.

A continuación, ¿qué login_shellse supone que representa exactamente ? De man bash:

login_shell

El shell establece esta opción si se inicia como un shell de inicio de sesión

Ese es el punto clave. sudo -i, como ya sabe por la respuesta anterior que leyó, se supone que simula el inicio de sesión inicial. Es por eso que shoptinforma login_shell on para esta opción. Piense en esto como si sudo -iobligara al shell a pasar por los archivos que se supone que deben aparecer solo durante un proceso de inicio de sesión (que no se obtienen mediante shells interactivos).

En otros casos, ya está ejecutando una instancia de un shell, por lo que no puede ser un shell de inicio de sesión, y el propósito de las opciones es diferente. sudo -ssimplemente lee $SHELL(que está destinado a representar su shell predeterminado como se establece /etc/passwd) variable y lo ejecuta con privilegio de root. Esto es equivalente a hacer sudo $SHELLo sudo mksho sudo bash(lo que sea que uses).

¿Recuerdas que mencioné que soy mkshusuario? Mira esto:

$ 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

Lo que ves es que sudo -ssaltó de bashmi mkshshell, con el indicador característico que he establecido para él. Y, por supuesto, dado que no es una acción de inicio de sesión, bashya que informaría que el shell se genera como una instancia de shell sin inicio de sesión. Sin embargo, en mi caso, verá que $-no tiene una letra lallí, que estaría allí si se tratara de una instancia de shell de inicio de sesión.

Finalmente, la misma idea se aplica a sudo suy sudo su -. Más tarde, uno genera una instancia de shell de inicio de sesión (es decir, se ejecutarán los archivos específicos necesarios para iniciar sesión) y el anterior genera solo shells interactivos (es decir, los archivos de inicio de sesión no se ejecutan).

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

Por lo tanto, técnicamente, shopt login_shellno tiene relación $SHELLalguna. Piénselo de esta manera: su propósito es mostrar cómo se ejecuta bash. $SHELLse supone que refleja solo lo que has asignado /etc/passwd.

En cuanto a la diferencia entre el shell de inicio de sesión y el shell de no inicio de sesión, Gilles lo ha explicado en unix.stackexchange.com en esta respuesta .


Diversión adicional

Aquí hay algo divertido que puedes probar. Como ya sabrás, se ejecutará un shell de inicio de sesión .profile(y .bashrcdado que Ubuntu .profile está configurado para hacerlo ), pero el infierno que no inicia sesión solo ejecutará el .bashrcarchivo. Por lo tanto, podemos probar con echocuál de estos comandos ejecuta un shell de inicio de sesión y cuál no, y esperamos dos líneas echopara shell de inicio de sesión y solo una para no inicio de sesión.

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

Apropiadamente, aquellos con dos líneas de salida se habrán login_shellestablecido en on.

Sergiy Kolodyazhnyy
fuente
Gracias @Serg y @Zanna. Ahora sobre $SHELLy login_shell/non-login_shellme aclararon. ¿Pero de dónde shoptobtienen los detalles? Es de echo $0?
prado
1
@prado Yo diría que sí, ya que el primer carácter de $0se usa para designar si un shell es o no un shell de inicio de sesión, por lo que si shoptverificaría esa variable, claro, es perfectamente aceptable. Sin embargo, probablemente haya más de lo que parece. shoptprobablemente para esta pregunta, no tengo una respuesta difícil, ya que no estoy familiarizado con el código fuente de bash tan bien.
Sergiy Kolodyazhnyy
@prado Bash puede iniciarse como un shell de inicio de sesión, ya sea teniendo el primer carácter de $ 0 -o utilizando la -lopción.
muru
@prado puede leer sobre la invocación y las opciones de bash en la página del manual. por ejemplo, la sección de SHELL BUILTIN COMMAND dice 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 ser una manera en que bash te permite descubrir, programáticamente, cómo saber cómo se inició. la otra forma sería[[ -o login ]]
the_velour_fog
11

Como @Serg explica en esta respuesta sobre cómo saber qué shell está ejecutando , la SHELLvariable es solo el shell predeterminado del usuario actual como se lee en /etc/passwd:

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

así que si echo $SHELLsiempre volveré /bin/bash:

$ zsh
% echo $SHELL
/bin/bash

Sea o no la envolvente es una envolvente de inicio de sesión, es un sh ell opt ion determinado a la vez que se inicia la cáscara. El programa shell almacena esta información junto con todas sus otras configuraciones y variables. El shoptcomando proporciona una manera de ver esta información y, si es posible para la opción en cuestión, establecerla o desactivarla (este no es el caso para el login_shellcual, por supuesto, depende del proceso utilizado para iniciar el shell)

Las sudoopciones del programa determinan cómo se iniciarán estos diferentes tipos de shell raíz:

ingrese la descripción de la imagen aquí

Zanna
fuente
1
Buena explicación. Creo que has explicado qué shopty login_shellse supone que representan mucho mejor que en mi respuesta.
Sergiy Kolodyazhnyy
@Serg, gracias :) Creo que tu explicación es más completa :)
Zanna
3

man bash:

Un shell de inicio de sesión es aquel cuyo primer carácter del argumento cero es a -, o uno que comenzó con la --loginopción.

man login:

El valor para $HOME, $SHELL[...] se ajustan de acuerdo a los campos apropiados en la entrada de la contraseña.

En breve:

  • Un shell es un shell de inicio de sesión si se invocó como un shell de inicio de sesión.
  • La variable de entorno $SHELLes establecida por logino por el programa de invocación, por ejemplo su. El shell en sí no lo establece.
  • shopt muestra las opciones de shell actualmente vigentes.
AlexP
fuente