Страницы

Поиск по вопросам

пятница, 9 ноября 2018 г.

Unix: как происходит инициализация переменных окружения при запуске shell-а?

Как это происходит? Откуда берутся строчки var=val? Откуда char** environ? Что происходит при инициализации shell?
Можно просто ответить: "Из системных файлов конфигурации". Я спрошу: "Из каких?" В /etc/profile определены лишь некоторые из них, как и в /etc/bash.bashrc, ~/.bashrc (~/.kshrc, ~/.zshrc). Оболочка сама определяет значение переменных, исходя из настроек системы? К примеру, делает вызов ulimit, locale и прочие, а USER, HOME, etc парсятся из /etc/passwd. Эти догадки верны?
Аспекты работы оболочки для меня не совсем очевидны, из мануалов интересующую информацию вычитать не удалось, как и узнать у google.


Ответ

Окружение - неотъемлемая часть всех процессов Unix и как известно, окружение наследуется от вызывающего процесса всеми его потомками. Потомки могут что то поменять в своей копии окружения, добавить, удалить и запустить своих потомков передав им свое, измененное окружение. Поэтому что бы понять, что формирует окружение любого запущенного процесса цепочку запуска надо рассмотреть с самого начала.
И так, Unix система начинает запуск. Загружается ядро. Ядро стартует "процесс номер 1", обычно /sbin/init. А уже init стартует все остальные процессы в системе (см. /etc/inittab). Смотрим исходный код /sbin/init (на примере sysVinit, который используется linux). Сразу находится функция init_buildenv - она создает первоначальное окружение для всех процессов в системе.
Окружение формируемое /sbin/init: RUNLEVEL PREVLEVEL SHELL=/bin/sh CONSOLE INIT_VERSION
Далее init запускает стартер системы (для linux обычно /sbin/rc), который выполняет загрузку демонов, он формирует начальное окружение с которым работают демоны. Кроме того init стартует поддержку терминалов (в linux обычно agetty), который ставит переменную TERM. Для сетевых подключений TERM по идее должен поставить sshd или другое средство подключения. Те в свою очередь запускают /bin/login или сами выполняют его работу. Вот он, авторизовав пользователя, смотрит /etc/passwd и формирует начальное окружение данного пользователя (добавляет к тому, что сделал init):
Окружение формируемое /bin/login HOME SHELL USER LOGNAME LANG TZ HZ PATH (см. /etc/login.defs) MAIL (см. /etc/login.defs) если в /etc/login.defs указан ENVIRONFILE - то добавляется его содержимое
Наконец login запускает shell определенный для данного пользователя. Разных shell довольно много и каждый по своему работает с окружением. От себя лично они добавляют мало, зато львиную долю окружения читают из файлов. Надо смотреть исходники каждого shell, что бы понять, кто что грузит. Для zsh примерный перечень такой:
/etc/profile ~/.profile ИЛИ /etc/suid_profile (проверяет привилегии) /etc/zshenv (если включен при сборке zsh) ~/.zshenv /etc/zprofile (если включен при сборке zsh) /etc/zshrc (если включен при сборке zsh) ~/.zshrc /etc/zlogin (если включен при сборке zsh) ~/.zlogin
Кроме того в окружение что то могут добавлять другие процессы, используемые при входе пользователя. sshd добавляет свои переменные, модули PAM, используемые при авторизации так же могут это делать.

Комментариев нет:

Отправить комментарий