Різниця між оболонкою для входу та оболонкою без входу?


318

Я розумію основну відмінність інтерактивної оболонки від неінтерактивної оболонки. Але що саме відрізняє оболонку входу від оболонки, яка не входить у систему?

Чи можете ви навести приклади для використання інтерактивної оболонки без входу ?


45
Я думаю, що питання краще формулювати як " Чому ми повинні піклуватися про диференціацію оболонок для входу та не входу в систему?" У багатьох місцях в Інтернеті вже йдеться про те, які відмінності стосуються того, які файли запуску кожен читає; але, здається, жодна з них не відповідає на "чому" задовільно і переконливо. На прикладі використання випадків, коли ви точно не хочете того чи іншого поведінки, було б чудово.
Кал

2
@Kal Це має бути іншим питанням, оскільки жодна відповідь тут насправді не охоплює цього. Редагувати: Насправді, ось що: ЧОМУ оболонку для входу над оболонкою без входу ? .
Skippy le Grand Gourou

Відповіді:


304

Оболонка входу - це перший процес, який виконується під вашим ідентифікатором користувача під час входу в інтерактивний сеанс. Процес входу вказує оболонці поводитись як оболонка входу з умовою: передаючи аргумент 0, який, як правило, є ім'ям виконавчого файлу оболонки, із -символом, який попередньо (наприклад, -bashтоді як це зазвичай було bash. Оболонки входу зазвичай читають файл, який робить такі речі, як встановлення змінних середовища: /etc/profileі ~/.profileдля традиційної оболонки Bourne, ~/.bash_profileдодатково для bash , /etc/zprofileі ~/.zprofileдля zsh , /etc/csh.loginі ~/.loginдля csh тощо.

Коли ви входите на текстову консоль, або через SSH, або за допомогою su -, ви отримуєте інтерактивну оболонку входу . Коли ви входите в графічний режим (у диспетчері X-дисплея ), ви не отримуєте оболонки для входу, натомість отримуєте менеджер сеансів або менеджер вікон.

Рідко можна запустити неінтерактивну оболонку входу , але деякі параметри X роблять це під час входу в Менеджер дисплеїв, щоб організувати читання файлів профілю. Інші параметри (це залежить від розподілу та диспетчера дисплеїв) читайте /etc/profileта ~/.profileявно, або не читайте їх. Інший спосіб отримати неінтерактивну оболонку входу - це дистанційний вхід в систему за допомогою команди, переданої через стандартний вхід, який не є терміналом, наприклад ssh example.com <my-script-which-is-stored-locally(на відміну від ssh example.com my-script-which-is-on-the-remote-machine, який запускає неінтерактивну оболонку, що не входить в систему).

Коли ви запускаєте оболонку в терміналі в існуючому сеансі (екран, X-термінал, термінальний буфер Emacs, оболонка всередині іншого тощо), ви отримуєте інтерактивну оболонку , яка не входить у систему . Ця оболонка може прочитати файл конфігурації оболонки ( ~/.bashrcдля bash, який викликається як bash, /etc/zshrcі ~/.zshrcдля zsh, /etc/csh.cshrcі ~/.cshrcдля csh, файл, зазначений ENVзмінною для оболонок, сумісних з POSIX / XSI, таких як тире, ksh та bash, коли викликається як sh, $ENVякщо встановлено і ~/.mkshrcдля мкш тощо).

Коли оболонка запускає скрипт або команду, передану в її командному рядку, це неінтерактивна оболонка , яка не входить у систему . Такі оболонки працюють постійно: дуже часто, коли програма викликає іншу програму, вона справді запускає крихітний сценарій в оболонці, щоб викликати цю іншу програму. Деякі оболонки читають файл запуску в цьому випадку (bash запускає файл, позначений BASH_ENVзмінною, zsh запускається /etc/zshenvта ~/.zshenv), але це ризиковано: оболонку можна викликати у всіляких контекстах, і навряд чи можна щось зробити, що може не зробити щось зламати.

