Linux. Переменные окружения и оболочки

14.04.2018

Теги: BashCLIexportLinuxsetunsetОкружениеПеременная

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

Среда содержит множество пар типа «ключ-значение». Если ключ содержит несколько значений, они обычно разделяются двоеточием. Если значение ключа содержит пробелы — нужно использовать кавычки.

КЛЮЧ_РАЗ=значение
КЛЮЧ_ДВА=значение1:значение2:…
КЛЮЧ_ТРИ='значение с пробелами'

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

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

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

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

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

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

$ env
SHELL=/bin/bash
USER=evgeniy
PWD=/home/evgeniy
LANG=ru_RU.UTF-8
..........

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

$ printenv SHELL
/bin/bash

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

$ env VAR='some value' command options

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

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

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

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

Основные переменные окружения и оболочки

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

  • 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 для фильтрации вывода команды env:

$ env | grep TEST_VAR
$

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

Убедимся в том, что переменная TEST_VAR не передается дочернему процессу. Для этого внутри текущей оболочки запустим новую оболочку:

$ bash
$ echo $TEST_VAR

$

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

$ exit

Создание переменных окружения

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

$ export TEST_VAR

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

$ env | grep TEST_VAR
TEST_VAR=Hello World!

Можно также снова развернуть дочернюю оболочку:

$ bash
$ echo $TEST_VAR
Hello World!

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

$ export NEW_VAR='New var value'

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

$ env | grep NEW_VAR
NEW_VAR=New var value

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

$ exit

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

$ echo $NEW_VAR

$ 

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

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

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

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

$ export -n TEST_VAR

Теперь эта переменная больше не является переменной окружения:

$ env | grep TEST_VAR
$

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

$ set | grep TEST_VAR
TEST_VAR='Hello World!'

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

$ unset TEST_VAR

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

$ echo $TEST_VAR

$

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

Какие бывают сеансы оболочки

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

Первое отличие — запускается оболочка в рамках сеанса входа или без входа.

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

Если запускается новый сеанс оболочки внутри аутентифицированного сеанса (например, вызывая команду bash из терминала) — запускается сеанс оболочки без входа. При запуске дочерней оболочки не требуется вводить данные для аутентификации.

Второе отличие — является сеанс оболочки интерактивным или неинтерактивным. Интерактивный сеанс оболочки — это сеанс оболочки, прикрепленный к терминалу. Неинтерактивный сеанс оболочки не прикреплен к сеансу терминала.

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

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

Сеанс, запускаемый в виде сеанса входа, будет считывать данные конфигурации сначала из файла /etc/profile. Затем он считывает первый из файлов ~/.bash_profile, ~/.bash_login и ~/.profile, который ему удается найти, и не считывает остальные файлы.

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

Тут нужно учитывать, что /etc/profile запускает на выполнение /etc/bash.bashrc — так что не надо думать, что сеанс входа будет каким-то неполноценным, без инициализации bash. С другой стороны, сеансу без входа нет необходимости чтения /etc/profile — потому что запускается внутри аутентифицированного сеанса и получит переменные окружения от него.

# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
# and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).

if [ "${PS1-}" ]; then
  if [ "${BASH-}" ] && [ "$BASH" != "/bin/sh" ]; then
    # The file bash.bashrc already sets the default PS1.
    # PS1='\h:\w\$ '
    if [ -f /etc/bash.bashrc ]; then
      . /etc/bash.bashrc
    fi
  else
    if [ "$(id -u)" -eq 0 ]; then
      PS1='# '
    else
      PS1='$ '
    fi
  fi
fi

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

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

Переменные окружения пользователя

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

# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

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

В самом начале мы видим, что для неинтерактивной оболочки это файл не выполняется. Давайте еще заглянем в файл ~/.profile — который выполняется для оболочки со входом. Этот файл тоже запускает на выполнение ~/.bashrc.

# ~/.profile: executed by the command interpreter for login shells.
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# exists.
# see /usr/share/doc/bash/examples/startup-files for examples.
# the files are located in the bash-doc package.

# 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 или /etc/environment.

Поиск: Bash • CLI • Linux • env • export • set • unset • Окружение • Переменная

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.