Де визначена оболонка для входу?


16

Я читав sudo -i/-s тут різницю . Після використання команди shoptзазначається, що всі ( sudo su/sudo -i/sudo -s) $SHELLнадають однакові результати, але shoptрезультати команд різні.

Отже, як визначається оболонка для входу та не входу?

Звідки shoptберуть результат?

Чому це не пов'язано $SHELL?

судо су

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

судо -і

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

судо -с

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
Одна проблема полягає в тому, що "оболонка входу" має два значення: 1. Це екземпляр оболонки, запущений певним чином, який робить конкретні речі (наприклад, читання .profile або еквіваленти), і 2. Це оболонка, яку слід запустити при вході в систему користувач, як визначено у /etc/passwdабо еквіваленті. $SHELLмістить останнє, ваші shoptрезультати стосуються першого. Як правило, коли оболонка в (2) запускається при вході в систему, вона запускається певним чином, необхідним для (1), отже, співвідношення значень.
муру

1
Пояснення @muru є хорошим. наприклад, якщо ви вбудуєте SSH у свій комп'ютер із віддаленої машини. / usr / sbin / sshd у вашій системі розщелить оболонку, яку визначає $SHELL(і з'єднає її з псевдотерміналом), що в свою чергу визначається у вашому записі / etc / passwd. ця оболонка є оболонкою для входу і може бути протестована if [[ -o login ]]; then echo "I am a login shell"; fi. Будучи оболонкою для входу, вона виконує ті завдання, відповідні новому сеансу. наприклад, джерело ~/.zprofileчи подібне, яке, можливо, встановило б змінні середовища та будь-який спеціальний код оболонки, який ви можете запустити в цей час
the_velour_fog

Відповіді:


17

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.


Дякую @Serg та @Zanna. Тепер про $SHELLта login_shell/non-login_shellуточнили. Але звідки shoptберуть деталі? Це звідки echo $0?
prado

1
@prado Я б сказав так, оскільки перший символ символу $0використовується для позначення того, чи оболонка є оболонкою для входу, тож якщо shoptперевірити цю змінну - звичайно, це цілком прийнятно. Однак, мабуть, більше, ніж очі. shoptМожливо, на це питання у мене немає важкої відповіді, оскільки я добре не знайомий з вихідним кодом Bash.
Сергій Колодяжний

@prado Bash можна запустити у вигляді оболонки для входу, маючи перший символ $ 0 -, або за допомогою -lпараметра.
muru

@prado ви можете прочитати про виклик bash та його параметри на сторінці man. Наприклад, у розділі КОМАНДА SHELL BUILTIN говориться, login_shell The shell sets this option if it is started as a login shell (see INVOCATION above). The value may not be changed.що, shopt login_shellздається, це один із способів, коли баш дозволяє дізнатися - програмно, як знати, як це було розпочато. інший спосіб був би[[ -o login ]]
the_velour_fog

11

Як @Serg пояснює в цій відповіді про те , як сказати , що оболонки ви працюєте , то SHELLзмінна тільки поточний користувач по замовчуванням оболонка , як читати /etc/passwd:

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

тож якщо я echo $SHELLце завжди повернеться /bin/bash:

$ zsh
% echo $SHELL
/bin/bash

Будь або не оболонка є Ввійти оболонки, є ш флігель неавтоматичного іонів визначається в момент запуску оболонки. Програма оболонки зберігає цю інформацію разом з усіма іншими її параметрами та змінними. shoptКоманда дає можливість побачити цю інформацію і, якщо це можливо для варіанту в питанні, щоб встановити або скинути його (це не відноситься до login_shellякої, звичайно ж , залежить від процесу , використовуваного для запуску оболонки)

Параметри sudoпрограми визначають, як будуть запускатися ці різні типи кореневої оболонки:

введіть тут опис зображення


1
Гарне пояснення. Я думаю, ви пояснили, що shoptі, login_shellяк передбачається, представляють набагато краще, ніж у моїй відповіді.
Сергій Колодяжний

@ Сергій дякую :) Я думаю, що ваше пояснення є більш ретельним :)
Zanna

3

man bash:

Оболонка входу - це той, чий перший символ нульового аргументу є a -, або той, що розпочався з --loginпараметра.

man login:

Значення $HOME, $SHELL[...] встановлюються в згідно з відповідними полями у записі пароля.

Коротко:

  • Оболонка - це оболонка для входу, якщо її викликали як оболонку для входу.
  • Змінна середовища $SHELLвстановлюється login, наприклад, програмою, що викликає, або su. Сама оболонка її не встановлює.
  • shopt показує чинні параметри оболонки.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.