Переменные окружения в Linux

ShellBeginner
Практиковаться сейчас

Введение

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

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

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

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

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

cd /home/labex/project/environment-lab
course_name="Linux for Noobs"

Если поставить перед именем символ $, оболочка раскроет это имя в соответствующее значение:

echo "$course_name"

Двойные кавычки разрешают раскрытие переменной и передают результат как один аргумент. Одинарные кавычки сохраняют знак доллара буквально. Сравните результаты:

printf 'double: %s\n' "$course_name"
printf 'single: %s\n' '$course_name'

Сохраните раскрытое значение в файл, чтобы проверить результат:

printf 'course=%s\n' "$course_name" > shell-variable.txt
cat shell-variable.txt

Эта переменная существует только в текущей оболочке, если её не экспортировать.

Наблюдение за наследованием дочерним процессом

На этом шаге вы сравните обычную переменную оболочки и экспортированную переменную внутри дочернего процесса.

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

Вернитесь в рабочий каталог и создайте по одной переменной каждого типа:

cd /home/labex/project/environment-lab
local_message="visible only in this shell"
export SHARED_MESSAGE="visible in child processes"

Создайте небольшой дочерний процесс Bash, который выведет оба имени. Кавычки вокруг маркера heredoc не позволяют текущей оболочке раскрыть переменные во время записи скрипта:

cat > inspect-child.sh <<'EOF'
#!/bin/bash
printf 'local=%s\n' "${local_message:-<missing>}"
printf 'shared=%s\n' "${SHARED_MESSAGE:-<missing>}"
EOF
chmod +x inspect-child.sh

Запустите скрипт, перенаправьте его вывод в файл, а затем выведите содержимое файла. Раздельные команды помогают увидеть, какая команда запускает дочерний процесс, а какая проверяет сохранённый результат:

./inspect-child.sh > child-environment.txt
cat child-environment.txt

Обычная переменная должна отображаться как <missing>, а SHARED_MESSAGE должна быть унаследована. Убедитесь, что экспортированное имя присутствует в окружении:

env | grep '^SHARED_MESSAGE='

Просмотр стандартных переменных окружения

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

Оболочки Linux обычно предоставляют полезные стандартные переменные:

  • HOME — ваш домашний каталог.
  • USER — имя вашей учётной записи.
  • SHELL — настроенная оболочка входа.
  • PWD — текущий рабочий каталог.
  • PATH — список каталогов для поиска команд, разделённых двоеточиями.
  • TERM — возможности терминала, доступные интерактивным программам.

Выведите выбранные значения с помощью printenv. Эта команда читает экспортированные переменные по имени:

printenv HOME USER SHELL PWD TERM

Переменную PATH удобнее читать, когда каждый каталог находится на отдельной строке. Передайте значение команде tr, чтобы заменить каждое двоеточие символом новой строки:

printf '%s\n' "$PATH" | tr ':' '\n'

Создайте стабильный отчёт по переменным, ожидаемые значения которых известны в этой лабораторной работе:

cd /home/labex/project/environment-lab
printf 'HOME=%s\nUSER=%s\n' "$HOME" "$USER" > standard-environment.txt
cat standard-environment.txt

Расширение PATH личной командой

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

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

Создайте команду с именем course-status:

mkdir -p "$HOME/bin"
cat > "$HOME/bin/course-status" <<'EOF'
#!/bin/bash
echo "Linux learning environment is ready"
EOF
chmod +x "$HOME/bin/course-status"

Добавьте этот каталог в текущий PATH. Сохранение $PATH позволяет и дальше запускать стандартные команды:

export PATH="$PATH:$HOME/bin"

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

command -v course-status
cd /tmp
course-status

Сохраните её вывод в рабочем каталоге лабораторной работы:

course-status > /home/labex/project/environment-lab/path-command.txt

Сохранение настроек для будущих сеансов Zsh

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

Экспорт изменяет текущий процесс и его будущие дочерние процессы, но не редактирует файл конфигурации. Настройка появляется в последующих терминалах только тогда, когда файл запуска создаёт её заново. LabEx Terminal использует Zsh, а его файл запуска для интерактивных сеансов — ~/.zshrc.

Добавьте чётко обозначенный блок. Каждая строка export будет заново создавать одну переменную окружения при запуске нового интерактивного сеанса Zsh. В этом варианте для начинающих файл запуска остаётся намеренно простым: сначала сохраняется существующий PATH, затем в его конец добавляется личный каталог.

cat >> "$HOME/.zshrc" <<'EOF'
## LABEX_ENV_LAB_START
export PROJECT_DIR="$HOME/project"
export PATH="$PATH:$HOME/bin"
## LABEX_ENV_LAB_END
EOF

Команда source читает файл в текущей оболочке. Перечитайте .zshrc сейчас, чтобы использовать его настройки, не закрывая терминал:

source "$HOME/.zshrc"

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

printf 'PROJECT_DIR=%s\n' "$PROJECT_DIR"

Вы должны увидеть PROJECT_DIR=/home/labex/project. Также можно запустить новый процесс Zsh и проверить, что будущий сеанс загружает те же настройки. В zsh -ic параметр -i запрашивает интерактивную оболочку, поэтому читается .zshrc, а -c передаёт команду, которую должна выполнить эта оболочка. Перенаправьте две строки вывода в future-shell.txt, затем просмотрите файл:

zsh -ic 'printf "PROJECT_DIR=%s\n" "$PROJECT_DIR"; command -v course-status' > /home/labex/project/environment-lab/future-shell.txt
cat /home/labex/project/environment-lab/future-shell.txt

В первой строке должно быть /home/labex/project, а во второй — /home/labex/bin/course-status.

В завершение изучите разницу между текущим состоянием и постоянной конфигурацией. Создайте и удалите временную переменную окружения:

export TEMP_NOTE="remove me"
printenv TEMP_NOTE
unset TEMP_NOTE
printenv TEMP_NOTE

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

Итоги

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