Чтение и установка переменных среды и оболочки на сервере Linux

Во время работы с сервером оболочка компилирует большое количество информации, которая определяет ее поведение и доступ к ресурсам. Некоторые из этих параметров находятся в настройках оболочки, другие определяются вводом пользователя.

Один из способов отслеживания оболочкой данной информации – это использование среды окружения. Среда – это область, содержащая определяющие свойства системы переменные, которую оболочка строит при каждом запуске сессии.

Данное руководство рассказывает, как взаимодействовать со средой и читать или устанавливать переменные среды и оболочки в интерактивном режиме и с помощью конфигурационных файлов. Все действия выполняются на Ubuntu 12.04 VPS, но любой современный дистрибутив Linux должен работать таким же образом.

Как работает среда и ее переменные

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

В целом среда предоставляет средство передачи, которое собирает и задает необходимые настройки процессу оболочки, который,в свою очередь, передать их своим дочерним процессам.

Среда имеет вид строки, содержащей пары вида «ключ-значение». Несколько значений, как правило, разделяются символом двоеточия (:). Каждая пара, в целом, выглядит примерно так:

КЛЮЧ=значение1:значение2:...

Если же значение содержит пробелы, нужно использовать двойные кавычки:

КЛЮЧ="значение с пробелами"

В данном случае под ключом подразумеваются переменные одного из двух существующих видов: переменные среды или оболочки.

Переменные среды – это переменные, которые были определены для текущей оболочки и наследуются всеми дочерними оболочками или процессами. Переменные среды используются для передачи информации процессам, запущенным из оболочки.

Переменные оболочки – это переменные, которые содержатся исключительно в оболочке, в которой они были установлены или определены. Они часто используются для отслеживания текущих данных (к примеру, текущего рабочего каталога).

Обычно такие переменные обозначаются с помощью заглавных букв. Это помогает пользователям различать переменные среды в других контекстах.

Вывод переменных оболочки и среды

Каждая сессия отслеживает свои переменные оболочки и среды. Вывести их можно несколькими способами.

Чтобы просмотреть список всех переменных среды, используйте команды env или printenv. По умолчанию они выведут точно такой же результат:

printenv
SHELL=/bin/bash
TERM=xterm
USER=demouser
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca:...
MAIL=/var/mail/demouser
PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
PWD=/home/demouser
LANG=en_US.UTF-8
SHLVL=1
HOME=/home/demouser
LOGNAME=demouser
LESSOPEN=| /usr/bin/lesspipe %s
LESSCLOSE=/usr/bin/lesspipe %s %s
_=/usr/bin/printenv

Это типичный пример выведенного командами printenv и env результата. Данные команды отличаются только несколькими индивидуальными функциями. К примеру, printenv может запрашивать значения отдельных переменных:

printenv SHELL
/bin/bash

Команда env позволяет изменять среду, в которой запущены программы, передавая набор определений переменных в команду, примерно так:

env VAR1="blahblah" command_to_run command_options

Как сказано выше, дочерние процессы обычно наследуют переменные среды родительского процесса, что дает возможность менять значения или вносить дополнительные переменные для дочерних процессов.

Как можно видеть в выводе команды printenv, многие переменные среды созданы с помощью системных файлов и процессов без вмешательства пользователя.

Но как же просмотреть переменные оболочки?

Для этого используется команда set. При вводе без дополнительных параметров set выводит список всех переменных оболочки, переменных среды, локальных переменных и функций оболочки:

set
BASH=/bin/bash
BASHOPTS=checkwinsize:cmdhist:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:login_shell:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
. . .

Как правило, этот список достаточно длинный. Чтобы вывести его в более удобном формате, откройте его с помощью программы-пейджера:

set | less

Этот список содержит огромное количество дополнительной информации, которая в данный момент не нужна (к примеру, некоторые функции bash).

Чтобы «почистить» выведенный результат, нужно запустить команду set в режиме POSIX, который пропускает функции оболочки. Это нужно выполнить в субоболочке, чтобы не изменить текущую среду:

(set -o posix; set)

Данное действие выведет все переменные среды и оболочки.

Можно также сравнить этот результат с результатом команд env/printenv и попробовать вывести список только переменных оболочки, но такой список не будет идеальным, поскольку данные команды выводят информацию по-разному:

comm -23 <(set -o posix; set | sort) <(env | sort)

Скорее всего, список будет содержать несколько переменных среды, поскольку команда set выводит значения в кавычках, а команды printenv и env – нет.

Тем не менее, это отличный способ просмотреть переменные среды и оболочки, установленные в данной сессии.

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

Основные переменные среды и оболочки

Некоторые особенно полезные переменные среды и оболочки используются очень часто.

