Я понимаю основное различие между интерактивной оболочкой и неинтерактивной оболочкой. Но что именно отличает оболочку входа в систему от оболочки без регистрации?
Можете ли вы привести примеры использования интерактивной оболочки без регистрации ?
Я понимаю основное различие между интерактивной оболочкой и неинтерактивной оболочкой. Но что именно отличает оболочку входа в систему от оболочки без регистрации?
Можете ли вы привести примеры использования интерактивной оболочки без регистрации ?
Ответы:
Оболочка входа - это первый процесс, который выполняется под вашим идентификатором пользователя при входе в интерактивный сеанс. Процесс входа в систему говорит оболочке вести себя как оболочка входа в систему с условием: передача аргумента 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
до следующего входа в систему.
Чтобы сказать, если вы находитесь в оболочке входа в систему:
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 вариант может быть использован , когда оболочка запускается , чтобы ингибировать такое поведение.»
В оболочке входа в систему 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
switchВы можете явно запросить интерактивную оболочку, если хотите выполнить команду удаленно через ssh с помощью -t
switch.
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
больше информации здесь .