
Я знаю, что это VARIABLE=value
создает переменную среды и export VARIABLE=value
делает ее доступной для процессов, созданных текущей оболочкой. env
показывает текущие переменные среды, но где они находятся? Что включает в себя переменная среды (илисреда, в этом отношении)?
решение1
Окружение не такое уж волшебное, как может показаться. Оболочка сохраняет его в памяти и передает системному execve()
вызову. Дочерний процесс наследует его как указатель массива, называемый environ
. Из execve
man-страницы:
СИНОПСИС
#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
решение2
Вы немного не правы: SOME_NAME=value
создает переменную оболочки (в большинстве оболочек). export SOME_NAME=value
создает переменную окружения. К лучшему или к худшему, большинство оболочек Unix/Linux/*BSD используют идентичный синтаксис для доступа к переменным окружения и переменным оболочки.
В более широком смысле «окружение» — это просто информация, которая сопровождает выполнение программы. В программах на языке C вы можете найти идентификатор процесса с вызовом getpid()
, в программе оболочки вы бы использовали доступ к переменной: $$
. Идентификатор процесса — это просто часть окружения программы. Я считаю, что термин «окружение» происходит из некоторых более теоретических тем компьютерной науки, таких как моделирование выполнения программы. Модели выполнения программы имеютсреда«который содержит связи между переменными и их значениями».
И это последнее, более сильное определение — то, чем является «окружение» для оболочек Unix/Linux/*BSD: связь между именами («переменными») и их значениями. Для большинства оболочек в стиле Unix значения — это все символьные строки, хотя это не так строго верно, как раньше. Ksh, Zsh и Bash — все они в наши дни имеют типизированные переменные. Даже определения функций оболочки могут быть экспортированы.
Использование среды, отдельной от простых переменных оболочки, подразумевает fork/exec
метод запуска нового процесса, который используют все Unix. Когда вы export
указываете пару имя/значение, эта пара имя/значение будет присутствовать в среде новых исполняемых файлов, запускаемых оболочкой с помощью системного execve(2)
вызова (обычно следующего за fork(2)
, за исключением случаев, когда exec
использовалась команда оболочки).
После execve()
, main()
функция нового двоичного файла имеет свои аргументы командной строки, окружение (хранится как массив указателей на var=value
строки с завершающим NULL, см. environ(7)
страницу руководства). Другое наследуемое состояние включает ulimit
настройки, текущий рабочий каталог и любые открытые файловые дескрипторы, для которых вызывающий execve()
не установил FD_CLOEXEC. Текущее состояние tty (включено эхо, режим raw и т. д.) также можно считать частью состояния выполнения, унаследованного новым exec
процессом.
См. bash
описание руководствасреда исполнениядля простых команд (кроме встроенных или функций оболочки).
Среда Unix отличается от по крайней мере некоторых других операционных систем: «лексические» переменные VMS могли быть изменены дочерним процессом, и это изменение было видно в родительском процессе. VMS cd
в дочернем процессе влияла на рабочий каталог родительского процесса. По крайней мере, в некоторых обстоятельствах, и моя память может меня подводить.
Некоторые переменные окружения хорошо известны, , $HOME
и другие. Некоторые являются общепринятыми для данной системы программирования, так что родительская оболочка может передавать много-много специальной информации некоторой программе, например, определенный временный каталог или идентификатор пользователя и пароль, которые не отображаются в . Простые программы CGI наследуют много информации от веб-сервера через переменные окружения, например.$PATH
$LD_LIBRARY_PATH
ps -ef
решение3
Переменные окружения в своей самой сырой форме — это просто набор пар имя/значение. Как описано на странице руководства bash ( man 1 bash
) в разделе ОКРУЖЕНИЕ:
When a program is invoked it is given an array of strings called the
environment. This is a list of name-value pairs, of the form
name=value.
The shell provides several ways to manipulate the environment. On
invocation, the shell scans its own environment and creates a parameter
for each name found, automatically marking it for export to child pro-
cesses. Executed commands inherit the environment.
На практике это позволяет вам определять поведение, которое является общим или уникальным для программ, вызываемых из текущей оболочки. Например, при использовании crontab
или visudo
вы можете определить EDITOR
переменную окружения, чтобы определить другой редактор, отличный от того, который ваша система будет использовать по умолчанию. То же самое можно сказать и о таких вещах, как команда man
, которая просматривает ваше PAGER
окружение, чтобы определить, какую программу-пейджер следует использовать для отображения вывода страницы руководства.
Довольно много команд unix считывают окружение и в зависимости от того, что там установлено, изменяют свой вывод/обработку/действие в зависимости от этого. Некоторые из них общие, некоторые уникальны для программы. Большинство страниц man содержат информацию о том, как переменная окружения влияет на описываемую программу.
Другие практические иллюстрации — для таких вещей, как системы с несколькими установками Oracle на одной платформе. Устанавливая ORACLE_HOME
, весь набор команд Oracle (загруженный из вашей PATH
переменной окружения) затем извлекает настройки, определения, сопоставления и библиотеки из этого каталога верхнего уровня. То же самое справедливо и для других программ, таких как java с ее JAVA_HOME
переменной окружения.
Сам bash имеет множество переменных окружения, которые могут изменять поведение ряда вещей, от истории ( HISTSIZE
и HISTFILE
т. д.), размера экрана ( COLUMNS
), автодополнения табуляции ( FIGNORE
, GLOBIGNORE
) локали и кодировки/декодирования символов ( LANG
, LC_*
), приглашения ( PS1
.. PS4
) и т. д. (опять же, обратитесь за информацией к странице руководства bash).
Также вы можете писать скрипты/программы, которые используют ваши собственные переменные среды (для передачи настроек или изменения функциональности).
решение4
«Переменные среды»представляют собой набор динамических именованных значений, которые могут влиять на поведение запущенных процессов на компьютере.
Они являются частью операционной среды, в которой выполняется процесс. Например, запущенный процесс может запросить значение переменной среды TEMP, чтобы найти подходящее место для хранения временных файлов, или переменную HOME или USERPROFILE, чтобы найти структуру каталогов, принадлежащую пользователю, запустившему процесс.
Подробнее здесь →http://en.wikipedia.org/wiki/Переменная_среды.
Все, что вы хотели знать о переменных окружения... ↑