Ниже приведен список основных переменных среды:

  • SHELL: описывает оболочку, которая интерпретирует введенные команды. В большинстве случаев по умолчанию установлена bash, но это значение можно изменить в случае необходимости.
  • TERM: указывает вид терминала, эмулируемого при запуске оболочки. В зависимости от операционных требований можно эмулировать разные аппаратные терминалы. Как правило, об этом не нужно беспокоиться.
  • USER: текущий пользователь.
  • PWD: текущий рабочий каталог.
  • OLDPWD: предыдущий рабочий каталог. Оболочка хранит его на случай запуска команды cd -.
  • LS_COLORS: определяет цветовые коды, которые используются для цветного вывода результата команды ls. Такой вывод помогает пользователю быстрее прочесть результат команды (например, быстро различить типы файлов).
  • MAIL: путь к текущему почтовому ящику пользователя.
  • PATH: список каталогов, к которым обращается система при выполнении команд. Когда пользователь запускает команду, система проверяет эти каталоги в указанном порядке в поисках исполняемого файла.
  • LANG: текущие настройки языка и локализации, в том числе кодировка символов.
  • HOME: домашний каталог текущего пользователя.
  • _: последняя выполненная команда.

Ознакомившись со списком переменных среды, изучите список переменных оболочки:

  • BASHOPTS: список опций, использованных при выполнении bash. Это можно применять для того, чтоб проверить, работает ли среда должным образом.
  • BASH_VERSION: запущенная версия bash в удобочитаемой форме.
  • BASH_VERSINFO: версия bash в машиночитаемом формате.
  • COLUMNS: определяет ширину вывода в столбцах.
  • DIRSTACK: стек каталогов, доступных командам pushd и popd.
  • HISTFILESIZE: максимальное количество строк, содержащееся в файле истории команд.
  • HISTSIZE: Количество команд, которые необходимо запоминать в списке истории.
  • HOSTNAME: текущее имя хоста.
  • IFS: Внутренний разделитель полей ввода в командной строке. По умолчанию установлен пробел.
  • PS1: определяет строку первичного приглашения – вид командной строки при запуске сессии оболочки. Переменная PS2 устанавливает строку вторичного приглашения, если команда занимает несколько строк.
  • SHELLOPTS: параметры оболочки, которые можно установить при помощи set.
  • UID: уникальный идентификатор текущего пользователя.

Установка переменных оболочки и среды

Ниже приведены несколько примеров, чтобы продемонстрировать разницу между переменными оболочки и среды и объяснить синтаксис установки этих переменных.

Создание переменных оболочки

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

TEST_VAR='Hello World!'

В данном примере используются кавычки, поскольку значение содержит пробелы.  Более того, здесь нужно использовать именно одинарные кавычки, так как восклицательный знак является специальным символом в bash-оболочке, который обращается к истории команд, если он не избегается или не заключен в одинарные кавычки.

Итак, полученная переменная оболочки действительна в текущей сессии, но не передается ее дочерним процессам.

Чтобы в этом убедиться, используйте команду grep на результат команды set:

set | grep TEST_VAR
TEST_VAR='Hello World!'

Убедиться, что данная переменная не является переменной среды, также можно, запустив grep на результат команды printenv:

printenv | grep TEST_VAR

Данное действие не выведет никакого результата.

Это можно использовать, чтобы открыть значение любой переменной оболочки или среды.

echo $TEST_VAR
Hello World!

Как можно видеть, чтобы обратиться к значению переменной, нужно использовать символ $.

Опять же, полученная переменная не должна быть передана какому-либо дочернему процессу. Чтобы это протестировать, внутри текущей оболочки разверните новую bash-оболочку:

bash
echo $TEST_VAR

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

Чтобы вернуться в исходную оболочку, введите exit:

exit

Создание переменных среды

Теперь попробуйте превратить переменную оболочки в переменную среды. Это делается путем экспорта переменной. Команда, выполняющая экспорт, имеет соответствующее название.

export TEST_VAR

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

printenv | grep TEST_VAR
TEST_VAR=Hello World!

Теперь эта переменная выведена в данном списке. Можно также снова развернуть дочернюю оболочку:

bash
echo $TEST_VAR
Hello World!

Отлично! Дочерняя оболочка получила переменную исходной оболочки. Попробуйте экспортировать еще одну переменную, прежде чем покинуть дочернюю оболочку.

export NEW_VAR="Testing export"

Проверьте, экспортировалась ли переменная:

printenv | grep NEW_VAR
NEW_VAR=Testing export

Теперь вернитесь в исходную оболочку:

exit

Проверьте, можно ли открыть данную переменную:

echo $NEW_VAR

Результат не возвращается

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

