Рубрики
Uncategorized

Как установить переменные среды в Linux и Mac: Недостающее руководство

Большинство статей охватывают только основы, поэтому мы попытались создать «недостающее руководство» для использования переменных среды в Linux и Mac.

Автор оригинала: Doppler.

Эта статья изначально появилась на doppler.com И был написан Ryan Blunden, разработчик выступает в допплер.

Оглавление

Оглавление Каковы переменные среды? Разница между оболочкой и переменными окружающей среды Как изменить и установить переменные среды Как удалить переменную среды Окружающая среда Изменяемая синтаксис и лучшие практики Как зафиксировать вывод команды и назначьте его в переменную среду Использование двойных или одиночных кавычек для переменных среды Область применения переменных среды в оболочках и сценариях оболочки Настройка переменных среды для одной команды Как проверить, существует ли переменная среды Где установить переменные среды Как перечислить переменные среды Как перечислить все переменные оболочки и среды Общие переменные среды в Linux и Mac Использование переменных среды для секретов приложений и учетных данных Как выполнить скрипт в контексте текущей оболочки Как пройти через переменные среды при использовании Sudo Как выполнить команду или скрипт в «чистой» среде Как установить переменную среды, чтобы быть только для чтения Дополнительные ресурсы Резюме

Каковы переменные среды?

Значения переменных среды могут контролировать поведение операционной системы, отдельных утилит, таких как GIT, скрипты оболочки, пользовательские приложения, такие как браузер Google Chrome или развертываемые приложения, такие как веб-приложение Python.

Давайте посмотрим на основы для настройки и доступа к переменным среды, используя следующие команды:

# Setting an environment variable

# The `export` keywords essentially means "make this globally accessible"
# No spaces on either side of the equals sign.
# Quotes recommended
export FULL_NAME="Darth Vader"

# Getting an environment variable's value

# Note the $ prefix used for referencing
echo "Anakin Skywalker is now $FULL_NAME"
# >> Anakin Skywalker is now Darth Vader

Это только верхушка айсберга, поэтому давайте погрузимся глубже.

Разница между оболочкой и переменными окружающей среды

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

Переменные оболочки должны использоваться при необходимости только в текущей оболочке или скрипте, в котором они были определены.

# Shell variable as it does not use the `export` command
WOOKIE="Chewbacca"
echo "The Wookie's name is $WOOKIE"
# >> The Wookie's name is Chewbacca

Если вы открыли новую оболочку и запустили эхо Команда, Имя Переменная не существует, так как она была выделена только предыдущей оболочкой.

# In a new shell
echo "The Wookie's name is $WOOKIE"
# >> The Wookie's name is

Те же правила применяются к скриптам, например, если файл Shell-var-test.sh содержал следующее:

# shell-var-test.sh
echo "The Wookie's name is $WOOKIE"

И Shell-var-test.sh был запущен даже после Имя Было определено, это не доступно для скрипта.

WOOKIE="Chewbacca"
bash shell-var-test.sh
# >> The Wookie's name is

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

WOOKIE="Chewbacca"
python -c "import os; print(os.environ.get('WOOKIE'))"
# >> None

Переменные среды, с другой стороны, предназначены для подключения к сценариям или дочерним процессам и отличаться от переменных оболочек с помощью Экспорт команда.

export WOOKIE="Chewbacca"
bash shell-var-test.sh
# >> The Wookie's name is Chewbacca

Также верно, что любые переменные изменения внутри скрипта или нового процесса не влияют на оболочку, где они были выполнены, даже для переменных среды.

Мы углубимся в объем переменных среды в снарядах и сценариях оболочки позже в этой статье, а также как изменить поведение Scoping по умолчанию, узнав, как выполнить скрипт в контексте текущей оболочки _.____

Как изменить и установить переменные среды

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

export FAV_JEDI="Obi-Wan Kenobi"
echo "My favorite Jedi is $FAV_JEDI"
# >> My fav jedi is Obi-Wan Kenobi

FAV_JEDI="Rey Skywalker"
echo "My favorite Jedi is now $FAV_JEDI"
# >> My favorite Jedi is now Rey Skywalker

Вы также можете изменить переменную, используя свое исходное значение для создания нового значения. Вы, скорее всего, видели это раньше в ~/.bash_profile или ~/.bashrc Файл при добавлении каталога к $ Путь Переменная:

# Add the `~/bin` directory to $PATH for user scripts and self-compiled binaries
PATH=$PATH:~/bin

Обратите внимание, что мы не поставить Экспорт до Путь В этом примере, и это потому, что Путь уже был экспортирован, поэтому положить Экспорт снова ничего не делает.

Как удалить переменную среды

unset Команда используется для удаления переменной:

export FAV_DROID="R2-D2"
echo "My favorite droid is $FAV_DROID"
# >> My favorite droid is R2-D2

