Разница между Оболочкой входа в систему и Оболочкой без регистрации?
318
Я понимаю основное различие между интерактивной оболочкой и неинтерактивной оболочкой. Но что именно отличает оболочку входа в систему от оболочки без регистрации?
Можете ли вы привести примеры использования интерактивной оболочки без регистрации ?
Я думаю, что вопрос лучше сформулировать так: « Почему / мы должны заботиться о том, чтобы различать входящие и не входящие в систему оболочки?» Многие места в сети уже говорят нам, в чем различия, с точки зрения того, какие файлы запуска каждый из них читает; но никто из них, кажется, не отвечает «почему» удовлетворительным и убедительным образом. Пример использования, когда вы определенно не хотите, чтобы одно или другое поведение было бы замечательно.
Оболочка входа - это первый процесс, который выполняется под вашим идентификатором пользователя при входе в интерактивный сеанс. Процесс входа в систему говорит оболочке вести себя как оболочка входа в систему с условием: передача аргумента 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, таких как dash, ksh и bash, при вызове как sh, $ENVесли установлено и ~/.mkshrcдля мкш и т. д.).
Когда оболочка запускает сценарий или команду, переданную в командной строке, это неинтерактивная оболочка , не входящая в систему . Такие оболочки работают постоянно: очень часто, когда программа вызывает другую программу, она действительно запускает крошечный скрипт в оболочке для вызова этой другой программы. Некоторые оболочки читают файл запуска в этом случае (bash запускает файл, указанный в BASH_ENVпеременной, zsh запускает /etc/zshenvи ~/.zshenv), но это опасно: оболочку можно вызывать во всех видах контекстов, и вряд ли можно что-то сделать, что может не сломать что-нибудь.
† Я немного упрощаю, подробности смотрите в руководстве.
Не могли бы вы привести пример работы 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.
Важность использования оболочки входа в систему заключается в том, что любые настройки /home/user/.bash_profileбудут выполнены. Вот немного больше информации, если вы заинтересованы (от man bash)
«Когда bash вызывается как интерактивная оболочка входа в систему или как неинтерактивная оболочка с параметром --login, она сначала читает и выполняет команды из файла / etc / profile, если этот файл существует. После прочтения этого файла он ищет ~/.bash_profile,
~/.bash_loginи ~/.profile, в таком порядке, и считывает и выполняет команды из первого , который существует и может быть прочитан. --noprofile вариант может быть использован , когда оболочка запускается , чтобы ингибировать такое поведение.»
В оболочке входа в систему argv[0][0] == '-'. Вот как он знает, что это оболочка входа в систему.
И затем, в некоторых ситуациях, он ведет себя по-разному в зависимости от статуса «оболочки входа». Например, оболочка, которая не является оболочкой входа в систему, не будет выполнять команду выхода из системы.
В соответствии man bashс добавлением акцента: «Оболочка входа - это та, чей первый символ нулевого аргумента - -, или тот, который начинается с опции --login ».
Wildcard
18
Оболочка, запущенная в новом терминале в графическом интерфейсе, будет интерактивной оболочкой без авторизации. Это будет источник вашего .bashrc, но не ваш .profile, например.
Я подробно остановлюсь на великолепном ответе Жиля в сочетании с методом Тимоти для проверки типа оболочки входа в систему.
Если вы хотите увидеть вещи сами, попробуйте приведенные ниже фрагменты и сценарии.
Проверка, является ли оболочка (не) интерактивной
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;
Давайте объединим два приведенных выше вместе, чтобы получить обе части информации одновременно:
ssh ubuntu@34.247.105.87Welcome to Ubuntu16.04.5 LTS (GNU/Linux4.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 Ubuntu16.04.5 LTS (GNU/Linux4.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 удаленно с помощью -tswitch
Вы можете явно запросить интерактивную оболочку, если хотите выполнить команду удаленно через ssh с помощью -tswitch.
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больше информации здесь .
Ответы:
Оболочка входа - это первый процесс, который выполняется под вашим идентификатором пользователя при входе в интерактивный сеанс. Процесс входа в систему говорит оболочке вести себя как оболочка входа в систему с условием: передача аргумента 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, таких как dash, 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
до следующего входа в систему.Чтобы сказать, если вы находитесь в оболочке входа в систему:
В Bash вы также можете использовать
shopt login_shell
:(или
on
в оболочке входа в систему).Информацию можно найти в
man bash
(поиск Invocation). Вот выдержка:Вы можете проверить это сами. Каждый раз, когда вы используете SSH, вы используете оболочку входа. Например:
Важность использования оболочки входа в систему заключается в том, что любые настройки
/home/user/.bash_profile
будут выполнены. Вот немного больше информации, если вы заинтересованы (отman bash
)источник
В оболочке входа в систему
argv[0][0] == '-'
. Вот как он знает, что это оболочка входа в систему.И затем, в некоторых ситуациях, он ведет себя по-разному в зависимости от статуса «оболочки входа». Например, оболочка, которая не является оболочкой входа в систему, не будет выполнять команду выхода из системы.
источник
man bash
с добавлением акцента: «Оболочка входа - это та, чей первый символ нулевого аргумента - -, или тот, который начинается с опции --login ».Оболочка, запущенная в новом терминале в графическом интерфейсе, будет интерактивной оболочкой без авторизации. Это будет источник вашего .bashrc, но не ваш .profile, например.
источник
Я подробно остановлюсь на великолепном ответе Жиля в сочетании с методом Тимоти для проверки типа оболочки входа в систему.
Если вы хотите увидеть вещи сами, попробуйте приведенные ниже фрагменты и сценарии.
Проверка, является ли оболочка (не) интерактивной
Проверка, является ли оболочка (не) логином
Если вывод команды
echo $0
начинается с-
, это оболочка входа в систему (echo $0
пример вывода:)-bash
. В противном случае это не входящая в систему оболочка (echo $0
пример вывода:)bash
.Давайте объединим два приведенных выше вместе, чтобы получить обе части информации одновременно:
Сценарии:
Типичная сессия SSH без специальных опций
Запуск сценария или выполнение явно через новую оболочку
Запуск локального скрипта удаленно
Запуск команды через ssh удаленно
Запуск команды через ssh удаленно с помощью
-t
switchВы можете явно запросить интерактивную оболочку, если хотите выполнить команду удаленно через ssh с помощью
-t
switch.Примечание: На тему почему работает команда удаленно не
login shell
больше информации здесь .источник