Переменная NEW_VAR была установлена как переменная среды дочерней оболочки. Эта переменная действительна для данной оболочки и ее дочерних оболочек и процессов. После возвращения пользователя в исходную оболочку данная среда была разрушена.

Перемещение и сброс переменных

Переменная TEST_VAR все еще является переменной среды. Чтобы снова сделать ее переменной оболочки, наберите:

export -n TEST_VAR

Теперь эта переменная больше не является переменной среды:

printenv | grep TEST_VAR

Это снова переменная оболочки:

set | grep TEST_VAR
TEST_VAR='Hello World!'

Чтобы полностью сбросить переменную, будь то переменная среды или оболочки, используйте команду unset:

unset TEST_VAR

Убедитесь, что такой переменной больше нет:

echo $TEST_VAR

Результат не был выведен, поскольку переменная была сброшена.

Автоматическая установка переменных среды

Как уже было сказано, многие программы используют перменные среды, чтобы определить, как им работать. Устанавливать необходимые переменные всякий раз, когда создается новая оболочка, достаточно неудобно. Кроме того, многие переменные устанавливаются сразу же, при входе. Как же устанавливать переменные автоматически?

Это немного сложнее, чем кажется сначала, поскольку bash-оболочка читает множество конфигурационных файлов.

Типы сессий оболочки

Оболочка bash читает разные конфигурационные файлы в зависимости от того, как сессия была запущена. Первые два типа сессий, определяющие оболочку, – это стартовая и дочерняя.

Стартовая, или начальная оболочка (login shell) – это сессия оболочки, которая открывается после авторизации пользователя. Если пользователь входит в терминал или проходит авторизацию при помощи SSH, будет открыта стартовая оболочка.

Если новая сессия запускается из авторизованной (стартовой) сессии (как ранее в примерах запускалась новая bash-оболочка), эта сессия будет дочерней (non-login shell). Чтобы открыть эту сессию, не нужно проходить процедуру авторизации.

Также сессии оболочки бывают интерактивными и неинтерактивными.

Интерактивная сессия оболочки (interactive shell) – это сессия, привязанная к терминалу. Неинтерактивная сессия оболочки (non-interactive shell) – это сессия, не привязанная к терминалу.

Итак, сессии оболочки классифицируются по таким аспектам: стартовая-дочерняя, интерактивная-неинтерактивная.

Обычная сессия, открытая с помощью SSH, как правило, является интерактивной стартовой сессией. Скрипт, запущенный через командную строку, обычно работает в неинтерактивной дочерней сессии. Терминальная сессия – это различные комбинации этих двух свойств.

Классифицируя сессию как стартовую или дочернюю, система понимает, какие файлы нужно читать для инициализации сессии оболочки.

Итак, сначала стартовая сессия получает конфигурации из файла /etc/profile. Затем она ищет конфигурационный файл стартовой оболочки в домашнем каталоге пользователя, чтобы получить определенные пользователем конфигурации.

Такая сессия читает файлы ~/.bash_profile, ~/.bash_login и ~/.profile и не читает остальных файлов.

Дочерняя сессия, в свою очередь, читает /etc/baash.bashrc, а затем пользовательский файл ~/.bash.rc для развертывания среды.

Неинтерактивные оболочки читают переменную среды BASH_ENV и указанный файл, чтобы создать новую среду.

Как задать переменные среды

Как видите, конфигурации разбросаны по разным файлам.

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

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

Как правило, для обеих оболочек используются переменные среды, задаваемые пользователем. Это значит, что задать эти переменные можно в файле ~/.bashrc.

Откройте данный файл:

nano ~/.bashrc

Скорее всего, он уже содержит немного данных. Большинство заданных здесь значений – это параметры bash, не имеющие отношения к переменным среды. Переменные в данном файле задаются точно так же, как и в командной строке:

export VARNAME=value

Внеся все необходимые переменные, закройте файл. При следующем запуске сессии оболочки заданные здесь переменные будут читаться и передаваться среде оболочки. Чтобы сказать текущей сессии читать данный файл, введите:

source ~/.bashrc

Чтобы задать общесистемные переменные, внесите их в /etc/profile, /etc/bash.bashrc или /etc/environment.

Итоги

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

В определенных ситуациях это дает ряд преимуществ. К примеру, некоторые механизмы развертывания полагаются на переменные среды для настройки данных аутентификации. Это удобно, поскольку такие важные данные не будут храниться в каком-либо файле, а значит – будут надежно защищены от посторонних.

Есть множество других более распространенных ситуаций, в которых может возникнуть необходимость прочитать переменные или изменить среду системы. Описанные в данном руководстве инструменты и методы – отличная основа для развития навыков работы с переменными и их правильного использования.

Tags: , ,

1 комментарий

Добавить комментарий