unset FAV_DROID
echo "My favorite droid is $FAV_DROID"
# >> My favorite droid is

Удаление переменной окружающей среды только влияет на текущую оболочку.

Окружающая среда Изменяемая синтаксис и лучшие практики

Вот некоторые правила и лучшие практики для назначения и использования переменных среды:

  • Имена переменной могут содержать только символы (A-Z, A-Z), цифры и подчеркивания
  • Нет пробелов по обе стороны от равенства
  • Конвенция об именах является Capited_snake_case.
  • Всегда окружающие значения с цитатами, например экспорт
  • Всегда объемные переменные использования с цитатами, например Echo «$ ключ»
  • Экспортируйте только переменную, если он будет использоваться сценарием, называемым из этой оболочки или дочернего процесса
  • Избегайте экспортирующих переменных, которые содержат конфиденциальную информацию, такой как токены API, устанавливая их только для одной команды.

Как зафиксировать вывод команды и назначьте его в переменную среду

Общим захват вывода команды, используя командную замену $ (…) и назначить его переменной. Например, назначить значение строки даты отформатированной строки:

TODAYS_DATE=$(date +"%B %-d, %Y")
echo "Today's date is $TODAYS_DATE"

Использование двойных или одиночных кавычек для переменных среды

Использование двойных или одиночных кавычек зависит от ваших требований и, как правило, всегда процитируйте свои значения, чтобы избежать непреднамеренных проблем разделения слов:

export FULL_NAME=Obi-Wan Kenobi
# >> bash: Kenobi: command not found 

FULL_NAME="Obi-Wan Kenobi"
echo "Help me $FULL_NAME. You're my only hope."
# >> Help me Obi-Wan Kenobi... You're my only hope

Двойные кавычки позволяют использовать переменную ссылка и замену команды $ (…) Например, получение текущего имени пользователя:

echo "My username is $(whoami) and I am currently in the $PWD directory"
# >> My username is ryan and I am currently in the /home/ryan/dev directory

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

export TRAVELLERS="Luke and Obi-Wan"
echo "Congratulations $TRAVELLERS, you've just won passage on the Millenium Falcon worth \$17,000"
# >> Congratulations Luke and Obi-Wan, you've just won passage on the Millenium Falcon worth $17,000

Другой вариант, вместо того, чтобы избежать зарезервированного символа, такого как $, использует отдельные кавычки, так как предотвращает переменную ссылка и замену команды, потому что строка не интерполизирована:

echo 'The $PWD env var is the path to the current working directory'
# >> The $PWD env var is the path to the current working directory

Наконец, если вы находитесь в ситуации, где V А R _ N А М Е * * F o R м D o е с N « T W o r к B е C . А U S е o F А м преступник i g u Я т y , t h е N уход o U N е е D T H е * * Var \ _name ** Форма не работает из-за неоднозначности, то вам нужно ** V А R _ N А М Е * * F o R м D o е с N « T W o r к B е C . А U S е o F А м преступник i g u Я т y , t h е N уход o U N е е D T H е * * {Var_name} Синтаксис вместо этого:

export FOO="foo"
echo "$FOObar" # Output will be empty as variable `$FOObar` does not exist
echo "${FOO}bar"
# >> foobar

Область применения переменных среды в оболочках и сценариях оболочки

Каждая команда, скрипт и приложение работает в собственном процессе, каждый из которых имеет уникальный идентификатор (обычно называемый PID ). Он может работать на несколько миллисекунд (например, ls -la ), или много часов, например, Визуальный студийный код или сервер приложений Python.

Чтобы увидеть это в действии, давайте запустим Спать Команда как фоновый процесс, добавление & После команды, поэтому мы видим его PID в оболочке:

# Run a command as a background process using `&` to see the PID of that command
sleep 5 &

При запуске команды или скрипта из оболочки текущая оболочка — родительский процесс и команда или скрипт — это Детский процесс , который имеет доступ только к переменным среды из текущей оболочки или родительского процесса.

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

Мы можем продемонстрировать это, используя подпульдую (…) Синтаксис или выполнение строки в качестве команды Bash:

# Subshell example
(export SUBSHELL_VAR='Test') && echo $SUBSHELL_VAR
# Empty output

# Child shell example by executing string with bash
bash -c "export SUBSHELL_VAR='Test'" && echo $SUBSHELL_VAR
# Empty output

В обоих случаях Subshell_var Переменная среды проживала и умерла в рамках дочернего процесса, в которой он был создан и не был виден родительским процессом.

Это может быть разумным, когда вы реализуете каждую команду, скрипт или приложение — это процесс, вплоть до PID 1, который является процессом, из которого наследуется каждый другой ребенок, даже если он не напрямую. Вы можете использовать PSTREE Команда (для пользователей Mac: Brew Установите PSTREE ), чтобы визуально видеть эту иерархию в действии.

