Типы командных оболочек. Инициализация bash - bashrc и bash_profile

Командные оболочки по типам могут рассмартиваться относительно их интерактивности:

  • interactive shell - интерактивный шелл (интерактивная командная оболочка)
  • non-interactive shell - не интерактивный шелл (не интерактивная командная оболочка)

И по наличию полноценного входа в систему:

  • login shell - шелл (командная оболочка) с полноценным авторизованным входом в систему
  • non-login shell - шелл (командная оболочка) без полноценного входа в систему
  1. interactive shell или интерактивная оболочка - это оболочка, в которой пользователь может вводить команды с клавиатуры и получать вывод этих команд на экран.
  2. non-interactive shell или не интерактивная оболочка - это оболочка, которая не позволяет вам вводить команды с клавиатуры в интерактивном режиме. Это могут быть собственные скрипты, или скрипты, запущенные через cron, или это может быть вызов команд через ssh без получения интерактивного шелла.

Отличие интерактивного от не интерактивного

  • Интерактивный шелл имеет возможностью постоянного общения через выбранную оболочку с операционной системой и возможностью выполннения необходимых команд в интерактивном режиме (т.е. с возможностью ожидания ввода с клавиатуры).
  • Не интерактивный вариант шелла используется для выполнения скриптов "в фоне" без участия человеческой руки.
  1. login shell или оболочка со входом в систему - это оболочка, при которой пользователь проходит этап аутентификации и авторизации. То есть, по сути, это первый вход в систему по ssh или через консоль с помощью подключенной клавиатуры. Его можно также назвать сессионным или главным шеллом.

Когда пользователь пытается подключиться к операционной системе, вызывается работа специальной утилиты под названием /bin/login, после успешной проверки аутентификационных данных (например username, password) проводится поиск утилиты, которая должна предоставлять интерфейс взаимодействия с операционной системой. Для этого считываются данные из файла /etc/passwd. Как вы должны помнить из практикума по Linux, в файле /etc/passwd напротив имени пользователя в конце строки будет указан путь к приложению, которое должно запускаться при входе пользователя в операционную систему. Обычно, это наш шелл, например: /bin/bash. Поэтому его и называют login shell. Естественно, это может быть любая утилита, не обязательно шелл (но это уже совсем другая история).

Как вызвать login shell?

  • Оболочка login shell создаётся при каждом новом входе в систему:
    • terminal (терминальный вход)
    • X-11 (графический вход)
  • Оболочка login shell также создаётся при подключении через ssh:
    • ssh root@serverIP
  • оболочка login shell может быть создана явным указанием на вход в систему
    • sudo -i
    • su -
    • su -l
    • su –login
    • su - username
    • su -l username
    • su –login username

Чтобы понять, в какой оболочке вы находитесь, нужно выполнить команду:

  echo $0

Если в выводе будет присутствовать имя оболочки, перед которой стоит дефис (dash), то значит это login shell. Примеры вывода: -bash, -zsh, -csh, -su Если же дефиса (dash) нет, то эта оболочка –> non-login shell

  1. non-login shell или оболочка без входа в систему - это оболочка, которая запускается внутри другой оболочки, пользователь которой уже прошел аутентификацию. К примеру, вы можете запустить второй bash внутри существующей сессии, и он будет non-login interactive shell.К примеру, вы можете запустить второй bash внутри существующей сессии, и он будет non-login interactive shell. Такой non-login shell может быть вызван следующими способами:
  • Вызывая non-login shell из login shell
  • Выполняя скрипты из терминала
  • Используя вызов графических терминалов

В зависимости от того, какой тип шелла используется, система будет вызывать различные скрипты для инициализации пространства (окружения) пользователя.

etc/profile - основной файл для настройки окружения пользователя. Этот файл вызывается только в interactive login shell. Внутри него вызывается проверка используемого шелла и подключается /etc/bash.bashrc в случае использования bash. Помимо этого данный скрипт считывает все файлы из /etc/profile.d/ и поочередно вызывает каждый из них.

