Окружающая среда не так волшебна, как может показаться. Оболочка сохраняет его в памяти и переходит к execve()
системному вызову. Дочерний процесс наследует его как вызываемый указатель массива environ
. Из execve
справочной страницы:
СИНТАКСИС
#include <unistd.h>
int execve(const char *filename, char *const argv[],
char *const envp[]);
argv
массив строк аргументов, переданных новой программе
По соглашению первая из этих строк должна содержать имя файла, связанное с исполняемым файлом. envp
представляет собой массив строк, обычно в форме ключ = значение, которые передаются в качестве среды для новой программы.
environ(7)
Страница руководства также предлагает некоторое представление:
СИНТАКСИС
extern char **environ;
ОПИСАНИЕ
Переменная environ
указывает на массив указателей на строки, называемые «окружением». Последний указатель в этом массиве имеет значение NULL
. (Эта переменная должна быть объявлена в пользовательской программе, но объявлена в заголовочном файле <unistd.h>
в случае, если заголовочные файлы были получены из libc4 или libc5, и если они пришли из glibc, и был определен _GNU_SOURCE.) Этот массив строк сделан доступным для процесс с помощью вызова exec (3), который запустил процесс.
Обе эти страницы руководства GNU соответствуют спецификации POSIX
exec(3)
семьи (т.е. те, которые не соответствуют exec * v) проходят ** под прикрытиями.exec*e
варианты, которые явно передают env вместо неявного использованияenviron
глобальной переменной. Значениеv
«вектор» и относится к аргументам командной строки, передаваемым в виде массива (а не «списка» (функция переменной длины)),execve
является системным вызовом, а все остальныеexec*
функции являются для него оболочками libc.Вы ошибаетесь:
SOME_NAME=value
создаете переменную оболочки (в большинстве оболочек).export SOME_NAME=value
создает переменную среды. К счастью, к худшему, большинство оболочек BSD Unix / Linux / * используют одинаковый синтаксис при доступе к переменным среды и переменным оболочки.В каком-то более широком смысле «среда» - это просто информация, которая сопровождает выполнение программы. В программах на языке Си, вы можете найти идентификатор процесса с
getpid()
вызовом, в программной оболочке вы будете использовать доступ к переменному:$$
. Идентификатор процесса является лишь частью среды программы. Я считаю, что термин «среда» происходит от некоторых более теоретических тем компьютерных наук, таких как моделирование выполнения программ. Модели выполнения программ имеют среду, «которая содержит ассоциации между переменными и их значениями».И последнее, более строгое определение - это «среда» для оболочек BSD Unix / Linux / *: связь между именами («переменными») и их значениями. Для большинства оболочек в стиле Unix значения являются символьными строками, хотя это не так строго, как раньше. В наши дни Ksh, Zsh и Bash имеют типизированные переменные. Даже определения функций оболочки могут быть экспортированы.
Использование среды, отдельной от простых переменных оболочки, включает
fork/exec
метод запуска нового процесса, который используют все Unixes. Когда выexport
используете пару имя / значение, эта пара имя / значение будет присутствовать в среде новых исполняемых файлов, запускаемых оболочкой с помощьюexecve(2)
системного вызова (обычно после afork(2)
, за исключением случаев, когда использоваласьexec
команда оболочки).После
execve()
,main()
функция new двоичного файла имеет свои аргументы командной строки, среду (хранится в виде массива указателей наvar=value
строки, заканчивающегося NULL , см.environ(7)
Справочную страницу). Другое наследуемое состояние включает в себяulimit
настройки, текущий рабочий каталог и любые дескрипторы открытых файлов, для которыхexecve()
вызывающему не было установлено FD_CLOEXEC. Текущее состояние tty (эхо-режим, необработанный режим и т. Д.) Также может рассматриваться как часть состояния выполнения, унаследованного вновь созданнымexec
процессом.См
bash
. Описание среды выполнения в руководстве для простых команд (кроме встроенных функций или функций оболочки).Среда Unix отличается, по крайней мере, от некоторых других операционных систем: «лексические выражения» VMS могут быть изменены дочерним процессом, и это изменение было видно в родительском процессе. VMS
cd
в дочернем процессе повлияет на рабочий каталог родительского процесса. По крайней мере, в некоторых обстоятельствах, и моя память может подвести меня.Некоторые переменные среды хорошо известны,
$HOME
,$PATH
,$LD_LIBRARY_PATH
и другие. Некоторые из них являются обычными для данной системы программирования, поэтому родительская оболочка может передавать много и много специальной информации в какую-либо программу, например, определенный временный каталог или идентификатор пользователя и пароль, которые не отображаются вps -ef
. Простые CGI-программы, например, наследуют много информации от веб-сервера через переменные среды.источник
SOME_NAME=value command
будет установлена переменная окружения SOME_NAME для вызова этой команды. Забавно, но, похоже, переменная оболочки не имеет того же имени.SOME_NAME=value command
себя вопреки вашим ожиданиям, заключается в том, что это специальный синтаксис, означающий «добавьте SOME_NAME в среду, переданную команде, но не изменяйте иные переменные этой оболочки».fork()
эд, но они делают получить (копию) переменную оболочки.Переменные окружения в их исходной форме - это просто набор пар имя / значение. Как описано в man-странице bash (
man 1 bash
) в разделе ENVIRONMENT:На практике это позволяет вам определять поведение, которое является общим или уникальным для программ, вызываемых из настоящей оболочки. Например, при использовании
crontab
илиvisudo
вы можете определитьEDITOR
переменную среды, чтобы определить другой редактор, отличный от того, который ваша система будет использовать по умолчанию. То же самое можно сказать и о таких вещах, какman
команда, которая смотрит на вашуPAGER
среду, чтобы определить, какую программу пейджера следует использовать для отображения выходных данных справочной страницы.Довольно много команд unix читают окружение и в зависимости от того, что там установлено, изменяют их вывод / обработку / действие в зависимости от них. Некоторые из них являются общими, некоторые являются уникальными для программы. Большинство man-страниц содержат информацию о том, как переменная окружения влияет на описанную программу.
Другие практические иллюстрации приведены для таких вещей, как системы с несколькими установками Oracle на одной платформе. Установив
ORACLE_HOME
весь набор команд оракула (загружаемых изPATH
переменной среды), вы извлекаете настройки, определения, сопоставления и библиотеки из этого каталога верхнего уровня. То же самое относится и к другим программам, таким как Java, с егоJAVA_HOME
переменной окружения.Сам bash имеет много переменных окружения, которые могут изменить поведение ряда вещей, таких как история (
HISTSIZE
иHISTFILE
т. д.), размер экрана (COLUMNS
), локализация табуляции (FIGNORE
,GLOBIGNORE
), локализация и кодировка / декодирование символов (LANG
,LC_*
), подсказка (PS1
..PS4
) и и так далее (снова ищите знания на странице руководства bash).Также вы можете писать скрипты / программы, которые используют ваши собственные переменные среды (для передачи настроек или изменения функциональности).
источник
«Переменные среды» - это набор динамических именованных значений, которые могут влиять на поведение запущенных процессов на компьютере.
Они являются частью операционной среды, в которой выполняется процесс. Например, запущенный процесс может запросить значение переменной среды TEMP, чтобы найти подходящее место для хранения временных файлов, или переменную HOME или USERPROFILE, чтобы найти структуру каталогов, принадлежащую пользователю, выполняющему процесс.
Более подробная информация здесь → http://en.wikipedia.org/wiki/Environment_variable .
Все, что вы хотите знать о переменных среды ... ↑
источник
Этот ответ требует некоторого опыта и знаний сценариев оболочки с терминами переменная, значение, подстановка переменной, приглашение, эхо, ядро, оболочка, утилита, сеанс и процесс.
Переменная окружения (envar) представляет собой набор глобальных определенных переменных , которые могут повлиять на то , как данные процессы будут вести себя в операционной системе компьютера.
1. Примерное введение:
Мы заменяем envars буквами
$
и заглавными буквами . Например:$PS1
.Мы можем напечатать envar следующим образом:
$PS1
содержит значение приглашения Unix. Скажи его родные ценности\u
\w
$
.\u
обозначает (текущего) пользователя,\w
обозначает рабочий каталог,$
должен граничить с подсказкой.Итак, если мы делаем:,
echo $PS1
мы видим значения\u
,\w
плюс знак доллара в конце.Мы могли бы изменить поведение Unix в этом контексте, если бы мы изменили значения этого envar. Например:
Теперь приглашение выглядит так (при условии, что рабочий каталог называется «Джон»):
Точно так же, как мы могли бы сделать
PS1="Hello, I'm your prompt >"
, поэтомуecho $PS1
принесет:В Bash 4.xx мы можем напечатать ВСЕ envars в системе с помощью
env
команды. Я предлагаю выполнитьenv
в терминале и взглянуть на вывод.2. Как эти данные отображаются и обрабатываются:
Терминал сеанса позволяет нам настроить envars, которые идут с Bash.
Вышеуказанные изменения обычно носят временный характер, и вот почему:
Каждый сеанс (который не является вложенным сеансом) является уникальным, и несколько процессов могут выполняться уникально одновременно (каждый со своим собственным набором envars), но обычно существует наследование от сеанса 0 к сеансу 1 и выше.
Изменения, которые мы вносим в один процесс, уникальны для него и прекратятся, если мы закроем его, не сохранив их каким-либо образом.
Итак, как мы можем сохранить эти изменения:
Существует несколько типов способов хранения изменений envar в зависимости от выбранной области. Вот разные области (уровни) для таких изменений:
Где хранятся данные envar:
Unix состоит из 3 основных уровней: ядра, оболочки и утилит. AFAIK каждая оболочка имеет свои собственные envars, и они построены в основном или исключительно в оболочке.
Конкретное место, где можно глобально изменить их, обычно,
/etc/profile
хотя мы также можем сделать это,.bashrc
конечно.3. Создание новых envars:
Мы можем создать новые envars, и вот способ; Начиная с Bash 4.xx, нет никакого собственного имени enavar
MESSAGE
(как уже говорилось, envars обычно в верхнем регистре).создаст его для нас, и теперь, если мы введем echo
$MESSAGE
, мы получимhello world!
.Если мы будем выполнять
bash
в нашем текущем рабочем сеансе (окне), мы запустим новую подсессию bash и больше не будем работать в исходном процессе, если мы не выполнимexit
.Примечание. В операционных системах с эмулятором терминала (например, рабочим столом Ubuntu) субсессия обычно выполняется в том же окне, но новый сеанс в другом окне не является субсессией существующего (это смежный процесс). ,
Примечание: не используйте специальные знаки в значениях envar, такие как! или они не будут спасены.
Экспорт envar из исходного сеанса во все подсессии:
Мы по-прежнему можем использовать envar, созданный в первом сеансе, а также во втором сеансе, без регистрации его в пользовательских файлах или файлах глобального уровня (см. Следующие данные). Вот как это сделать:
Перейти к исходному сеансу (в текущем или другом окне) и выполнить:
при экспорте не используйте
$
знак.Теперь он экспортируется во все подсессии. Если вы будете выполнять
echo $MESSAGE
в подсессии, от вашего пользователя или другого, он будет напечатан.Обратите внимание, что внутренние переменные оболочки, такие как,
PS1
не должны экспортироваться, но если вы хотите экспортировать их по любой причине, и они не появляются, не выполняйтеbash
послеexport
, а скорееbash –norc
.4. Envar $ PATH:
$PATH
это среда, которую пользователи обычно меняют больше всего.Если мы
echo $PATH
, мы увидим этот поток:Напечатанные значения этого envar разделены двоеточиями (:), но здесь есть потенциально более удобный способ (это те же значения):
Это директории для поиска, когда мы запускаем утилиту.
Выполнив,
which echo
мы получим его местоположение файла - например, мы можем увидеть, что он существует в/bin/echo
.Исходя из этого, нам не нужно вводить echo envar для просмотра значений evnar. Мы также можем сделать:
Envar все равно будет выполнен, например:
Дает нам
Как только:
Дает нам
Примечание:
$HOME
сокращенно как~
.Отношения system- $ PATH и возможное взаимодействие с пользователем:
В Bash 4.xx, когда мы используем утилиту без полного пути, система будет использовать все 6 упомянутых выше значений
$PATH
envar. Итак, он будет начинаться с/user/local/bin
и будет следить за всем своим содержимым в поискахecho
исполняемого файла.В этом случае он остановится на том
/bin/echo
, в котором, в этом случае, находится исполняемый файл.Следовательно, основная причина, по которой мы могли бы настроить
$PATH
envar, - это установка исполняемых файлов, которые не соответствуют ни одному из его собственных значений.После установки таких исполняемых файлов мы должны соответствующим образом установить их
$PATH
значение, и тогда мы сможем работать с ними.5. Приложение - расширение
$PATH
:Мы можем
export $PATH
объединить подсессии (включая расширения bash, такие как WP-CLI для WordPress или Drush для Drupal) следующим образом:Это добавит новое значение
/home/John
к$PATH
, а затем сразу же добавит к нему любые собственные значения (сразу после двоеточия), которые хранятся в синтаксисе$PATH
.Такое постоянное изменение может быть сделано в соответствующем сценарии, обычно под
/etc/profile
и по имени.bashrc
.источник
!
что значение переменной среды не работает, что прямо под примером, показывающим ее работу, ложное представление о подсессиях, довольно странный совет о том, что делать после экспорта переменной оболочки и ложного представления о глобальных переменных среды.warning about ! in an environment variable value not working that is right below an example showing it working
? Пожалуйста, пример.quite bizarre advice about what to do after exporting a shell variable
, что именно ты имеешь ввиду?false notion of global environment variables
, что именно ты имеешь ввиду?