Настройка переменных среды для одной команды

Иногда вы захотите разоблачить или изменять переменные среды только для жизни одной команды, сценария или детского процесса.

Чтобы продемонстрировать, мы будем использовать следующий скрипт Baby-yoda.sh :

# baby-yoda.sh
echo "Baby Yoda is named $BABY_YODA"

Во-первых, давайте посмотрим, как сделать это длинный и неэффективный способ:

export BABY_YODA="Grogu"
bash baby-yoda.sh
# >> Baby Yoda is named Grogu
unset BABY_YODA

Вместо этого мы можем превратить это в одну команду, определив переменную перед командой:

BABY_YODA="Grogu" bash baby-yoda.sh
# >> Baby Yoda is named Grogu

Теперь вам может быть интересно, что, если вы хотите временно разоблачить переменную среды нескольким командам? Это может не работать так, как вы ожидаете. Давайте попробуем запустить наш скрипт дважды, используя && синтаксис:

BABY_YODA="Grogu" bash baby-yoda.sh && bash baby-yoda.sh
# >> Baby Yoda is named Grogu
# >> Baby Yoda is named

Вторым вызовом скрипта не было Baby_yoda Набор вариабельной среды, потому что оболочка интерпретируется вышеуказанная команда как:

BABY_YODA="Grogu" bash baby-yoda.sh
bash baby-yoda.sh

Чтобы временно разоблачить переменную среды нескольким командам, мы можем пройти строку в Bash для выполнения:

BABY_YODA="Grogu" bash -c 'bash baby-yoda.sh && bash baby-yoda.sh'
# >> Baby Yoda is named Grogu
# >> Baby Yoda is named Grogu

Как проверить, существует ли переменная среды

В какой-то момент вам нужно условно проверить наличие переменной среды.

В большинстве ситуаций вы захотите проверить переменную установлена с непустойным значением, так что это то, что мы начнем с. Чтобы продемонстрировать, сохранить следующий код в Deathstar-attack.sh :

# deathstar-attack.sh
if [-z "$DEATHSTAR_SHIELD_DOWN"]; then 
    echo "Break off the attack! The shield is still up!"
else
    echo "The shield is down! Commence attack on the Death Star's main reactor!"
fi

Затем давайте выполним сценарий без определения DeathStar_shield_down Переменная:

bash deathstar-attack.sh
# >> Break off the attack! The shield is still up!

Сейчас с определением Deathstar_shield_down. :

export DEATHSTAR_SHIELD_DOWN="Yes"
bash deathstar-attack.sh
# >> The shield is down! Commence attack on the Death Star's main reactor!

Если с другой стороны, вы хотите проверить, устанавливается ли переменная и не волнует, если она пуста или нет, то используйте следующее, сохраняя ее в Death-star-attack-2.sh. :

# deathstar-attack-2.sh
if [-z "${DEATHSTAR_SHIELD_DOWN+x}"]; then 
    echo "Break off the attack! The shield is still up!"
else
    echo "The shield is down! Commence attack on the Death Star's main reactor!"
fi

Это работает, потому что $ {Deathstar_shield_down + x} Использует расширение параметра, которое для этой цели оценивает ничего, если DeathStar_shield_down не является

unset DEATHSTAR_SHIELD_DOWN
bash deathstar-attack-2.sh
# >> Break off the attack! The shield is still up!

export DEATHSTAR_SHIELD_DOWN=""
bash deathstar-attack-2.sh
# >> The shield is down! Commence attack on the Death Star's main reactor!

Где установить переменные среды

Где и как вы устанавливаете переменные среды, зависит от операционной системы, и хотите ли вы установить их на системе или отдельном уровне пользователя, а также какую оболочку вы используете, например, башмак или ZSH. (который сейчас по умолчанию в Mac).

Чтобы избежать просто повторения контента ради этого, проверьте эту отличную всеобъемлющую статью от Unix/Linux Stack Exchange Вопрос: Как навсегда установить экологические переменные Отказ

Как перечислить переменные среды

printenv Команда делает именно так, как она описывает, печатая все переменные среды доступны для текущей оболочки.

Вы можете комбинировать printenv с Греп Для фильтрации переменных среды списка:

Чтобы вывести значение определенной переменной окружающей среды, вы должны использовать также printenv. :

Возможно, вы думаете: «Разве вы не можете использовать Echo для этого»? И да, вы можете, но эхо Работает для переменных оболочек тоже, что делает printenv Превосходный, потому что он работает только для переменных среды.

Если вам интересно, как сказать, если printenv. Que_var на самом деле работал или Que_var Был просто пустым, вы можете осмотреть $? Переменная после Команда printenv И если код выхода был 0, вариабельная среда существует.

