Статьи

Понимание * NIX сценариев входа

Сталкивались ли вы когда-нибудь со сценарием, в котором вам нужно было установить переменную среды или запустить программу для изменения вашей оболочки или среды рабочего стола, но вы не знали, откуда лучше ее вызывать?

Это обычная ситуация. Многие задачи требуют, чтобы переменные среды работали правильно, от запуска утилит упаковки Debian до управления IaaS и всего, что между ними.

Иногда программа обычно запускается только один раз при первом входе в систему, например команда xrandr . Кроме того, программы иногда ожидают внедрения в оболочку, например, rbenv , rvm или собственную утилиту envswitch SitePoint.

Эти настройки не должны быть загружены из любого места. Иногда существует ряд факторов, которые следует учитывать, прежде чем принимать решение о лучшем месте.

Давайте посмотрим на некоторые распространенные параметры, присутствующие в установке Debian GNU / Linux Jessie, и попробуем разобраться во всем этом.

/ И т.д. / профиль

По умолчанию Debian предоставляет /etc/profile , который сразу же используется для установки $PATH (используется для объявления путей поиска команд).

 if [ "`id -u`" -eq 0 ]; then PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" else PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games" fi export PATH 

Для удобства пользователь root (идентификатор пользователя 0) получает разные пути, определенные для всех остальных. Это потому, что системные двоичные (sbin) местоположения идеально зарезервированы для системного администрирования или программ, которые должны запускаться от имени пользователя root. Пути игры для root опущены, потому что вы никогда не должны запускать программы от имени пользователя root, если это не является абсолютно необходимым.

Затем /etc/profile обрабатывает настройку $PS1 , которая используется для установки основной строки приглашения. Определены значения по умолчанию: '$ ' (или '#' для root), если оболочкой не является Bash. Если оболочкой является Bash, то /etc/bash.bashrc используется /etc/bash.bashrc (помимо всего прочего). Мы поговорим о /etc/bash.bashrc ближайшее время.

Таким образом, на этом этапе мы можем сделать вывод, что /etc/profile читается всеми оболочками во время входа в систему (т. Е. С помощью команды login). Вместо того, чтобы использовать более эффективную встроенную переменную Bash ${UID} для определения идентификатора пользователя, вместо этого /etc/profile вызывает команду id для этого. Вместо определения необычного приглашения оболочки была создана специфическая для Bash конфигурация, поскольку Bash поддерживает экранированные обратным слешем специальные символы, такие как \u (имя пользователя) и \h (имя хоста), чего не было бы во многих других оболочках. /etc/profile должен стараться быть POSIX-совместимым, чтобы быть совместимым с любой оболочкой, которую пользователь может установить для себя.

Debian GNU / Linux часто поставляется с предустановленной Dash, базовой оболочкой, предназначенной только для реализации расширений POSIX (и некоторых Berkeley). Если мы изменим / etc / profile (сначала создадим резервную копию!), Чтобы строка PS1='$ ' установила другое значение и смоделировала вход в Dash (с помощью команды dash -l ), мы увидим, что Dash использует подсказку, которую мы определили , Однако, если мы вместо этого вызываем команду dash без аргумента -l , /etc/profile не читается, и Dash возвращается к значению по умолчанию (которое, кстати, является тем, что было первоначальным значением PS1 до того, как мы его изменили).

