У світі Linux існує різноманіття типів змінних оточення. Давайте розглянемо, як їх переглядати, створювати для локальних та віддалених сеансів, а також як зробити їх стійкими після перезавантаження системи.
Принцип дії змінних оточення
Коли ви відкриваєте термінал і запускаєте командний інтерпретатор всередині нього, набір змінних оточення використовується для забезпечення правильної конфігурації цього інтерпретатора. Ці змінні також надають доступ до важливих даних, необхідних для роботи термінала та інтерпретатора. Разом ці змінні формують параметри, що визначають середовище, яке ви бачите в терміналі, включаючи зовнішній вигляд командного рядка. Саме тому їх називають змінними оточення.
Деякі змінні оточення є загальносистемними, або глобальними, доступними для всіх користувачів. Інші ж є локальними, видимими лише в межах вашого поточного сеансу. Третій тип змінних оточення визначається безпосередньо в оболонці. Ваші налаштування локалізації, часовий пояс, клавіатура, перелік каталогів для пошуку команд, а також редактор за замовчуванням — все це зберігається у змінних оточення оболонки.
Ми розглянемо, як переглядати наявні змінні оточення, а також навчимося створювати власні. Крім того, ви дізнаєтесь, як зробити їх доступними для дочірніх процесів і як зберегти їх після перезавантаження системи.
Успадкування середовища
При запуску оболонки відбувається її ініціалізація, під час якої зчитуються змінні оточення, що визначають середовище оболонки.
Коли програма або команда запускається з цієї оболонки, як дочірній процес, вона успадковує середовище батьківського процесу. Однак, будьте уважні! Можна створювати змінні, які не додаються до середовища, і тому не будуть успадковані дочірнім процесом.
Якщо дочірнім процесом є інша оболонка, то вона ініціалізується зі своїм власним, новим набором змінних. Таким чином, якщо ви змінюєте командний рядок в поточній оболонці, а потім запускаєте дочірню, то остання не успадкує змінений командний рядок від батьківської оболонки.
Глобальні змінні оточення
За угодою, імена змінних оточення пишуться великими літерами. Ось деякі приклади глобальних змінних оточення та їхніх значень:
SHELL
: назва інтерпретатора, який використовується при відкритті термінала. У більшості дистрибутивів Linux це буде bash, якщо ви не змінювали його значення за замовчуванням.
TERM
: термінали емулюють апаратні термінали. Ця змінна містить тип емульованого апаратного термінала.
USER
: ім’я користувача, який наразі працює в системі.
PWD
: шлях до поточного робочого каталогу.
OLDPWD
: каталог, в якому ви знаходилися до переходу до поточного робочого каталогу.
LS_COLORS
: перелік колірних кодів, що використовуються ls
для виділення різних типів файлів.
MAIL
: якщо поштова система налаштована на вашому комп’ютері (за замовчуванням це не так), тут зберігається шлях до поштової скриньки поточного користувача.
PATH
: перелік каталогів, в яких оболонка шукає виконувані файли команд.
LANG
: налаштування мови, локалізації та кодування символів.
HOME
: домашній каталог поточного користувача.
_
: змінна оточення підкреслення містить останню введену команду.
Ми можемо переглянути значення деяких з цих змінних, використовуючи команду echo
, яка виводить значення на екран. Щоб побачити значення змінної оточення, потрібно додати знак долара ($) на початку її імені.
Корисним є те, що ви можете використовувати автодоповнення, щоб заповнити назву змінної оточення. Введіть кілька літер імені і натисніть Tab. Оболонка доповнить ім’я змінної. Якщо цього не сталося, вам потрібно буде ввести більше літер, щоб відрізнити змінну оточення від інших команд з подібними іменами:
echo $SHELL
echo $LANG
echo $HOME
echo $PWD
Щоб створити власні глобальні змінні оточення, додайте їх до файлу /etc/environment
. Вам знадобиться sudo
для редагування цього файлу:
sudo gedit /etc/environment
Щоб додати змінну оточення, введіть її ім’я, знак рівності (=) і значення, яке змінна має зберігати. Не ставте пробіл перед або після знака рівності. Ім’я змінної оточення може містити літери, підкреслення (_) або цифри. Однак першим символом не може бути число.
Якщо значення містить пробіли, обов’язково візьміть його в лапки (“).
Збережіть файл, потім вийдіть з системи та знову увійдіть. Використовуйте echo
, щоб перевірити, чи існує нова змінна та чи містить вона задане значення:
echo $WEBSITE
Оскільки це глобальна змінна оточення, доступна кожному, користувач mary може використовувати її, коли наступного разу ввійде в систему:
echo $WEBSITE
Щоб переглянути всі змінні оточення одразу, введіть printenv
. Виводу багато, тому має сенс відсортувати його і передати на less
:
printenv | sort | less
Відсортований перелік змінних оточення відображається в less
.
Можна також передати вивід через grep
для пошуку змінних оточення, пов’язаних з певною темою.
printenv | grep GNOME
Змінні оточення оболонки
Ось деякі змінні оточення оболонки, які використовуються bash
для визначення та запису своєї поведінки та функціональності. Деякі значення оновлюються під час використання термінала. Наприклад, змінна оточення COLUMNS
буде оновлена, щоб відображати зміни в ширині вікна термінала:
BASHOPTS
: параметри командного рядка, які використовувались під час запуску bash
.
BASH_VERSION
: номер версії bash
у вигляді рядка з слів і чисел.
BASH_VERSINFO
: версія bash
у вигляді цифр.
COLUMNS
: поточна ширина вікна термінала.
DIRSTACK
: каталоги, які були додані до стеку каталогів командою pushd
.
HISTFILESIZE
: максимальна кількість рядків, дозволена у файлі історії.
HISTSIZE
: кількість рядків історії, дозволена в пам’яті.
HOSTNAME
: ім’я хоста комп’ютера.
IFS
: внутрішній роздільник полів, що використовується для розділення вводу в командному рядку. За замовчуванням це пробіл.
PS1
: змінна оточення PS1
містить визначення для основного, за замовчуванням, командного рядка. У визначенні командного рядка можна включити набір маркерів, які називаються вихідними послідовностями. Вони представляють такі речі, як ім’я хоста і користувача, поточний робочий каталог і час.
PS2
: коли команда охоплює більше ніж один рядок і очікується ще введення, відображається вторинний командний рядок. Змінна оточення PS2
містить визначення цієї вторинної підказки, яка за замовчуванням є знаком “більше” (>).
SHELLOPTS
: параметри оболонки, які можна встановити за допомогою параметра set
.
UID
: ідентифікатор користувача поточного користувача.
Давайте перевіримо деякі з цих змінних оболонки:
echo $BASH_VERSION
echo $HOSTNAME
echo $COLUMNS
echo $HISTFILESIZE
echo $UID
Для повноти, ось маркери, які можна використовувати у визначеннях командного рядка:
\t
: поточний час у форматі ГГ:ММ:СС.
\d
: поточна дата, виражена як день тижня, місяць, число.
\n
: символ нового рядка.
\s
: назва вашої оболонки.
\W
: назва вашого поточного робочого каталогу.
\w
: шлях до поточного робочого каталогу.
\u
: ім’я користувача особи, що ввійшла в систему.
\h
: ім’я хоста комп’ютера.
\#
: кожна команда в оболонці пронумерована. Це дозволить вам побачити номер команди в командному рядку. Це не те саме число, яке команда матиме у списку історії.
\$
: встановлює кінцевий символ підказки на знак долара ($) для звичайного користувача та символ решітки (#) для користувача root. Це працює шляхом перевірки UID користувача. Якщо він дорівнює нулю, користувач є root.
Визначення змінної оточення PS1
знаходиться у файлі .bashrc
.
Створення змінних оточення сеансу
Щоб створити змінні оточення для власного використання, додайте їх в нижню частину вашого файлу .bashrc
. Якщо ви хочете, щоб змінні були доступні для віддалених сеансів, наприклад, для з’єднань SSH, вам також потрібно буде додати їх до файлу .bash_profile
.
Формат визначення змінної оточення однаковий для обох файлів. Щоб додати визначення до файлу .bash_profile
, введіть наступне у вашому домашньому каталозі:
gedit .bashrc
Ми додали змінну оточення під назвою INHERITED_VAR
. Зверніть увагу на слово “export” на початку рядка.
Збережіть і закрийте файл після редагування. Ви можете вийти з системи і знову увійти, або ж змусити оболонку повторно прочитати файл .bash_profile
, використовуючи точку (.) ось так:
. .bashrc
Тепер створімо змінну оточення в командному рядку:
LOCAL_VAR="This session only"
Якщо ми використаємо echo
, то побачимо, що обидві змінні оточення доступні:
echo $LOCAL_VAR
echo $INHERITED_VAR
Ви помітите, що визначення змінної INHERITED_VAR
містило слово “export” на початку рядка. Це означає, що змінна оточення буде успадкована дочірніми процесами поточної оболонки. Якщо ми запустимо ще одну оболонку командою bash
, то знову зможемо перевірити дві змінні всередині дочірньої оболонки:
bash
echo $LOCAL_VAR
echo $INHERITED_VAR
Як бачите, INHERITED_VAR
доступна в дочірній оболонці, а LOCAL_VAR
— ні. Ми просто отримаємо порожній рядок.
Хоча export
додає частину змінної оточення до середовища, яке успадковують дочірні процеси, INHERITED_VAR
не є глобальною змінною оточення. Наприклад, користувач mary не може посилатися на неї:
echo $INHERITED_VAR
Щоб закрити наш дочірній сеанс bash
, скористаємося командою exit
:
exit
Успадковане середовище також впливає на сценарії. Ось простий сценарій, який записує значення трьох наших змінних оточення у вікно термінала:
#!/bin/bash echo "WEBSITE" $WEBSITE echo "LOCAL_VAR" $LOCAL_VAR echo "INHERITED_VAR" $INHERITED_VAR
Сценарій був збережений у файлі envtest.sh
, а потім виконаний з наступними правами:
chmod +x envtest.sh
Коли ми запускаємо сценарій, він може отримати доступ до двох із трьох змінних оточення:
./envtest.sh
Сценарій може бачити глобальну змінну оточення WEBSITE
та експортовану змінну оточення INHERITED_VAR
. Він не може отримати доступ до LOCAL_VAR
, навіть якщо сценарій виконується в тій самій оболонці, де була створена змінна.
При необхідності, ми можемо експортувати змінну оточення з командного рядка. Ми зробимо це з нашою LOCAL_VAR
, а потім знову запустимо сценарій:
export LOCAL_VAR
./envtest.sh
Змінна оточення була додана до середовища поточної оболонки, і тому вона з’являється в середовищі, що успадковується сценарієм. Сценарій також може використовувати цю змінну оточення.
Віддалені підключення
Глобальні змінні оточення доступні для сеансів віддаленого входу. Проте, якщо ви бажаєте, щоб ваші локально визначені змінні оточення були доступні вам віддалено, ви повинні додати їх до файлу .bash_profile
. Можна задавати ту саму змінну в файлах .bashrc
і .bash_profile
з різними значеннями. Це може використовуватися сценаріями для зміни поведінки для користувачів, що працюють локально або віддалено.
(З ризиком ускладнити, існує також файл .profile
. Він також може містити визначення змінних оточення. Однак файл .profile
не зчитується, якщо є файл .bash_profile
. Тому найбезпечнішим варіантом, сумісним з bash
, є використання файлу .bash_profile
).
Для редагування файлу .bash_profile
знову використаємо gedit
:
gedit .bash_profile
Ми додамо ту саму змінну оточення з тим самим значенням, що використовували раніше.
Збережіть зміни та закрийте gedit
.
На іншому комп’ютері ми створимо SSH з’єднання з тестовим комп’ютером.
ssh [email protected]
Після підключення, знову запустимо сценарій:
./envtest.sh
Файл .bash_profile
був прочитаний як частина ініціалізації віддаленого входу, і змінна оточення INHERITED_VAR
доступна нам та сценарію.
Скасування змінної оточення
Щоб скасувати встановлення змінної оточення, використовуйте команду unset
. Якщо ми скасуємо глобальну змінну оточення WEBSITE
та експортовану змінну INHERITED_VAR
, вони більше не будуть доступні в командному рядку або в дочірніх процесах:
unset WEBSITE
unset INHERITED_VAR
./envtest.sh
echo $WEBSITE
Варто зазначити, що це змінить доступність глобальних змінних оточення лише для вас в поточному сеансі. Інший користувач, який одночасно ввійшов в систему, все одно матиме доступ до свого примірника цієї глобальної змінної. Його екземпляр був ініціалізований і зчитаний з файлу /etc/environment
під час входу в систему і є незалежним від інших копій змінної.
Наприклад, користувач mary все ще може отримати доступ до змінної WEBSITE
та прочитати її значення, навіть якщо користувач dave скасував її під час свого сеансу:
echo $WEBSITE
Контроль середовища
Змінні оточення можна використовувати, щоб сценарії та програми знали, як їм слід поводитися. Їх можна використовувати для збереження налаштувань або невеликих обсягів даних. Наприклад, сценарій може задати значення у змінній, яке буде доступне іншим сценаріям, не записуючи ці дані у файл.