Как перечислить все переменные оболочки и среды

Можно перечислить как переменные оболочки, так и среды с использованием команды SET:

( set -o posix ; set ) | less

Вы заметите, что вы видите не только переменные, но функции тоже.

При использовании Bash вы можете использовать Compgen что менее шумно :

Общие переменные среды в Linux и Mac

Следующие переменные среды не являются исчерпывающим списком, но являются наиболее распространенными между Linux и Mac:

  • $ PATH: Разделенный из толстой кишки списка каталогов для поиска дворотов и сценариев, которые не нужен полный путь для их выполнения, например, E.G. эхо вместо /bin/echo как /bin в $ ДОРОЖКА
  • Дом $: Домашний каталог пользователя для текущей оболочки
  • $ Pwd: Расположение каталога в текущей оболочке
  • $ Shell: Исполняемый для текущей оболочки, например /bin/bash
  • $ HostName: Имя хоста текущего компьютера, как оно может появиться в вашей локальной сети

Использование переменных среды для секретов приложений и учетных данных

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

Это связано с тем, что контейнеры для виртуальных машин (VM) и Docker предоставляют среду песочницы для приложений для выполнения, поэтому любая вариабельная среда влияет только на то, что конкретное применение в этом VM или контейнере.

Поскольку приложения настраиваются по-разному от разработки до производства, настроить приложение с использованием переменных среды означает только значения должны изменяться при развертывании к разным средам, а не исходным кодом.

Переменные среды также должны использоваться для настройки рабочих мест CI/CD и сред, E.G, Действия GitHub.

Поставка конфигурации приложений и секретов, используя переменные среды, именно то, что Допплер CLI Делает, и наша миссия состоит в том, чтобы сделать это как можно быстрее, легко и безопасным, насколько это возможно с Интеграции для каждого крупного поставщика каждого облака и платформы Отказ

Как выполнить скрипт в контексте текущей оболочки

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

Пример — код автозаполнения Bash из Домашний вид На MacOS используя синтаксис ведущего периода:

# Load bash autocompletion code into the current shell
. /usr/local/Cellar/bash-completion/1.3_3/etc/bash_completion

Давайте продемонстрируем эту функциональность, загружая переменные в текущую оболочку, используя сценарий ниже, сохраняя его как Текущие-shell-vars.sh:

#!/usr/bin/env bash

COOL_DROID="R2-D2"
ANNOYING_DROID="C-3PO"

Затем сделайте исполняемый сценарий:

chmod +x current-shell-vars.sh

Просто выполнение скрипта сделает только переменные, доступные для кода внутри скрипта:

./current-shell-vars.sh
echo $COOL_DROID
# empty output

Для выполнения его в текущей оболочке мы префиксируем команду с ведущим периодом:

. ./current-shell-vars.sh
echo "$COOL_DROID is cool but $ANNOYING_DROID is pretty annoying"
# >> R2-D2 is cool but C-3PO is pretty annoying

Будьте очень осторожны с этой функциональностью, и только выполняют сценарии, которые вы абсолютно доверяете!

Если вам интересно, «не Источник сделать то же самое?» да, это делает, но это доступно только в Bash, поэтому вышеуказанная форма просто более портативна

Как пройти через переменные среды при использовании Sudo

По умолчанию для безопасности, команды, выполняемые как root, используя Sudo Не проходите через переменные среды из текущей оболочки, но вы можете переопределить это, используя — Отсутствует env флаг:

# Print the environment variables for the root user
sudo printenv
# Pass through the environment variables from the current shell
sudo --preserve-env printenv

Используйте это осторожность!

Как выполнить команду или скрипт в «чистой» среде

Иногда вы захотите выполнить команду или скрипт в «чистой» среде, лишенной всех переменных среды, используя env. -Я :

env -i printenv
# Empty output as no env vars exist

Как установить переменную среды, чтобы быть только для чтения

Чтобы сделать переменную среды (или функцию) только для чтения, просто используйте readly команда:

readonly export READONLY_VAR=1
READONLY_VAR=2
# >> READONLY_VAR: readonly variable

Дополнительные ресурсы

Там, очевидно, намного больше для программирования Shell, чем просто переменные среды, и вот три важных ресурса, которые требуют использования вашей оболочки и сценарии на следующий уровень:

Резюме

Удивительная работа!   Вы теперь знаете тонну отличных и практичных вещей о переменных средах для Linux и Mac, и мы надеемся, что вам понравилось путешествие!

Обратная связь приветствуется, и вы можете добраться до нас на Twitter наше Сообщественный форум или отправьте мне письмо на ryan.blunden [at] doppler [dot] com .

Оригинал: «https://www.codementor.io/@doppler/how-to-set-environment-variables-in-linux-and-mac-the-missing-manual-1ipt2bm9gh»