Переменная окружения PATH
Довольно часто на наших курсах нам приходится работать с различными переменными окружения. Особый интерес у учеников вызывает переменная окружения PATH. В этой мини-статье решили рассказать о том, что это за переменная и зачем нужна нашей операционной системе.
Что такое переменная окружения
Для начала давайте определимся с тем, что вообще такое переменная окружения.
Переменная окружения — это то же самое, что и переменная в любом языке программирования. Для тех, кто никогда не писал код, проще всего объяснить это следующим образом. Это некая сущность, у которой есть имя и значение.
Если в языке программирования переменная существует только в рамках какой-то программы, то переменная окружения существует в рамках всей операционной системы и любая программа может к ней обратиться.
Нужны такие переменные как раз для этого — чтобы программы могли к ним обращаться и получать требующуюся им для работы информацию.
Например, давайте представим, что мы пишем программу, которая в ходе своей работы должна взаимодействовать с Java. На каждом компьютере она может находиться в разных местах. У меня в одной директории, у другого человека — в другой. Как нам написать программу, которая работала бы у всех?
Очень просто, мы пишем требование к нашей программе — в системе, где вы будете ее запускать, обязательно должна быть выставлена переменная окружения JAVA_HOME, содержащая путь до Java. Читая значение этой переменной наша программа будет понимать, где искать движок на том компьютере, на котором ее запустили.
Переменная окружения PATH
Переменная окружения PATH нужна прежде всего самой командной строке. Ее значение — это список директорий, в которых хранятся исполняемые файла. Директории перечислены через двоеточие. Например:
Тут две директории, перечисленные через двоеточие:
Сама по себе командная строка не знает, как выполнять какую-либо команду, которую мы вводим. После ее введения оболочка начинает поиск исполняемого файла этой команды как раз среди директорий, перечисленных в PATH.
Переменная окружения PATH существует как в Linux, так и в MacOS и Windows и везде работает одинаково.
По дефолту в PATH лежат только основные директории, но мы можем добавлять туда и новые после установки каких-то новых программ.
Дальнейшие команды будут работать только в командной оболочке bash в операционных системах Linux (например, Ubuntu) и MacOS. Если у вас Windows, повторить их можно, установив специальное расширение cygwin по нашему видео — https://www.youtube.com/watch?v=2csABC85onI
Чтобы узнать, какие директории уже указаны в PATH, можно распечатать ее содержимое:
Если директорий много, в таком виде читать ее содержимое не очень удобно и мы предлагаем использовать следующую команду:
Так получится гораздо нагляднее.
Чтобы узнать, в какой директории лежит исполняемый файл той или иной команды, необходимо ввести команду which. Например, давайте посмотрим, где лежит исполняемый файл команды ls:
Как редактировать переменную окружения PATH?
Для ОС Windows версии 8 и 10:
В строке «Поиск» выполните поиск: Система (Панель управления)
Нажмите на ссылку “Дополнительные параметры системы”
Нажмите “Переменные среды”
В разделе “Переменные среды” выберите переменную среды PATH
Нажмите “Изменить”
Если переменной PATH не существует, нажмите “Создать”
В окне “Изменение системной переменной” (или “Новая системная переменная”) укажите значение переменной среды PATH
Нажмите “ОК”
Откройте заново окно командной строки (если она была открыта)
Для MacOS и Linux переменная окружения PATH обычно дополняется через системные файлы .bashrc и .bash_profile
Вот и все, что нужно знать о переменной окружения PATH, чтобы начать с ней работать.
Приходите на наш курс Bash — инструменты тестировщика, там мы рассказываем это и многое другое для того, чтобы наши ученики чувствовали себя уверенным пользователем Linux и MacOS и могли эффективно работать с любой командной оболочкой.
А если хочешь почувствовать себя настоящим профессионалом командной строки, покупай пакет курсов Консольные утилиты PRO с хорошей скидкой.
Учитесь новому каждый день! 🙂
Environment variables (Русский)
Состояние перевода: На этой странице представлен перевод статьи Environment variables. Дата последней синхронизации: 19 октября 2023. Вы можете помочь синхронизировать перевод, если в английской версии произошли изменения.
- Приложения по умолчанию
- systemd/Пользователь#Переменные окружения
Переменная окружения — именованный объект, содержащий текстовую информацию, которую могут использовать запускаемые программы. Проще говоря, это переменная с именем и значением. Значением такой переменной может быть, например, место размещения исполняемых файлов в системе, имя предпочитаемого текстового редактора или настройки системной локали. Новые в Linux пользователи часто находят такой способ хранения настроек неудобным. Однако переменные окружения позволяют простым и надёжным способом передавать настройки сразу для множества приложений.
Утилиты
Пакет coreutils содержит программы printenv и env. Программа printenv позволяет отобразить список текущих переменных окружения и их значения:
$ printenv
Примечание: Некоторые переменные окружения относятся к конкретному пользователю в системе. Вы можете убедиться в этом, сравнив выводы команды printenv, запущенной обычным пользователем и суперпользователем.
Программа env может быть использована для запуска команд с указанием нового значения переменной окружения. В следующем примере будет запущен xterm, для которого переменная окружения EDITOR имеет значение vim . Такой вызов не затронет переменную окружения EDITOR в текущем сеансе терминала.
$ env EDITOR=vim xterm
Встроенная в командную оболочку команда set(1p) позволяет вам устанавливать значения переменных окружения в текущем сеансе терминала, а также отображать имена и значения переменных окружения текущего сеанса.
Чтобы увидеть переменные окружения конкретных процессов, откройте файл /proc/pid/environ , где pid — числовой идентификатор интересующего процесса. Записи в этом файле отделены друг от друга нулевым байтом ( \x0 ), который обычно не виден в терминале. Вы можете использовать, например, sed для отображения переменных окружения процесса в более читабельном формате, заменив нулевые байты на переносы строки: sed ‘s:\x0:\n:g’ /proc/$PID/environ
Установка переменных
Чтобы избежать замусоривания переменных окружения, стоит по возможности ограничивать области действия переменных. Кроме того, графические сеансы и службы systemd требуют установки переменных в определённых местах, чтобы они сработали. Область действия переменных окружения разделяется на контексты, на которые они влияют:
- системный — все программы у любых пользователей, кроме служб systemd;
- пользовательский — все программы определённого пользователя, кроме служб systemd (смотрите systemd/Пользователь#Переменные окружения) или графических окружений (смотрите раздел #Графические приложения).
На системном уровне
С помощью файлов инициализации оболочки
Большинство дистрибутивов Linux советуют изменять или добавлять переменные окружения в /etc/profile или других местах. Имейте в виду, что сразу множество файлов могут содержать переменные окружения и переопределять их, вроде /etc/locale.conf . По сути, любой скрипт может быть использован для этого, однако по принятым в UNIX соглашениям следует использовать для этого только определённые файлы.
Для установки переменных окружения на уровне всей системы можно использовать следующие файлы (каждый со своими ограничениями):
- /etc/environment используется модулем pam_env. Он не привязан к командным оболочкам, поэтому скрипты или glob-выражения использовать здесь нельзя. Здесь можно указывать только пары имя=значение .
- /etc/profile устанавливает переменные только в оболочках входа (когда пользователь выполняет вход в систему). В нём можно запускать скрипты (например, запускаются скрипты из каталога /etc/profile.d/ ) и он может использоваться в оболочках, совместимых с Bourne shell.
- Файлы настроек, специфичные для конкретных командных оболочек — глобальные файлы настроек для вашей командной оболочки, инициализирует переменные и запускает скрипты. Например, Bash (Русский)#Файлы настроек (например, ~/.bashrc ) или Zsh (Русский)#Файлы запуска/завершения (например, ~/.zshrc ).
Ниже приведён пример скрипта, который создаёт функцию для добавления нескольких каталогов (например, ~/bin и ~/scripts ) в PATH . Чтобы это сделать, просто поместите код в один из системных файлов инициализации окружения ( /etc/profile или /etc/bash.bashrc ):
set_path()< # Проверяем, что id пользователя 1000 или больше [ "$(id -u)" -ge 1000 ] || return for i in "$@"; do # Проверяем существование каталога [ -d "$i" ] || continue # Проверяем, что его ещё нет в $PATH. echo "$PATH" | grep -Eq "(^|:)$i(:|$)" && continue # Затем добавляем в $PATH и экспортируем переменную export PATH="$:$i" done > set_path ~/bin ~/scripts
Одним из способов использования общих переменных окружения в разных оболочках является создание файла без комментариев, пустых строк и пробелов (bash), который может быть прочитан непосредственно программой envsubst (вдохновлено [1]):
EDITOR=vim XDG_CACHE_HOME=$HOME/.cache XDG_CONFIG_HOME=$HOME/.config XDG_DATA_HOME=$HOME/.local/share XDG_STATE_HOME=$HOME/.local/state
bashrc
export $(envsubst < .env)
config/fish/config.fish
export (envsubst < .env)
С помощью pam_env
PAM-модуль pam_env(8) загружает переменные для прописывания в окружение из этих файлов в указанном порядке: /etc/security/pam_env.conf и /etc/environment .
- Эти файлы считываются перед другими файлами, в частности перед ~/.profile , ~/.bash_profile и ~/.zshenv .
- Устаревший файл ~/.pam_environment больше не считывается. Смотрите FS#68945.
/etc/environment должен содержать только простые пары вида ПЕРЕМЕННАЯ=значение на отдельных строках, например:
EDITOR=nano
/etc/security/pam_env.conf имеет формат:
ПЕРЕМЕННАЯ [DEFAULT=значение] [OVERRIDE=значение]
@ и @ являются специальными переменными, значение которых берётся из /etc/passwd . Следующий пример показывает, как использовать переменную HOME внутри другой переменной:
XDG_CONFIG_HOME DEFAULT=@/.config
Примечание: Переменные $ и $ не связаны с переменными окружения HOME и SHELL , по умолчанию они не задаются.
Формат также позволяет расширить уже определённые переменные значениями из других переменных с помощью $ПЕРЕМЕННАЯ> , например:
GOPATH DEFAULT=$/go
Пары ПЕРЕМЕННАЯ=значение тоже допускаются, но расширение переменных здесь не поддерживается. Подробнее смотрите pam_env.conf(5) .
На уровне пользователя
Не всегда требуется устанавливать переменные окружения на уровне системы. Например, вы можете захотеть добавить свой каталог /home/пользователь/bin в PATH , однако не хотите, чтобы это затрагивало других пользователей системы. Пользовательские переменные окружения можно устанавливать во многих файлах:
- Файлы инициализации командной оболочки, например Bash (Русский)#Файлы настроек или Zsh (Русский)#Файлы запуска/завершения.
- Если вы не хотите ограничить область действия переменных только открытыми терминалами (например, только для приложений командной строки), вы скорее всего хотите изменить параметры оболочки входа.
Например, чтобы добавить каталог в PATH , поместите следующее в ~/.bash_profile :
export PATH
Для применения изменений перелогиньтесь или выполните source: $ source ~/.bash_profile .
Примечание: Демон dbus и пользовательский экземпляр systemd не наследуют никакие переменные окружения из мест вроде ~/.bashrc . Это означает, что, например, активируемые через dbus программы вроде GNOME Files не будут использовать их по умолчанию. Смотрите systemd/Пользователь#Переменные окружения.
Совет: С помощью команды export -p можно просмотреть глобальные и локальные переменные окружения, объявленные для пользовательского сеанса.
Графические приложения
Если переменная окружения влияет только на графические приложения, можно ограничить область её применения, установив её только в рамках графического сеанса. В порядке сужения области:
- #На уровне Xorg или #На уровне Wayland — охватывают весь графический сеанс, в том числе наверняка среду рабочего стола;
- #На уровне графического сеанса — охватывает приложения, запущенные в рамках графического сеанса, в том числе, возможно, и среду рабочего стола;
- #На уровне приложения — только для отдельного графического приложения.
На уровне графического сеанса
Некоторые графические окружения (например, KDE Plasma), поддерживают запуск скриптов при входе: можно использовать их для установки переменных окружения. Пример есть в статье KDE (Русский)#Автозапуск приложений.
На уровне Xorg
Установка переменных окружения для сеанса Xorg зависит от того, каким конкретно способом он запускается:
- Большинство экранных менеджеров выполняют source файла xprofile.
- startx и SLiM выполняют xinitrc.
- XDM выполняет ~/.xsession ; смотрите XDM (Русский)#Определение сеанса.
- SDDM дополнительно выполняет source скриптов оболочек входа, вроде ~/.bash_profile для bash или ~/.zprofile и ~/.zlogin для zsh. [2]
Хотя конец скрипта зависит от того, какой это файл, а любой расширенный синтаксис зависит от используемой оболочки, базовое использование универсально:
~/.xprofile, ~/.xinitrc или ~/.xsession
. export ПЕРЕМЕННАЯ=значение .
На уровне Wayland
Так как Wayland не использует Xorg-специфичные файлы, GDM и KDE Plasma вместо них загружают пользовательские переменные окружения systemd.
~/.config/environment.d/envvars.conf
ПЕРЕМЕННАЯ=значение
Другие экранные менеджеры (например, SDDM) пока что не поддерживают это напрямую. Однако SDDM выполняет source скриптов оболочек входа и для сеансов Wayland тоже.
Если ваш экранный менеджер выполняет скрипты запуска вроде ~/.bash_profile и вы хотите использовать environment.d , то с помощью run-parts можно сделать так:
~/.bash_profile
# использует systemd-environment-d-generator(8) для генерации переменных окружения и экспортирует их export $(run-parts /usr/lib/systemd/user-environment-generators | sed '/:$/d; /^$/d' | xargs)
Примечание: Этот код запускает все исполняемые файлы в каталоге /usr/lib/systemd/user-environment-generators , что может быть как желательным, так и нежелательным. Если нужно, запускайте /usr/lib/systemd/user-environment-generators/30-systemd-environment-d-generator напрямую.
На уровне приложения
Чтобы установить переменные окружения только для определённого приложения вместо целого сеанса, измените .desktop файл этого приложения. Смотрите Ярлыки приложений#Изменение переменных окружения.
Для игры из Steam можно настроить окружение, отредактировав её параметры запуска.
На уровне сеанса или оболочки
Иногда бывает нужно установить временную переменную окружения. Например, если нужно временно запускать исполняемые файлы из определённого каталога, но не хочется вводить абсолютный путь к каждому из них или редактировать настройки командной оболочки на время работы с ними.
В таком случае можно определить переменную PATH в текущем сеансе с помощью команды export. Пока командная оболочка продолжает работать, все запускаемые в ней процессы будут использовать изменённое значение переменной.
$ export PATH="$:/home/my_user/tmp/usr/bin"
Примеры
В этом разделе описываются типовые переменные окружения, используемые в Linux.
- XDG_CURRENT_DESKTOP — это переменная freedesktop.org, содержащая список разделённых двоеточиями строк, которыми идентифицируется среда рабочего стола[3]. Стандартные значения — GNOME , GNOME-Flashback , KDE , LXDE , LXQt , MATE , TDE , Unity , XFCE , EDE , Cinnamon , Pantheon и DDE [4].
- Cinnamon был зарегистрирован позже других сред. В итоге некоторые приложения по-прежнему ожидают старое нестандартное значение X-CINNAMON , например Qt[5].
- XDG_SESSION_DESKTOP похожа на XDG_CURRENT_DESKTOP , но допускает использование только одной строки. Несмотря на название, переменная не входит в стандарт freedesktop.org.
- DE — более старая переменная для обозначения текущей среды рабочего стола (Desktop Environment). Её значения не стандартизированы, но можно ориентироваться на xdg-utils как на справочник типовых значений для многих сред рабочего стола.
- DESKTOP_SESSION — ещё одна старая переменная, но используется реже, чем DE . Значение также может быть путём к файлу .desktop сеанса в каталоге /usr/share/xsessions/ [6].
- WINDOW_MANAGER — переменная, иногда используемая для выбораоконного менеджера, который будет использоваться в среде рабочего стола. Это отличает её от других упомянутых здесь переменных, которые устанавливаются уже выбранным экранным менеджером или средой рабочего стола и используется для чтения другими программами.
- PATH содержит список каталогов, разделённых двоеточиями, в которых система ищет исполняемые файлы. Когда обычная команда (например, ls, systemctl или pacman) интерпретируется командной оболочкой (например, bash или zsh), оболочка ищет исполняемый файл с указанным именем в каталогах из этого списка и, если находит, запускает файл, передав ему указанные аргументы командной строки. Чтобы запускать исполняемые файлы, пути к которым не находятся в PATH , необходимо указывать относительный или абсолютный путь к файлу, например ./a.out или /bin/ls .
Примечание: Из соображений безопасности, не рекомендуется включать текущий каталог ( . ) в список PATH , так как это может спровоцировать случайный запуск вредоносного исполняемого файла.
- HOME содержит путь к домашнему каталогу текущего пользователя. Эта переменная может использоваться приложениями для определения расположения файлов настроек пользователя, который их запускает.
- PWD содержит путь к текущему рабочему каталогу.
- OLDPWD содержит путь к предыдущему рабочему каталогу, то есть, значение PWD перед последним вызовом cd.
- TERM содержит тип запущенного терминала, например xterm-256color . Это используется некоторыми программами, которые хотят знать возможности текущего терминала.
- MAIL содержит путь к каталогу, где сохраняется входящая почта. Обычно имеет значение /var/spool/mail/$LOGNAME .
- ftp_proxy и http_proxy содержат адреса прокси-серверов для протоколов FTP и HTTP соответственно:
ftp_proxy="ftp://192.168.0.1:21" http_proxy="http://192.168.0.1:80"
- MANPATH содержит разделённый двоеточиями список каталогов, которые использует man для поиска man-страниц.
Примечание: В /etc/profile есть комментарий "Man is much better than us at figuring this out", так что эту переменную обычно стоит не задавать. Смотрите manpath(5) .
- INFODIR содержит разделённый двоеточиями список каталогов, которые использует info для поиска info-страниц, например /usr/share/info:/usr/local/share/info .
- TZ может использоваться для установки временной зоны. Можно ссылаться на файл из /usr/share/zoneinfo/ , например TZ=":/usr/share/zoneinfo/Europe/Moscow" , тогда перед путём к файлу должно стоять двоеточие (смотрите документацию GNU).
Программы по умолчанию
- SHELL содержит путь к предпочитаемой командной оболочке текущего пользователя. Имейте в виду, что это не обязательно совпадает с текущей работающей оболочкой. Если значение не указано, Bash автоматически устанавливает в качестве её значения оболочку входа, прописанную в файле /etc/passwd , или /bin/sh , если это не удаётся определить.
- PAGER указывает команду для запуска программы постраничного просмотра содержимого текстовых файлов, например, /bin/less .
- EDITOR содержит команду для запуска программы для редактирования текстовых файлов, например /usr/bin/nano . Также можно задать специальную команду, которая будет выбирать редактор в зависимости от окружения, например, gedit в X или nano в терминале, как в этом примере:
[ -n "$DISPLAY" ] && export EDITOR=gedit || export EDITOR=nano
- VISUAL позволяет указать имя продвинутого текстового редактора для более сложных задач, например, редактирования почты. Это могут быть vi , vim, emacs и т. д.
- BROWSER содержит команду для запуска веб-браузера. Может быть полезно устанавливать это значение в зависимости от наличия графического окружения:
[ -n "$DISPLAY" ] && export BROWSER=firefox || export BROWSER=links
Совет: При прописывании программ по умолчанию также можно ориентироваться на переменную WAYLAND_DISPLAY , наличие которой указывает на то, что запущен Wayland-композитор.
Смотрите также
- Gentoo:Handbook:X86/Working/EnvVar
- Ubuntu Community Wiki - Environment Variables
Переменные окружения — Основы командной строки
Команда cd без аргументов делает домашнюю директорию пользователя рабочей. Возникает вопрос, каким образом она узнает о том, где находится домашняя директория?
Можно предположить, что команда cd каким-то образом обращается к операционной системе и узнает у нее эту информацию или смотрит напрямую в конфигурационных файлах. Но ни первого, ни второго она не делает.
Эта команда ориентируется на так называемую переменную окружения, которую мы изучим в этом уроке.
Что такое переменные окружения
Переменные окружения похожи на переменные в языках программирования. Они существуют в рамках запущенной сессии командной оболочки, то есть, переменные пропадут, когда терминал закроется. Они подгружаются туда во время его инициализации, хотя это не единственный путь их появления.
Посмотреть установленные переменные можно командой env (environment). Ниже неполный список этих переменных, которые доступны на одном из серверов Хекслета:
env TERM=xterm-256color SHELL=/bin/bash LC_ALL=en_US.UTF-8 USER=kirill.m HEXLET_VERSION=v2711 PATH=/home/kirill.m/bin:/home/kirill.m/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin PWD=/home/kirill.m LANG=en_US.UTF-8 SHLVL=1 HOME=/home/kirill.m LOGNAME=kirill.m
Формат вывода очень простой: слева от знака равно расположено имя переменной, справа — значение. В вашем случае вывод команды env будет отличаться не только значениями этих переменных, но и их составом. Например, у вас точно не будет HEXLET_VERSION , но наверняка будет HOME , только с другим значением.
Основное предназначение переменных окружения — конфигурирование системы и программ. Их удобство заключается в универсальности. Кроме того, они помогают отвязать нас от способа появления этих значений в системе.
Возьмем для примера ту же команду cd . Она знает лишь то, что домашняя директория доступна в переменной окружения HOME . Как она попала в систему — не важно.
Без переменной окружения пришлось бы делать одну из двух вещей:
- При вызове cd каждый раз указывать, где находится домашняя директория. Например, так: cd --home-dir /home/kirill.m . Такой способ убивает весь смысл быстрого перехода в домашнюю директорию
- Договариваться, что где-то будет храниться специальный файл с настройками, в том числе домашней директории. Настройки из этого файла будут читаться командой cd при каждом запуске
Существует некоторый базовый набор переменных, которые всегда устанавливаются bash при старте. Они используются большим количеством утилит и нужны для нормального функционирования системы. Одну из таких переменных мы уже знаем — это HOME :
# Для вывода переменной используется echo, # а перед самой переменной ставится знак $ echo $HOME /home/kirill.m # Вокруг знака `=` не должно быть пробелов HOME=/tmp echo $HOME /tmp # Возвращаем обратно HOME=/home/kirill.m echo $HOME /home/kirill.m
Теперь проведем эксперимент: попробуем установить HOME и выполнить переход в эту директорию с помощью команды cd , которая должна отправить нас в домашнюю директорию:
# Достаточно выполнить присваивание слева от запускаемой команды HOME=/tmp cd /tmp pwd /tmp
Команда cd выполнила переход по пути, указанном в переменной HOME . Теперь снова сделаем cd , но не добавляя определение переменной слева:
cd pwd /home/kirill.m echo $HOME /home/kirill.m
В этот раз произошел переход в настоящую домашнюю директорию. Получается, что вызов HOME=/tmp cd изменил переменную только для того конкретного запуска. И действительно, существует два способа задавать значение переменной окружения: локальный и глобальный.
Когда мы указали HOME=/tmp прямо перед командой cd , то переменная не была изменена для текущей сессии — она была изменена для запущенной команды, в данном случае cd . Такой трюк можно проделывать с любой командой.
Другой способ установки изменяет значение глобально, для всей сессии и выполняется так:
echo $HOME /home/kirill.m export HOME=/tmp cd pwd /tmp echo $HOME /tmp
Обратите внимание, что изменение происходит в рамках текущей сессии. Другими словами, если у нас открыто две вкладки терминала, то изменение произойдет только в той вкладке, в которой мы написали команду.
Особую роль среди переменных окружения играет PATH — еще одна важная переменная. Сложности с ней возникают настолько часто, что этой переменной посвящен практически целый урок впереди.
Самостоятельная работа
Изучите переменные окружения в вашей локальной среде, набрав команду env .
Дополнительные материалы
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Об обучении на Хекслете
- Статья «Как учиться и справляться с негативными мыслями»
- Статья «Ловушки обучения»
- Статья «Сложные простые задачи по программированию»
- Вебинар « Как самостоятельно учиться »
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно
- 130 курсов, 2000+ часов теории
- 1000 практических заданий в браузере
- 360 000 студентов
Наши выпускники работают в компаниях:
Переменные окружения в Node.js: полное руководство
В этой статье мы рассмотрим переменные окружения (environment variables). По сути, это пары ключ-значение набора данных, которые хранятся на уровне операционной системы.
В этой статье мы узнаем о переменных окружения в Node.js с примерами. Содержание:
- Что такое переменные окружения
- Почему переменные окружения важны
- Необходимые условия для проекта
- Установка Node.js и настройка нового проекта
- Инициализация первой переменной окружения в Node.js
- Переменные окружения при вызове API / асинхронные задачи
- Переменные окружения в операциях с базой данных / асинхронные задачи
- Расширенные возможности работы с переменными окружения в Node.js: кодирование, валидация и преобразование типов
- Управление секретами и лучшие практики безопасности с примерами
- Подводные камни и как их избежать
Переменные окружения
Переменные окружения — это набор данных в виде пар ключ-значение, доступных на уровне операционной системы. Этот набор данных доступен во всех основных оболочках командной строки операционных систем Windows, Mac и Linux.
Почему переменные окружения важны?
- Разделение проблем
- Безопасность
- Переносимость
- Масштабируемость
- Совместимость
- Интероперабельность
Необходимые условия для этого проекта
Предполагается, что у вас есть:
- Базовые знания Node.js
- Базовые знания JavaScript
- Некоторые знания о разработке бэкенда
Установка Node и настройка проекта
Установить Node.js на машину можно разными способами. Для начала нужно зайти на официальный сайт Node и скачать оттуда нужную версию.
Давайте рассмотрим установку Node.js в операционной системе Linux, предпочтительно Ubuntu
Шаг 1. Откройте терминал
Шаг 2. Используйте скрипт curl или wget для установки nvm, используя git-репозиторий nvm. Запустите скрипт для установки nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash # OR wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
Шаг 3. Закройте и снова откройте терминал и выполните следующие действия, чтобы применить скрипт
export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
Шаг 4. Подтверждение установки
Убедиться, что NVM установлен в вашей системе, можно с помощью следующей команды:
nvm --version
*Шаг 5. * Установка Node
Введите следующую команду для установки последней версии node:
nvm install latest
nvm install --lts
Шаг 6. Установка версии по умолчанию
Чтобы установить версию Node, которая будет использоваться в вашей системе по умолчанию, используйте команду:
nvm alias default 20.8.0
Шаг 7. Проверка установки
Чтобы проверить, установлен ли Node, введите команду:
node -v # сообщает текущую версию node в вашей системе. В нашем случае это 20.8.0
Инициализация проекта
Теперь, когда мы установили Node, давайте создадим новый проект, в котором мы будем использовать переменную окружения.
Создайте новую директорию, назовите ее env-demo и перейдите в нее:
mkdir env-demo cd env-demo
Теперь введите команду для инициализации нового проекта и заполните поля по своему усмотрению.
npm init
package name: (env-demo) version: (1.0.0) description: entry point: (index.js) test command: git repository: keywords: author: license: (ISC)
В итоге будет создан файл package.json, который будет выглядеть примерно так:
< "name": "env-demo", "version": "1.0.0", "description": "", "main": "index.js", "scripts": < "test": "echo \"Error: no test specified\" && exit 1" >, "author": "", "license": "ISC" >
Инициализация первой переменной окружения
Шаг 1: Установите пакет dotenv
Сейчас у вас инициализирован проект в приведенном выше разделе и создан файл package.json . Чтобы установить пакет node dotenv, который используется для создания env-файлов, введите в терминале команду:
npm install dotenv --save
Пакет dotenv будет установлен и сохранен как зависимость в файле package.json. Это должно выглядеть примерно так:
< "name": "env-demo", "version": "1.0.0", "description": "", "main": "index.js", "scripts": < "test": "echo \"Error: no test specified\" && exit 1" >, "author": "", "license": "ISC", "dependencies": < "dotenv": "^16.3.1" >>
Шаг 2 Создание файла .env
- В корневой папке создайте новый файл и назовите его .env .
- Откройте его в текстовом редакторе и создайте несколько пар ключ-значение. Это ваши переменные окружения. Вот пример
DATABASE_URL=sample-database-url PORT=3000 SECRET_KEY=mysecretkey
Шаг 3. Загрузка и чтение переменных окружения
В корневой папке создайте файл index.js, затем откройте терминал и введите следующую команду для установки Express.js:
npm install express --save
Express будет установлен и сохранен в качестве зависимости в файле package.json . Файл package.json будет выглядеть следующим образом:
< "name": "env-demo", "version": "1.0.0", "description": "", "main": "index.js", "scripts": < "test": "echo \"Error: no test specified\" && exit 1" >, "author": "", "license": "ISC", "dependencies": < "dotenv": "^16.3.1", "express": "^4.18.2" >>
и структура вашего проекта выглядит следующим образом:
Теперь откройте файл index.js и введите следующую команду, чтобы запустить простой веб-сервер.
const express = require('express'); const app = express(); const port = 4000; // defaults to 4000 app.get('/', (req, res) => < res.send('Hello World!') >) app.listen(port, () => < console.log(`Server running on http://localhost:$/`); >);
запустите код с помощью
node index.js
и перейдите на localhost://4000, чтобы получить hello world
Загрузка и чтение файла .env
Теперь, когда сервер запущен, давайте прочитаем файл .env , который мы создали в предыдущем шаге, и загрузим данные о порте из файла .env .
Откроем файл index.js и «потребуем» там библиотеку dotenv :
require('dotenv').config()
Теперь вы можете получить доступ к файлу .env с помощью process.env . Давайте воспользуемся process.env для доступа к номеру порта в файле index.js :
const express = require('express'); require('dotenv').config() const app = express(); const port = process.env.PORT || 4000; // Read from .env if not available then defaults to 4000 app.get('/', (req, res) => < res.send('Hello World!') >) app.listen(port, () => < console.log(`Server running on http://localhost:$/`); >);
Теперь давайте перезапустим сервер и перейдем на localhost://3000 . Вместо того, чтобы работать на 4000, наш сервер теперь работает на порту 3000, который он взял из файла .env
Вы также можете увидеть это в консоли:
Итак, вы успешно создали и сохранили файл env на своей машине.
В качестве другого примера вы можете получить доступ к DATABASE_URL следующим образом:
const dbUrl = process.env.DATABASE_URL; // Use dbUrl to connect to your database
index.js
const express = require('express'); require('dotenv').config() const app = express(); const port = process.env.PORT || 4000; // Read from .env if not available then defaults to 4000 app.get('/', (req, res) => < res.send('Hello World!') >) app.listen(port, () => < console.log(`Server running on http://localhost:$/`); >);
package.json
< "name": "env-demo", "version": "1.0.0", "description": "", "main": "index.js", "scripts": < "test": "echo \"Error: no test specified\" && exit 1" >, "author": "", "license": "ISC", "dependencies": < "dotenv": "^16.3.1", "express": "^4.18.2" >>
.env
DATABASE_URL=sample-database-url PORT=3000 SECRET_KEY=mysecretkey
Как использовать переменные окружения в асинхронных задачах
В этом разделе мы поговорим о том, как переменные окружения можно использовать в асинхронных задачах, таких как вызов API или операции с базой данных.
Переменные окружения особенно важны в этих задачах, потому что их можно использовать для безопасного хранения учетных данных и конечных точек.
Кроме того, эти переменные можно автоматизировать, поскольку они меняются в разных средах, таких как разработка, стейджинг и продакшен.
Шаг 1. Настройка переменных окружения
Откройте файл .env и отредактируйте его следующим образом:
API_URL=https://jsonplaceholder.typicode.com/todos/1 API_KEY=sfjks4325 PORT=3000
Шаг 2. Использование async / await с переменными окружения
Далее установите библиотеку axios, чтобы выполнять вызовы на удаленный сервер:
npm install axios --save
Эта команда установит axios и сохранит ее как зависимость в файле package.json.
Файл package.json должен выглядеть примерно так:
< "name": "env-demo", "version": "1.0.0", "description": "", "main": "index.js", "scripts": < "test": "echo \"Error: no test specified\" && exit 1" >, "author": "", "license": "ISC", "dependencies": < "axios": "^1.5.1", "dotenv": "^16.3.1", "express": "^4.18.2" >>
Далее используйте axios для выполнения вызовов сайта jsonplaceholder и записи их в консоль.
Введите этот код в файл index.js
const express = require('express'); require('dotenv').config(); const axios = require('axios'); const app = express(); const port = process.env.PORT || 4000; // Read from .env if not available then defaults to 4000 const fetchData = async () => < const url = process.env.API_URL; const apiKey = process.env.API_KEY; try < const response = await axios.get(url, < headers: < 'Authorization': `Bearer $` > >); console.log(response.data); > catch (error) < console.error(`Error fetching data: $`); > >; app.get('/', (req, res) => < fetchData() res.send('Hello World!') >) app.listen(port, () => < console.log(`Server running on http://localhost:$/`); >);
Что мы здесь делаем:
- Импортируем модули express , dotenv , axios .
- Затем инициализируем приложение и порт с помощью переменных окружения.
- Затем создаем асинхронную функцию const fetchData = async ()=> (. )
- В этой функции мы используем url и apiKey из файла .env . Хотя я должен отметить, что вам не нужен apiKey для вызова сайта jsonplaceholder. Я просто поместил этот ключ для демонстрации.
- Записываем данные в консоль.
- Вызываем метод fetchData() на маршруте get. Таким образом, каждый раз, когда кто-то переходит на / , вызывается метод и данные записываются в консоль.
Использование Async/await с переменными окружения в операциях с базой данных
Давайте рассмотрим еще один пример. На этот раз мы будем выполнять операции с базой данных с помощью переменных окружения.
Шаг 1: Настройка переменных окружения.
Откройте файл .env в текстовом редакторе и введите следующее:
DB_HOST=localhost DB_PORT=5432 DB_NAME=mydatabase DB_USER=username DB_PASSWORD=password
Шаг 2: Установите библиотеку pg
Следующим шагом будет установка библиотеки pg :
npm install pg --save
*Шаг 3: * Подключитесь к базе данных и выполните асинхронный запрос с помощью файла .env
Напишите следующий код, чтобы подключиться к базе данных и использовать учетные данные .env, которые мы только что создали:
const < Pool >= require('pg'); require('dotenv').config(); const pool = new Pool(< host: process.env.DB_HOST, port: process.env.DB_PORT, database: process.env.DB_NAME, user: process.env.DB_USER, password: process.env.DB_PASSWORD >); const fetchUsers = async () => < try < const res = await pool.query('SELECT * FROM users'); console.log(res.rows); >catch (err) < console.error(`Error fetching users: $`); > >; fetchUsers();
Мы не интегрируем этот пример в нашу обычную кодовую базу, потому что он является исключением и не будет полезен в дальнейшем в этом руководстве.
Расширенные возможности работы с переменными окружения в Node JS: кодирование, валидация и преобразование типов
Переменные окружения — это не только чтение и хранение. С помощью расширенных манипуляций с переменными окружения мы узнаем о:
- кодировании
- валидации и
- преобразовании типов
1. Кодирование
Кодирование используется для различных целей в переменных окружения, в том числе для обеспечения безопасности. Наиболее популярный тип кодировки — base64.
Кодирование:
const decodedData = Buffer.from(encodedData, 'base64').toString('utf-8'); console.log(`Decoded: $`);
2. Валидация
Валидация используется для проверки того, является ли код правильным или нет. Например, url, который вы собираетесь использовать — является ли он корректным или нет и т.д.
Или, как в этом примере, мы проверяем, находится ли номер порта в указанном диапазоне или нет.
const validatePort = (port) => < const parsedPort = parseInt(port, 10); if (isNaN(parsedPort) || parsedPort < 1024 || parsedPort >65535) < throw new Error('Invalid port number'); >return parsedPort; >; const port = validatePort(process.env.PORT);
3. Преобразование типа
Переменные окружения всегда имеют тип string. Но часто возникает необходимость использовать и другие типы данных, например int или booleans. Здесь поможет преобразование типов.
Пример целого числа:
const isProduction = process.env.NODE_ENV === 'production'; const retries = parseInt(process.env.RETRIES, 10) || 3;
Пример булевого значения
const shouldLog = process.env.SHOULD_LOG === 'true';
Комбинированный пример
Вот пример, объединяющий все расширенные манипуляции с env, доступные в переменных окружения.
// Encoding and decoding const apiKey = Buffer.from(process.env.API_KEY || '', 'base64').toString('utf-8'); // Validation if (apiKey.length !== 32) < throw new Error('Invalid API key length'); >// Type conversion const maxUsers = parseInt(process.env.MAX_USERS, 10); if (isNaN(maxUsers))
Управление секретами и лучшие практики безопасности с примерами
В этом разделе мы узнаем об управлении секретами и лучших практиках безопасности с примерами. Вот шаги, которые вы можете предпринять для защиты переменной окружения, а также их примеры.
1. Никогда не делайте коммит файлов .env
Всегда следите за тем, чтобы файлы .env находились в gitignore и никогда не коммитились в git-репозиторий.
# Ignore dotenv environment variables file .env
2. Хеширование пароля
Всегда хэшируйте пароли, хранение паролей в виде обычного текста — плохая практика. Для хэширования паролей можно использовать, например, библиотеку bcryt.
const bcrypt = require('bcrypt'); const saltRounds = 10; async function hashPassword(plainPassword)
3. Кодирование переменных окружения
В качестве меры безопасности всегда кодируйте секреты, обычно они имеют кодировку base-64.
const buffer = Buffer.from(process.env.MY_SECRET, 'base64'); const decodedSecret = buffer.toString('utf-8');
4. Централизованное управление секретами
Для крупных проектов можно рассмотреть сервисы централизованного управления секретами — например, hashicorp vault, AWS secrets manager.
Они предлагают такие расширенные функции, как ротация секретов, автоматическая аренда и ротация, а также ведение журнала аудита.
Вот пример с node vault:
const vault = require("node-vault")(< endpoint: "https://vault-endpoint", token: process.env.VAULT_TOKEN, >); async function getDatabaseCreds() < const data = await vault.read("path/to/secret"); return < user: data.data.username, password: data.data.password, >; >
5. Принцип наименьших привилегий
Всегда следуйте принципу наименьших привилегий. API, которые не требуют идентификационных данных на запись, никогда не должны получать привилегии на запись.
Подводные камни
- Хардкодинг служебной информации
- Отсутствие валидации
- Игнорирование окружения
- Неадекватная безопасность
- Плохая документация
- Возврат в предыдущее значение (Fallback) по умолчанию
Нужен Chat API для вашего сайта или приложения
Поставщиком Chat API является DeadSimpleChat
- Добавьте масштабируемый чат в приложение за считанные минуты
- Одновременно 10 миллионов пользователей
- Uptime 99,999%
- Фичи модерации
- Чат 1-1
- Групповой чат
- Полностью настраиваемый
- Чат API и SDK
- Предварительно созданный чат
Заключение
В этой статье мы узнали о переменных окружения и о том, как их использовать в Node.js.
Мы рассмотрели важные темы, связанные с управлением переменными окружения в Node.js. Этого должно быть достаточно для большинства случаев использования переменных окружения в приложениях Node.js.
Надеюсь, вам понравилась статья, и спасибо за чтение.
Всех разработчиков на JavaScript приглашаем на открытое занятие в OTUS «Построение графических приложений с применением библиотеки Konva.js». Записаться на урок можно на странице курса.
- node.js
- javascript
- переменные окружения
- Konva.js
- Блог компании OTUS
- JavaScript
- Node.JS