Ви розумієте список аргументів? Наприклад, якщо ви вводите 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
.