Вы понимаете список аргументов?
Например, если вы ls -l foo bar
, оболочка выполнит /bin/ls
со списком аргументов, состоящим из четырех строк:
тогда как, если вы ls -l "foo bar"
(или ls -l 'foo bar'
или ls -l foo\ bar
), оболочка выполнит /bin/ls
со списком аргументов, состоящим из трех строк:
и ls -l *
может дать вам что-то вроде:
ls
-l
ant
bat
cat
dog
etc
т.е. все файлы в текущем каталоге.
Что ж,
среда в основном просто список второго аргумента.
Возможно, было бы лучше сказать:«среда - это второй список строк, структурированный точно так же, как список аргументов, но обработанный по-другому».
Если вы посмотрите на execve(2), то увидите, что системный вызов execve
принимает три аргумента:
- char * имя файла, (программа для выполнения; например,
/bin/ls
)
- char * argv [],
- char * envp []
Всякий раз, когда какая-либо программа выполняет любую другую программу, она в основном использует execve
(возможно, через какую-то высокоуровневую функцию, например, execl
), поэтому она передает список аргументов и список окружения.
Список окружения очень похож на вывод env
; например,
HOME=/home/fred
USERNAME=fred
PATH=/bin:/usr/bin:…
TERM=xterm
SHELL=/bin/bash
PWD=/home/fred/Super_User_files
так далее…
Выполняемая программа может делать со списком окружения все, что захочет - просматривать его (например, с помощью getenv
), изменять его или игнорировать - то же самое, что можно делать со списком аргументов.
Когда программа выполняет другую программу с одной из функций выполнения более высокого уровня, например execl
, она автоматически вызывает execve
с тем же списком среды, который был передан программе.
И это то, что происходит в 90% программ, которые выполняют другие программы.
Но оболочки позволяют вам изменять среду, а затем они используют execve
напрямую для передачи самой современной пользовательской среды каждой программе, которую она запускает.
TL; DR
Каждый процесс содержит свой список среды в памяти так же, как он содержит список аргументов и обычные переменные.
Среда передается из программы в программу через механизм exec
.
Библиотечные функции позволяют программе легко передавать свою среду любой другой программе, которую она запускает.
(Естественно, среда сохраняется (копируется) по всей fork
, как и вся остальная локальная память.)
Ядро на самом деле ничего не знает об окружающей среде, за исключением того факта, что оно предоставляет средства для передачи среды через execve
.