Разница между Оболочкой входа в систему и Оболочкой без регистрации?

318

Я понимаю основное различие между интерактивной оболочкой и неинтерактивной оболочкой. Но что именно отличает оболочку входа в систему от оболочки без регистрации?

Можете ли вы привести примеры использования интерактивной оболочки без регистрации ?

Igorio
источник
45
Я думаю, что вопрос лучше сформулировать так: « Почему / мы должны заботиться о том, чтобы различать входящие и не входящие в систему оболочки?» Многие места в сети уже говорят нам, в чем различия, с точки зрения того, какие файлы запуска каждый из них читает; но никто из них, кажется, не отвечает «почему» удовлетворительным и убедительным образом. Пример использования, когда вы определенно не хотите, чтобы одно или другое поведение было бы замечательно.
Кал
2
@Kal Это должен быть другой вопрос, так как здесь нет ответа на этот вопрос. Редактировать: На самом деле, вот оно: ПОЧЕМУ оболочка входа через оболочку без входа в систему ? ,
Скиппи ле Гран Гуру

Ответы:

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, таких как dash, 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(поиск Invocation). Вот выдержка:

Оболочка входа - это та, чей первый символ аргумента ноль - -, или тот, который начинается с опции --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] == '-'. Вот как он знает, что это оболочка входа в систему.

И затем, в некоторых ситуациях, он ведет себя по-разному в зависимости от статуса «оболочки входа». Например, оболочка, которая не является оболочкой входа в систему, не будет выполнять команду выхода из системы.

BOPOHOK
источник
4
В соответствии man bashс добавлением акцента: «Оболочка входа - это та, чей первый символ нулевого аргумента - -, или тот, который начинается с опции --login ».
Wildcard
18

Оболочка, запущенная в новом терминале в графическом интерфейсе, будет интерактивной оболочкой без авторизации. Это будет источник вашего .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 удаленно с помощью -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больше информации здесь .

Патрик Стас
источник