Переменные окружения
| Что это | пары ИМЯ=значение в окружении процесса |
|---|---|
| Наследование | копируются от родителя к дочернему процессу |
| Просмотр | env, printenv, echo $ИМЯ |
| Установка в Bash | export ИМЯ=значение |
| Стандартные | PATH, HOME, USER, SHELL, LANG, TZ, PWD |
| Принцип конфигурации | The Twelve-Factor App — конфигурация в окружении |
Переменные окружения — именованные строковые значения вида ИМЯ=значение, которые есть у каждого процесса в Unix-подобных системах (и в Windows). Процесс получает копию окружения от родителя при запуске и может передать её — с изменениями — своим дочерним процессам.[1] Через переменные окружения программы узнают, где искать исполняемые файлы (PATH), домашний каталог пользователя (HOME), язык интерфейса (LANG), а приложения — адрес базы данных, режим работы и ключи доступа к API.
Переменные окружения — стандартный способ настраивать приложения, особенно в контейнерах и облаке.
Основы
echo $HOME # прочитать
printenv PATH # то же
env # все переменные окружения
export APP_ENV=production # установить для текущей оболочки и всех дочерних процессов
DEBUG=1 python app.py # установить только для одной команды
unset APP_ENV # удалить
Важно различать переменные оболочки и переменные окружения. Присваивание NAME=value в Bash создаёт переменную только в текущей оболочке; export делает её частью окружения, которое унаследуют запущенные программы.[3] Изменение окружения дочерним процессом никогда не влияет на родителя — поэтому скрипт, запущенный как ./set_env.sh, не может поменять переменные вашей оболочки; для этого его выполняют через source set_env.sh.
Стандартные переменные
| Переменная | Значение |
|---|---|
PATH |
каталоги через двоеточие, где оболочка ищет команды |
HOME |
домашний каталог пользователя |
USER, LOGNAME |
имя пользователя |
SHELL |
оболочка пользователя по умолчанию |
PWD |
текущий каталог |
LANG, LC_* |
язык и региональные настройки (ru_RU.UTF-8) |
TZ |
часовой пояс (Europe/Moscow) |
EDITOR |
редактор по умолчанию для git commit, crontab -e |
TMPDIR |
каталог для временных файлов |
Многие из них определены в стандарте POSIX.[2] Порядок каталогов в PATH важен: побеждает первая найденная программа. Узнать, какая именно запустится, помогает command -v python или which python.
Где задаются постоянно
~/.bashrc,~/.zshrc— для интерактивных оболочек пользователя;~/.profile,~/.bash_profile— для оболочек входа;/etc/environment,/etc/profile.d/*.sh— для всех пользователей;- в юнитах systemd — директивы
Environment=иEnvironmentFile=: службы не читают~/.bashrc; - в crontab — строки
ИМЯ=значениев начале файла (см. cron и таймеры systemd).
Конфигурация приложений
Методология The Twelve-Factor App рекомендует хранить конфигурацию, которая отличается между окружениями (разработка, тест, продакшен), в переменных окружения, а не в коде: один и тот же собранный артефакт запускается везде, меняются только переменные.[4]
import os
DATABASE_URL = os.environ["DATABASE_URL"] # обязательная — упадёт, если не задана
DEBUG = os.environ.get("DEBUG", "0") == "1" # необязательная со значением по умолчанию
WORKERS = int(os.getenv("WORKERS", "4"))
Все значения — строки, поэтому их нужно преобразовывать и проверять. Удобно делать это одной моделью настроек, например через pydantic-settings (см. Dataclasses и Pydantic).[5]
Файлы .env
При локальной разработке переменные хранят в файле .env в корне проекта:
DATABASE_URL=postgresql://app:secret@localhost:5432/app
REDIS_URL=redis://localhost:6379/0
DEBUG=1
Его загружают библиотеки вроде python-dotenv, Docker Compose (автоматически для подстановок в compose.yaml)[6] и uv run --env-file .env. Файл .env с реальными значениями никогда не коммитят — в Git кладут шаблон .env.example без секретов, а .env добавляют в .gitignore.
Контейнеры и Kubernetes
docker run -e APP_ENV=production --env-file prod.env myapp:1.0
В Kubernetes переменные контейнеров берутся из манифеста, ConfigMap и Secret (см. ConfigMap и Secret). Изменение переменной требует перезапуска процесса: окружение читается при старте и само не обновляется.
Секреты в переменных окружения
Переменные окружения — распространённый способ передать приложению пароли и ключи, но у него есть риски:
- окружение процесса может прочитать тот же пользователь или root через
/proc/<PID>/environ; - переменные наследуются всеми дочерними процессами, в том числе сторонними утилитами;
- они попадают в отчёты об ошибках, отладочный вывод и логи, если их неосторожно распечатать;
docker inspectпоказывает переменные контейнера.
Для чувствительных данных лучше использовать специализированные хранилища и монтирование секретов файлами (см. Управление секретами), а в переменных передавать хотя бы не больше, чем нужно.
Типичные ошибки
- Пробелы вокруг
=в Bash:export NAME = valueне работает, нужноexport NAME=value. - Значения с пробелами без кавычек:
export GREETING="Привет, мир". - Служба systemd или задача cron «не видит» переменную из
~/.bashrc— у них своё окружение. - Опечатка в имени необязательной переменной молча включает значение по умолчанию — обязательные настройки стоит проверять при старте.