Я розумію основну відмінність інтерактивної оболонки від неінтерактивної оболонки. Але що саме відрізняє оболонку входу від оболонки, яка не входить у систему?
Чи можете ви навести приклади для використання інтерактивної оболонки без входу ?
Я розумію основну відмінність інтерактивної оболонки від неінтерактивної оболонки. Але що саме відрізняє оболонку входу від оболонки, яка не входить у систему?
Чи можете ви навести приклади для використання інтерактивної оболонки без входу ?
Відповіді:
Оболонка входу - це перший процес, який виконується під вашим ідентифікатором користувача під час входу в інтерактивний сеанс. Процес входу вказує оболонці поводитись як оболонка входу з умовою: передаючи аргумент 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
), але це ризиковано: оболонку можна викликати у всіляких контекстах, і навряд чи можна щось зробити, що може не зробити щось зламати.
† Я трохи спрощую, дивіться посібник про деталі горі.
bash
неінтерактивну оболонку входу?
echo $- | bash -lx
FOO
є змінною середовища (тобто .profile
містить export FOO=something
), то вона доступна для всіх підпроцесів, включаючи foo.sh
. Якщо ви міняєте .profile
на export FOO=something_else
те ./foo.sh
буде по- , як і раніше друкувати something
до наступного разу , коли ви увійти.
Щоб сказати, чи є ви в оболонці для входу:
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 варіант може бути використаний , коли оболонка запускається , щоб пригнічувати таку поведінку. »
У реєстраційній оболонці, argv[0][0] == '-'
. Ось як він знає, що це оболонка для входу.
І тоді в деяких ситуаціях він поводиться по-різному, залежно від статусу "оболонки для входу". Наприклад, оболонка, яка не оболонка для входу, не виконала б команду "вихід".
man bash
, з додаванням акцент, «А Ввійти оболонка, чий перший символ аргументу нуль є -, або один почав з --login варіант. »
Я детально розповім про чудову відповідь Гілла в поєднанні з методом Тімоті для перевірки типу оболонки для входу.
Якщо вам подобається бачити речі для себе, спробуйте фрагменти та сценарії нижче.
Перевірка, чи оболонка є (не) інтерактивною
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 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 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
-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
більше інформації тут .