Последнее, что следует отметить в /etc/profile это следующий фрагмент кода в конце:

 if [ -d /etc/profile.d ]; then for i in /etc/profile.d/*.sh; do if [ -r $i ]; then . $i fi done unset i fi 

Другими словами, все читаемое /etc/profile.d/*.sh соответствующее /etc/profile.d/*.sh получено из источника. Это важно, потому что это указывает на то, что редактирование /etc/profile напрямую никогда не требуется (поэтому восстановите резервную копию, сделанную ранее!). Любые переменные, определенные выше, могут быть переопределены в отдельном файле. Одним из преимуществ этого является то, что он позволяет системным обновлениям автоматически добавлять изменения в /etc/profile , поскольку система управления пакетами Debian Apt обычно не затрагивает измененные файлы конфигурации.

~ / .bash_profile, ~ / .bash_login и ~ / .profile

Одна потенциальная проблема с /etc/profile заключается в том, что он находится в общесистемном пути. Это означает, что изменения там затрагивают всех пользователей в системе. На персональном компьютере это может показаться не большой проблемой, но для его изменения требуются права суперпользователя. По этим причинам каждая отдельная учетная запись пользователя Bash может создать один из файлов ~/.bash_profile , ~/.bash_login или ~/.profile для поиска — и первый найденный файл (ищется в указанном порядке) используется, пока любой остальные файлы игнорируются. Другие оболочки, такие как Dash, поддерживают нечто подобное, но смотрят только на ~/.profile . Это позволяет пользователю создавать файл .bash_profile для ситуаций, специфичных для Bash, и, если он иногда переключается на Dash или какую-либо другую оболочку в качестве своей оболочки входа в систему (например, с помощью команды chsh -s dash), ~/.profile может быть зарезервирован для этот вариант использования.

Нужно помнить важность этого. Стандартный каталог Debian ( /etc/skel , используемый для размещения файлов и каталогов, которые будут скопированы в домашние каталоги новых учетных записей пользователей) включает в себя файл .profile , но не файл .bash_profile или .bash_login . Кроме того, Debian использует Bash в качестве пользовательской оболочки по умолчанию. Поэтому многие пользователи привыкли помещать свои настройки оболочки входа в Bash в .profile .

Я видел инструкции по установке для таких проектов, как RVM, которые инструктируют пользователя создавать файл .bash_profile , но это опасно, так как это может нарушить среду оболочки пользователя! Даже если пользователь не .profile , он может воспользоваться преимуществами функции ~/.profile по умолчанию, которая добавляет ~/bin к $PATH среды $PATH . Это больше не будет работать. Одним из вариантов, который может повысить безопасность, является добавление .bash_profile в качестве символической ссылки на .bashrc в /etc/skel перед созданием учетных записей пользователей.

Если мы посмотрим на сценарий Debian Jessie по умолчанию .profile , то увидим следующий фрагмент:

 # if running bash if [ -n "$BASH_VERSION" ]; then # include .bashrc if it exists if [ -f "$HOME/.bashrc" ]; then . "$HOME/.bashrc" fi fi 

Это похоже на то, что мы видели в /etc/profile , где /etc/bash.bashrc получен, если найден, а оболочка — Bash. Значение этого обсуждается в следующем разделе.

/etc/bash.bashrc и ~ / .bashrc

При запуске Bash будет читать и /etc/bash.bashrc и ~/.bashrc , в указанном порядке, но только если он запускается как интерактивная оболочка, которая не является оболочкой входа в систему (что обычно подразумевается при запуске через xterm). Это стандартное поведение для оболочки Bash. Однако Debian получает эти файлы из сценариев входа в систему /etc/profile и ~/.profile соответственно. Это эффективно изменяет поведение так, что /etc/bash.bashrc и .bashrc (если они существуют) всегда вызываются при запуске оболочки Bash, независимо от того, является ли она оболочкой входа в систему или нет. Не рассчитывайте, что это поведение одинаково в разных дистрибутивах.

.bashrc — отличное место для добавления псевдонимов команд. На самом деле, некоторые люди имеют так много псевдонимов, что предпочитают хранить их в отдельном файле. По умолчанию Debian .bashrc ищет ~/.bash_aliases и ~/.bash_aliases его, если файл существует, поэтому не стесняйтесь хранить все ваши псевдонимы Bash. .bashrc также является лучшим местом для пользователя, чтобы переопределить переменные оболочки, такие как $PS1 или $HISTSIZE (количество сохраняемой истории команд), если он хочет. По умолчанию Debian .bashrc имеет длину более 100 строк, но он довольно прост для чтения и хорошо прокомментирован. Как следует из названия, не ожидается, что .bashrc будет получен не-Bash-оболочками.

~ / .xsession и ~ / .xsessionrc

Если вы пользователь рабочего стола GNU / Linux, который входит в систему локально через менеджер отображения (в отличие от программы входа через getty), нельзя ожидать , что /etc/profile и ~/.profile будут работать . Некоторые дисплеи диспетчера ошибочно исходят из этих файлов напрямую — например, Диспетчер дисплеев Gnome — но другие DM, такие как LightDM, этого не делают. К счастью, у вас есть другие варианты.

Когда начинается сеанс X Window System (независимо от использования диспетчера отображения или startx из виртуального терминала), будет выполнен сценарий оболочки /etc/X11/Xsession . По сути, это эквивалентно /etc/profile используемому оболочками для входа в систему, только для X и не из источника, а из непосредственного выполнения. Это также значительно сложнее. Аналогично тому, как /etc/profile читает в сценариях из /etc/profile.d , /etc/X11/Xsession исходные сценарии /etc/X11/Xsession в /etc/X11/Xsession.d . Все скрипты в этом каталоге начинаются с цифры, поэтому скрипты будут загружаться в порядке нумерации.

Debian Jessie включает в себя файл с именем 40x11-common_xsessionrc . Все, что он делает, это проверяет, является ли ~/.xsessionrc читабельным, и (если да) получает его. Это делает ~/.xsessionrc идеальным местом для загрузки переменных среды или запуска разовых утилит при запуске (таких как xrandr или xmodmap ), которые применяются только к сеансам X. Вы также можете использовать это в качестве источника /etc/profile и ~/.profile если хотите, поэтому любые переменные среды, указанные там, будут также унаследованы вашим менеджером сеансов (если они еще не были). Обратите внимание, что .xsessionrc не существует по умолчанию, поэтому вы должны его создать.

Если мы продолжим просматривать файлы в /etc/X11/Xsession , мы найдем 50x11-common_determine-startup который определяет менеджер сеанса
нагрузить. Если файл ~/.xsession существует и является исполняемым, он будет сохранен и выполнен позже как часть 99x11-common_start . Поскольку ~/.xsession предназначен для запуска диспетчера сеансов, сеанс X выйдет из системы, и вы ~/.xsession к экрану входа диспетчера дисплеев, когда этот скрипт завершится.

Как и ~/.xsessionrc , ~/.xsession не существует по умолчанию, поэтому вы должны создать его, если хотите. Вы можете создать простой скрипт .xsession который выглядит следующим образом:

 # Start our session manager of choice. # exec x-session-manager 

где x-session-manager умолчанию настроен на команду update-alternatives . Таким образом, вы можете легко изменить менеджер сеансов в сторону от общесистемного по умолчанию, просто заменив x-session-manager скажем, /usr/bin/startxfce4 (для переключения на XFCE), и другие учетные записи пользователей останутся полностью незатронутыми ,

Конечно, многие диспетчера отображения предоставляют возможность выбирать общие диспетчера сеансов непосредственно на экране входа в систему, поэтому этот файл часто не требуется. Однако .xsession обеспечивает большую гибкость, и здесь вы можете вызывать любую программу, а не только менеджеры сеансов. Например, вы можете вместо этого вызвать chromium или iceweasel в цикле while, чтобы реализовать базовую настройку в режиме киоска.

~ / .Bash_logout

Ранее мы рассмотрели файлы, которые читаются, когда пользователь запускает интерактивную оболочку входа в систему Bash, но что если вы захотите запустить программу при выходе из системы? Для этого ~/.bash_logout использования ~/.bash_logout — ваш друг. Значение по умолчанию, включенное в Debian, используется только для очистки экрана (что я считаю важным с точки зрения безопасности), но с небольшим воображением может быть использовано для других целей — например, для отображения напоминания в течение нескольких секунд перед вами. отойди от машины.

Основным ограничивающим фактором является то, что .bash_logout читается только при выходе из интерактивной оболочки, и нельзя предполагать, что он будет загружен при выходе из X-сессии.

Другие опции

Это касается наиболее распространенных вариантов, доступных для вас. В зависимости от вашей установки могут существовать другие варианты (например, /etc/environment ), но я не считаю, что они могут существовать на других платформах, и им редко приходилось их трогать.

Примеры

Итак, где вы должны разместить общесистемные переменные среды? Если вы хотите, чтобы переменная окружения влияла на каждого пользователя, лучше всего /etc/profile.d/somefile.sh . Однако это предполагает, что вы используете менеджер входа в систему, который использует /etc/profile . Если нет, вы можете (как администратор) вместо этого добавить скрипт в /etc/X11/Xsession.d/ в исходный /etc/X11/Xsession.d/ /etc/profile .

Если вы хотите, чтобы скрипт находил местоположение личного каталога и добавлял его в вашу переменную PATH, вам следует подумать о том, будет ли каталог часто перемещаться. Если вы добавите код для этого в .profile , пользователь должен будет выйти и снова войти, чтобы PATH отражал изменение каталога во время сеанса пользователя. Если вы вместо этого добавили код в .bashrc , это означает, что код будет выполняться каждый раз, когда пользователь открывает xterm — что, вероятно, не идеально, если для его выполнения требуется более полсекунды или около того. Так что это вопрос взвешивания компромиссов.

Что если вы хотите, чтобы переменная окружения была только для ваших личных сеансов входа? Если это касается только сеансов X, вы можете добавить его в ~/.xsessionrc . Преимущество этого заключается в том, что он обычно будет доступен для всех программ, запускаемых через менеджер сеансов X, поскольку он устанавливается до запуска менеджера сеансов X и, следовательно, наследуется. Например, некоторые графические драйверы могут отключить vsync, запустив

 export vblank_mode=0 

Поэтому размещение в .xsessionrc должно повлиять на все программы.

Однако, если эта строка была добавлена ​​в .bashrc , это повлияет только на программы, запущенные через xterm; программы, запускаемые через панель запуска оконного менеджера, будут работать как обычно. Вы можете добавить его в .profile и в исходный .profile из .xsessionrc , но тогда вам не нужно экспортировать переменную среды, даже если ваш X-сервер не работает.

Надеюсь, теперь вы лучше понимаете, как работают сценарии входа и выхода из системы Debian GNU / Linux. Сообщите нам в комментариях, если вы создали или столкнулись с каким-либо особенно интересным или творческим использованием этих сценариев входа в систему и выхода из системы, и как вы это сделали.

Далее в этой серии я буду обсуждать варианты управления точечными файлами .