Я трохи спрощую, дивіться посібник про деталі горі.


2
Чи можете ви навести приклад, як запустити bashнеінтерактивну оболонку входу?
Пьотр Доброгост

13
@PiotrDobrogostecho $- | bash -lx
Жиль

1
Я не знаю, чи це правда в цілому, але я хочу зазначити, що коли я відкриваю новий термінал (на OSX за допомогою налаштувань за замовчуванням), я отримую оболонку входу, хоча я ніколи не ввожу своє ім’я користувача або пароль.
Кевін Вілер

4
@KevinWheeler У OSX за замовчуванням програма Terminal запускає оболонку входу. (Як я пояснюю, програма, яка запускає оболонку, вирішує, чи діє оболонка як оболонка для входу.) Це не звичайний спосіб робити.
Жиль

2
@IAmJulianAcosta Якщо FOOє змінною середовища (тобто .profileмістить export FOO=something), то вона доступна для всіх підпроцесів, включаючи foo.sh. Якщо ви міняєте .profileна export FOO=something_elseте ./foo.shбуде по- , як і раніше друкувати somethingдо наступного разу , коли ви увійти.
Жиль

48

Щоб сказати, чи є ви в оболонці для входу:

prompt> echo $0
-bash # "-" is the first character. Therefore, this is a login shell.

prompt> echo $0
bash # "-" is NOT the first character. This is NOT a login shell.

У Bash ви також можете використовувати shopt login_shell:

prompt> shopt login_shell
login_shell     off

(або onв оболонці для входу).

Інформацію можна знайти в man bash(пошук виклику). Ось уривок:

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

Ви можете перевірити це самостійно. Щоразу, коли ви SSH, ви використовуєте оболонку для входу. Наприклад:

prompt> ssh user@localhost
user@localhost's password:
prompt> echo $0
-bash

Важливість використання оболонки для входу полягає в тому, що будь-які параметри в системі /home/user/.bash_profileбудуть виконані. Ось трохи більше інформації, якщо вас цікавить (від man bash)

"Коли bash викликається як інтерактивна оболонка для входу або як неінтерактивна оболонка з опцією --login, вона спочатку зчитує та виконує команди з файлу / etc / profile, якщо цей файл існує. Після прочитання цього файлу він шукає ~/.bash_profile, ~/.bash_loginі ~/.profile, в такому порядку, і зчитує і виконує команди з першого , який існує і може бути прочитаний. --noprofile варіант може бути використаний , коли оболонка запускається , щоб пригнічувати таку поведінку. »


23

У реєстраційній оболонці, argv[0][0] == '-'. Ось як він знає, що це оболонка для входу.

І тоді в деяких ситуаціях він поводиться по-різному, залежно від статусу "оболонки для входу". Наприклад, оболонка, яка не оболонка для входу, не виконала б команду "вихід".


4
Згідно man bash, з додаванням акцент, «А Ввійти оболонка, чий перший символ аргументу нуль є -, або один почав з --login варіант. »
Джокер

18

Оболонка, запущена в новому терміналі GUI, була б інтерактивною оболонкою без входу. Це, наприклад, джерело вашого .bashrc, але не ваш .profile.


4

Я детально розповім про чудову відповідь Гілла в поєднанні з методом Тімоті для перевірки типу оболонки для входу.

Якщо вам подобається бачити речі для себе, спробуйте фрагменти та сценарії нижче.

Перевірка, чи оболонка є (не) інтерактивною

if tty -s; then echo 'This is interactive shell.'; else echo 'This is non-interactive shell.'; fi

Перевірка, чи оболонка (не) вхід

Якщо вихід echo $0починається з -, це оболонка входу ( echo $0приклад виводу:) -bash. Інакше це оболонка без входу ( echo $0вихідний приклад bash:).

if echo $0 | grep -e ^\- 2>&1>/dev/null; then echo "This is login shell."; else echo "This is non-login shell."; fi;

