Операционная система Linux предполагает наличие интерфейса взаимодействия между компонентами системы и пользователем. Такой интерфейс называется оболочкой (от английского shell).
📜 Читайте также: RDP-клиенты для Linux
При взаимодействии с сервером во время сеанса система сохраняет большое количество информации для определения своего поведения и обеспечения доступа к ресурсам. Такие настройки хранятся внутри файлов конфигурации или определяются пользователем.
При запуске сеанса оболочка каждый раз создаёт специальную область — окружение. В этой области содержатся переменные, которые определяют свойства системы. Информация, которая компилируется при создании окружения, доступна дочерним процессам оболочки и ее самой.
Иными словами, окружение является средой, через которую оболочка получает настройки и передает их дочерним процессам.
Окружение — набор пар вида «ПЕРЕМЕННАЯ=ЗНАЧЕНИЕ», каждая пара выглядит подобным образом:
KEY=value1:value2:...
или в случае, если в значении есть пробел:
KEY="long value"
В этих строках ключи являются переменными оболочки или окружения.
Переменные окружения — переменные, которые определяются для текущего сеанса и наследуются любыми дочерними оболочками и сеансами. Используются для передачи информации процессам.
Переменные оболочки — переменные, которые содержатся исключительно в оболочке, внутри которой они определены. Используются для кратковременных данных, например, командой PWD для определения текущего рабочего каталога.
Такие переменные обычно именуются с помощью заглавных букв, чтобы разработчики отличали их от переменных других контекстов.
Стандартные переменные
Ниже представлен список переменных, которые используются наиболее часто.
Переменные окружения
- SHELL — описывает оболочку, в которой выполняется интерпретация команд пользователя. Чаще всего — /bin/bash, но можно установить любое другое значение.
- USER — текущий пользователь системы.
- PWD — текущий рабочий каталог.
- OLDPWD — предыдущий рабочий каталог.
- LS_COLORS — цвета, которые используются для цветного вывода ls.
- MAIL — путь к почтовому ящику текущего пользователя.
- PATH — список каталогов, которые система проверяет при поиске команд. Так, при вводе любой команды система последовательно проверяет все каталоги, указанные в этой переменной.
- LANG — язык для текущей локали.
- HOME — домашний каталог текущего пользователя.
- _ — последняя выполненная команда.
- TERM — тип терминала, который запускается при запуске оболочки.
Переменные оболочки
- BASHOPTS — список опций, которые используются при исполнении оболочки bash.
- BASH_VERSION (или BASH_VERSINFO) — версия оболочки bash.
- COLUMNS — количество столбцов для отображения вывода.
- DIRSTACK — стек каталогов, доступных с помощью pushd и popd.
- HISTFILESIZE — количество строк журнала истории команд.
- HOSTNAME — имя хоста сервера.
- IFS — внутренний разделитель поля для выделения ввода, пробел по умолчанию.
- PS1 — приглашение при запуске сеанса оболочки.
- SHELLOPTS — опции оболочки, которые задаются с помощью set.
- UID — уникальный идентификатор текущего пользователя.
Кстати, в официальном канале Timeweb Cloud собрали комьюнити из специалистов, которые говорят про IT-тренды, делятся полезными инструкциями и даже приглашают к себе работать.
Вывод переменных оболочки и окружения
Каждый сеанс оболочки Linux использует собственные переменные оболочки и окружения. Протестируем работу с переменными на чистой системе Ubuntu 20.04, для этого можно использовать облачные серверы Timeweb Cloud.
Список переменных окружения
Посмотреть список всех переменных окружения можно с помощью команд env или printenv. В общем случае они работают одинаково. Проверим переменные окружения в Linux суперпользователя root:
sudo su
env
В ответе увидим приблизительно такой вывод:
SHELL=/bin/bash
PWD=/root
LOGNAME=root
XDG_SESSION_TYPE=tty
MOTD_SHOWN=pam
HOME=/root
LANG=C.UTF-8
LS_COLORS=rs=0:di=01;…………………………
SSH_CONNECTION=185.246.*.121 42062 165.227.*.42 22
LESSCLOSE=/usr/bin/lesspipe %s %s
XDG_SESSION_CLASS=user
TERM=xterm-256color
LESSOPEN=| /usr/bin/lesspipe %s
USER=root
SHLVL=1
XDG_SESSION_ID=13106
XDG_RUNTIME_DIR=/run/user/0
SSH_CLIENT=185.246.*.121 42062 22
XDG_DATA_DIRS=/usr/local/share:/usr/share:/var/lib/snapd/desktop
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/0/bus
SSH_TTY=/dev/pts/1
_=/usr/bin/env
Отличие printenv от env в том, что с помощью первой утилиты можно запросить значение конкретной переменной:
printenv HOME
Вывод:
/root
С помощью команды env можно передавать наборы определений переменных, изменяя окружение, в котором запущены команды. Это позволяет переопределять или задавать новые переменные для дочерних процессов:
env TEMPVAR="tempval"
Переменные оболочки
Для просмотра переменных оболочки нужно ввести команду set без параметров:
set
В результате выполнения команды вы увидите очень большой список из переменных и функций. Этот вид можно сделать более компактным:
set | less
Вывод всё ещё очень объёмный. В этой статье нас интересуют только переменные, поэтому для команды set зададим режим работы POSIX. Это значит, что в выводе будут отсутствовать функции оболочки. Выполним команду в субоболочке:
(set -o posix; set)
Вывод стал хотя бы читаемым. Теперь можно сравнить его с выводом команды env, чтобы получить исключительно переменные оболочки:
comm -23 <(set -o posix; set | sort) <(env | sort)
Такой вывод всё равно будет включать несколько переменных окружения, потому что команды отображают информацию по-разному — в кавычках и нет (например, SSH_CLIENT).
Но такая команда всё равно покажет, какие переменные доступны для вашего сеанса.
Настройка переменных
Рассмотрим на практических примерах работу с переменными оболочки и окружения.
Во всех случаях будем придерживаться общепринятого правила по именованию — заглавными буквами. Если строка содержит пробелы, поместим её в кавычки.
Создание и настройка переменных оболочки
Внутри текущего сеанса создадим переменную TEMP_VAR, указав имя и значение.
TEMP_VAR='HELLO TIMEWEB READERS!'
Эта переменная доступа в текущем сеансе, но недоступна для дочерних процессов. Проверим, существует ли такая переменная в выводе команды set:
set | grep TEMP_VAR
В результате увидим нашу переменную. То, что это переменная оболочки, а не окружения, доказывает пустой вывод команды printenv | grep TEMP_VAR.
Сослаться на эту переменную можно использовав перед её именем знак доллара:
Команда:
echo $TEMP_VAR
выводит строку „HELLO TIMEWEB READERS!“.
Теперь проверим, что эта переменная правда недоступна в дочерних процессах. Создадим новую оболочку bash и проверим.
Создаём новую оболочку:
bash
Запрашиваем вывод переменной:
echo $TEMP_VAR
В результате — пустой вывод. Возвращаемся в предыдущий сеанс с помощью команды exit.
Создание переменных окружения
Теперь переменную TEMP_VAR нужно превратить в переменную окружения. Сделаем это с помощью команды export:
export TEMP_VAR
Проверим, появилась ли переменная TEMP_VAR в выводе команды printenv:
printenv | grep TEMP_VAR
В результате видим нашу переменную (без кавычек):
TEMP_VAR=HELLO TIMEWEB READERS!
Для ещё одной проверки повторим эксперимент с дочерней оболочкой bash.
Создаём новую оболочку:
bash
Запрашиваем вывод переменной:
echo $TEMP_VAR
В результате видим строчку:
HELLO TIMEWEB READERS!
Всё работает корректно — дочерняя оболочка получила переменную, определенную в родительской. Попробуем в этой же оболочке создать новую переменную:
export TEMP_VAR1="EXPERIMENT"
Выходим из оболочки и проверяем, доступна ли переменная на уровень выше:
exit
echo $TEMP_VAR1
Видим пустой вывод. Это связано с тем, что системные переменные окружения Linux передаются только дочерним процессам. Это организовано прежде всего для безопасности — так программы не смогут повлиять на среду, в которой они запущены. Когда мы вышли из оболочки, переменная TEMP_VAR1 была уничтожена.
Сброс и удаление системных переменных окружения
Переменная TEMP_VAR всё ещё является переменной окружения. Превратить её обратно в переменную оболочки можно так же с помощью команды export с флагом -n:
export -n TEMP_VAR
Убедимся, что TEMP_VAR всё ещё является переменной оболочки:
set | grep TEMP_VAR
Тогда как вывод команды printenv | grep TEMP_VAR будет пустым.
Полностью сбросить переменную можно с помощью команды unset.
unset TEMP_VAR
Убедимся в сбросе, проверив, что вывод команды echo $TEMP_VAR пустой.
Настройка переменных при входе
Программы ОС Linux используют переменные окружения для конфигурации своей работы. Если вы написали скрипт, который оперирует переменными окружения, очень утомительно задавать их каждый раз при входе.
Определять переменные при входе возможно, но при этом стоит учитывать, что оболочка bash работает с разными файлами конфигурации в зависимости от того, как она была запущена.
Ключевое различие в том, запускается оболочка со входом или без входа. Оболочка входа — сеанс, который начинается с аутентификации. Например, когда вы подключаетесь к серверу через терминал или SSH, ваш сеанс будет считаться оболочкой со входом.
Однако если вы создаете новый сеанс из текущей оболочки (как в примерах выше), запускается сеанс оболочки без входа.
Также сеансы бывают интерактивными или неинтерактивными, иными словами, прикрепленными к терминалу или нет, соответственно.
То, как классифицируется каждый конкретный сеанс влияет на файлы, которые будут считываться при инициализации оболочки.
Например, сеанс входа считывает данные из файла /etc/profile, затем он будет искать первый файл конфигурации в домашней директории пользователя: ~/.bash_profile, ~/.bash_login и ~/.profile.
Сеанс без входа же будет считывать файл /etc/bash.bashrc и затем использовать файл ~/.bashrc конкретного пользователя для создания окружения.
Неинтерактивные оболочки используют переменную окружения BASH_ENV для определения файла, в котором задано новое окружение.
Задание переменных
Из-за того, что существует множество файлов для определения настроек, администратор сервера может гибко настраивать сценарии использования системы. Единственная сложность в том, чтобы запомнить, где хранятся переменные окружения в Linux для каждого конкретного случая.
Большинство современных дистрибутивов Linux позволяют настраивать файлы конфигурации сеанса оболочки со входом для использования файлов конфигурации без входа. Проще говоря, если вам нужно задать настройки, которые используются в обоих сценариях, укажите их для сценария без входа.
Зададим переменные для конкретного пользователя в файле ~/.bashrc:
nano ~/.bashrc
Файл уже содержит немало данных, которые, например, настраивают bash. Задать переменные окружения можно так же, как в примерах выше. Добавьте строчку в конец файла:
export TEMP_VAR="Hello Timweb readers!"
Сохраните и закройте файл. После создания нового сеанса объявление переменной TEMP_VAR передастся в среду оболочки.
Файл можно считать прямо сейчас, не дожидаясь новой аутентификации:
source ~/.bashrc
Общесистемные переменные, которые не зависят от пользователя нужно задавать в глобальных файлах:
- /etc/profile — для всех пользователей, подключающихся удаленно
- /etc/bash.bashrc — для всех сессий, кроме удалённых
- /etc/environment — для пользователей, подключающихся и удалённо, и локально
Заключение
Большинство программ, запускаемых в ОС Linux, оперируют системными переменными, чтобы определить свое поведение. Так, например, можно разграничивать доступ для разных пользователей или отображать информацию по-разному в зависимости от способа входа.
Если вы разрабатываете продукты, которые работают в среде ОС Linux, или администрируете сервер, вам необходимо знать, принципы работы локальных переменных.
В статье мы рассмотрели, что такое окружение и оболочка в ОС Linux на примере сервера, заказанного в Timeweb Cloud, а также для чего используются переменные и как они могут быть полезны для конфигурации системы. На примерах проверили, как взаимодействуют родительские и дочерние оболочки.
Также на примерах определили основные способы создания и настройки переменных окружения и оболочки.
Статья оказалась полезной? Подписывайтесь, ставьте лайки и поделитесь ссылкой с друзьями.💗