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просто читає $SHELL(яка призначена для відображення вашої оболонки за замовчуванням як встановлена в /etc/passwd) змінної та запускає її з привілеєм root. Це еквівалентно виконанню sudo $SHELLабоsudo 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не має. Подумайте про це так: його мета - показати, як працює баш.$SHELLповинен відображати лише те, що вам призначено /etc/passwd.
Що стосується різниці між оболонкою для входу і оболонкою без входу, то в цій відповіді це пояснило високоповажний Gilles на unix.stackexchange.com .
Додаткові розваги
Ось щось цікаве ви можете спробувати. Як ви вже можете знати, запуститься оболонка для входу .profile(а .bashrcоскільки Ubuntu .profile налаштована так ), але пекло, яке не входить в систему, запустить лише .bashrcфайл. Тож ми можемо перевірити, echoяка з цих команд виконує оболонку входу, а яка ні, і ми очікуємо, що два рядки echoдля оболонки для входу та лише один для не входу в систему.
$ 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:~#
Досить належним чином, ті, які мають два рядки виводу, повинні login_shellвстановити on.
.profileабо еквіваленти), і 2. Це оболонка, яку слід запустити при вході в систему користувач, як визначено у/etc/passwdабо еквіваленті.$SHELLмістить останнє, вашіshoptрезультати стосуються першого. Як правило, коли оболонка в (2) запускається при вході в систему, вона запускається певним чином, необхідним для (1), отже, співвідношення значень.