/etc/bash.bashrc - как указывалось выше, данный файл будет выполнен скриптом /etc/profile. Но также этот файл будет вызван напрямую при использовании любого типа шелла - interactive / non-interactive / login / non-login.

Единственное, на что стоит обратить внимание, в самом начале этого скрипта встречается конструкция:

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

Данная конструкция проверяет, вызывается ли шелл интерактивно или нет (это первый из способов определения интерактивности - вывод переменной $PS1 не должен быть пустым). Во втором случае обработка будет прервана. Это следует учитывать при добавлении различных переменных для крон скриптов - в не интерактивном шелле они просто не будут применены.

~/.bash_profile - пользовательский файл, который запускается в первую очередь (если существует) при использовании login interactive shell.

~/.profile - локальный пользовательский файл, который не запустится, если существует .bash_profile. Он вызывается только для login shell. Его основная задача - подключить ~/.bashrc, который настроит bash для пользователя.

~/.bash_logout - пользовательский файл, который будет вызван при закрытии login shell пользователем.

~/.bashrc - локальный пользовательский файл, который настраивает рабочее окружение, специфичное для данного пользователя. Если все предыдущие файлы были системными - то есть исполнялись для всех пользователей, то данный файл будет для каждого пользователя различным. В нем также используется конструкция, которая прерывает выполнение в случае использования не интерактивного логин шелла:

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

На заметку! Код выше - это еще один из вариантов проверки наличия интерактивности вашего шелла.

Если посмотреть на это со стороны команд, то выглядеть это будет вот так:

bash
echo $0
bash       
echo $-
himBHs

$- настройки выставленных опций (параметров) вашего bash-шелла. В выводе информации из $-может присутствовать опция -i - interactive, которая покажет, что данный шелл является интерактивным.

*interactive login shell**

  • LOGIN вызывает /etc/profile
  • → /etc/profile вызывает /etc/bash.bashrc
  • → /etc/profile последовательно вызывает cкрипты в /etc/profile.d/
  • → LOGIN вызывает ~/.bash_profile . Если его нет, то вызывает ~/.profile
  • → ~/.bash_profile или ~/.profile вызывает ~/.bashrc
  • → ~/.bashrc вызывает ~/.bash_aliases

В zsh опций гораздо больше, но -i тоже присутствует:

echo $0
-zsh
 
echo $-                                                                   
569JNRXZghikms

~/.bash_profile - пользовательский файл, который запускается в первую очередь (если существует) при использовании login interactive shell. ~/.profile - локальный пользовательский файл, который не запустится, если существует .bash_profile. Он вызывается только для login shell. Его основная задача - подключить ~/.bashrc, который настроит bash для пользователя. ~/.bash_logout - пользовательский файл, который будет вызван при закрытии login shell пользователем.

Теперь конкретно по последовательности вызова скриптов процессом, предоставляющим доступ к системе (назовем его LOGIN). Для interactive login shell:

interactive login shell

  1. → LOGIN вызывает /etc/profile
  2. → /etc/profile вызывает /etc/bash.bashrc
  3. → /etc/profile последовательно вызывает cкрипты в /etc/profile.d/
  4. → LOGIN вызывает ~/.bash_profile . Если его нет, то вызывает ~/.profile
  5. → ~/.bash_profile или ~/.profile вызывает ~/.bashrc
  6. → ~/.bashrc вызывает ~/.bash_aliases

interactive non-login shell

Для interactive non-login shell схема по проще, ввиду того, что осуществлять вход в систему ненужно, поэтому запускающий процесс будем называть shell:

  1. → shell вызывает /etc/bash.bashrc
  2. → shell вызывает ~/.bashrc
  3. → ~/.bashrc вызывает ~/.bash_aliases

Для non-interactive non-login shell схема такая же, как и для interactive non-login shell, но есть один нюанс, в файлах /etc/bash.bashrc и ~/.bashrc нужно убрать ограничение [ -z "$PS1" ] && return. Это можно осуществить через комментарий или просто удалив строку:

  # If not running interactively, don't do anything
  # [ -z "$PS1" ] && return

Ну или указывать то, что вы хотели бы выполнить, до объявления вышеуказанного блока.