Давайте поєднаємо два вище, щоб отримати обидві відомості одразу:

THIS_SHELL_INTERACTIVE_TYPE='non-interactive'; 
THIS_SHELL_LOGIN_TYPE='non-login'; 
if tty -s; then THIS_SHELL_INTERACTIVE_TYPE='interactive'; fi; 
if echo $0 | grep -e ^\- 2>&1>/dev/null; then THIS_SHELL_LOGIN_TYPE='login'; fi;
echo "$THIS_SHELL_INTERACTIVE_TYPE/$THIS_SHELL_LOGIN_TYPE"

Сценарії:

Типовий сеанс SSH без спеціальних опцій

ssh ubuntu@34.247.105.87
Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.4.0-1083-aws x86_64)

ubuntu@ip-172-31-0-70:~$ THIS_SHELL_INTERACTIVE_TYPE='non-interactive';
ubuntu@ip-172-31-0-70:~$ THIS_SHELL_LOGIN_TYPE='non-login';
ubuntu@ip-172-31-0-70:~$ if tty -s; then THIS_SHELL_INTERACTIVE_TYPE='interactive'; fi;
ubuntu@ip-172-31-0-70:~$ if echo $0 | grep -e ^\- 2>&1>/dev/null; then THIS_SHELL_LOGIN_TYPE='login'; fi;
ubuntu@ip-172-31-0-70:~$ echo "$THIS_SHELL_INTERACTIVE_TYPE/$THIS_SHELL_LOGIN_TYPE"

interactive/login

Запуск сценарію або виконання явно через нову оболонку

ubuntu@ip-172-31-0-70:~$  bash -c 'THIS_SHELL_INTERACTIVE_TYPE='non-interactive'; THIS_SHELL_LOGIN_TYPE='non-login'; if tty -s; then THIS_SHELL_INTERACTIVE_TYPE='interactive'; fi; if echo $0 | grep -e ^\- 2>&1>/dev/null; then THIS_SHELL_LOGIN_TYPE='login'; fi; 
echo "$THIS_SHELL_INTERACTIVE_TYPE/$THIS_SHELL_LOGIN_TYPE"'

interactive/non-login

Запуск локального сценарію віддалено

ssh ubuntu@34.247.105.87 < checkmy.sh
Pseudo-terminal will not be allocated because stdin is not a terminal.
Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.4.0-1083-aws x86_64)

non-interactive/login

Запуск команди над ssh віддалено

ssh ubuntu@34.247.105.87 'THIS_SHELL_INTERACTIVE_TYPE='non-interactive'; THIS_SHELL_LOGIN_TYPE='non-login'; if tty -s; then THIS_SHELL_INTERACTIVE_TYPE='interactive'; fi; if echo $0 | grep -e ^\- 2>&1>/dev/null; then THIS_SHELL_LOGIN_TYPE='login'; fi; echo "$THIS_SHELL_INTERACTIVE_TYPE/$THIS_SHELL_LOGIN_TYPE"'

non-interactive/non-login

Запуск команди над ssh віддалено за допомогою -tперемикача

Ви можете явно вимагати інтерактивної оболонки, коли ви хочете віддалено запускати команду через ssh, використовуючи -tперемикач.

ssh ubuntu@34.247.105.87 -t 'THIS_SHELL_INTERACTIVE_TYPE='non-interactive'; THIS_SHELL_LOGIN_TYPE='non-login'; if tty -s; then THIS_SHELL_INTERACTIVE_TYPE='interactive'; fi; if echo $0 | grep -e ^\- 2>&1>/dev/null; then THIS_SHELL_LOGIN_TYPE='login'; fi; echo "$THIS_SHELL_INTERACTIVE_TYPE/$THIS_SHELL_LOGIN_TYPE"'

interactive/non-login

Примітка: На тему чому працює команда видалення не login shellбільше інформації тут .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.