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 mksh
sudo 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), отже, співвідношення значень.