Важливо розуміти, що кожен процес має свій набір змінних середовища.
Коли процес викликає fork()
системний виклик, створюється другий процес ( дочірня ), ідентичний першому ( батьківський ) (ця копія включає оточення, яке знаходиться трохи вище стека (або трохи нижче, залежно від того, як ви думаєте про стеки :-)
- але в Unix / Linux стек росте вниз від високих адрес).
Зазвичай дочірній процес потім викличе execve()
системний виклик, який викине все у свою (віртуальну) пам’ять та реконструює його з розділів коду та даних у вказаному бінарному файлі.
Однак, коли він реконструює стек, він копіює обстановку та аргументи, передані execve()
на стек спочатку (у цьому порядку), перш ніж викликати main()
функцію (велика робота виконується в crt0
коді завантажувальної програми після execve()
повернення (до запису точка, вказана у двійковій)).
У execve()
бібліотеці C є обгортки для системного виклику, які передаватимуть поточне середовище (тобто копію батьківського середовища), а не абонент, який надає це (таким чином дитина наслідує батьківське оточення) - див environ(7)
.
Спробуйте виконати команду (як root) ps axeww | less
... це покаже вам середовище для всіх процесів! Цікавим є процес id 1 (тобто init
процес - перший процес, створений ядром під час завантаження).
Якщо ви хочете подивитися на середовище для певного процесу (а ви знаєте, що це ідентифікатор процесу), спробуйте виконати команду cat /proc/<PID>/environ
(замінивши <PID>
ідентифікатором процесу).
Зауважте, що якщо у процесу достатньо привілеїв, він може переписати власний стек, що може ускладнити пізнання того, що його середовище - ви побачите деякі демонові процеси на зразок цього у виводі ps.
Зрештою, вся ця вафля зводиться до того, що @chaos сказав вище, якщо ви хочете переглянути поточне значення певної змінної середовища у вашому процесі оболонки, просто скористайтеся командою (вбудована) echo "$<NAME>"
(замінивши <NAME>
на ім'я змінна середовище, яка вас цікавить) ... просто пам’ятайте, що одна і та ж змінна може мати інше значення або взагалі не існувати в іншому процесі.
echo
- це поганий вибір команди, оскільки він міг би перетворити вміст змінної. Він виведе вміст параметра оболонки тим самим іменем. Це не обов'язково те ж саме при використанні Bourne оболонки або окр вари , як1
,*
наприклад. І ви не можете використовувати такий підхід для env vars, ім'я яких недійсне як ім'я змінної оболонки.