Кому належать змінні середовища?


5

З кількох веб-сайтів я прочитав, що getenvце системний дзвінок. Однак я не можу знайти жодних посилань на це sys_getenv.

Я намагаюся зрозуміти, що саме таке "змінні середовища". Вони є частиною ядра чи механізмом оболонки? Копаючи трохи глибше, я виявив, що getenvце частина стандартної бібліотеки С. На жаль, це не допомагає мені відповісти на моє оригінальне запитання.


Відповіді:


8

Ви розумієте список аргументів? Наприклад, якщо ви вводите ls -l foo bar, оболонка виконує /bin/lsсписок аргументів, що складається з чотирьох рядків:

    ls -l foo bar

в той час як, якщо ви вводите ls -l "foo bar" (або ls -l 'foo bar'чи ls -l foo\ bar), оболонка виконує /bin/lsзі списком аргументів , що складається з трьох рядків:

    ls -l foo bar

і 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.


Отже, я зрозумів, що execveце частина libc. Всередині цієї функції я знайду справжній системний дзвінок, який повинен бути fork(), чи правильно?
nowox

1
Ні-ні-ні.  fork()і exec()(під яким я маю на увазі execсімейство функцій) пов'язані дещо як ліва рукавичка і права рукавичка; вони часто ходять разом, і вони концептуально пов'язані, але це не одне і те ж.  execl()знаходиться в libc, але execve()це системний виклик.  execl() дзвінки execve() , не на відміну від того, як функція libc fprintf()викликає write()системний виклик, а функція libc sleep()викликає alarm()системний виклик. Ви можете перевірити, ввівши man foo  - якщо сторінка "man" з'являється як foo(2), - це систематичний виклик; foo(3)- це функція бібліотеки.
Скотт

@ fixer1234 - Дякую, але −1: незрозуміло, що ти просиш; -1: занадто широкий. Серйозно; Я сказав: "Кожен процес містить свій список середовища в пам'яті, так само, як він містить ... звичайні змінні." Чи допоможе це, якби я сказав: "Кожен процес містить свій список оточуючих у пам'яті простору користувача ..."? Чи допоможе це, якби я сказав: "Обробляє" власну "локальну пам'ять, і я можу отримати доступ до неї безпосередньо, без втручання ядра. Відповідно привілейований процес може отримати доступ до локальної пам'яті іншого процесу за допомогою системних дзвінків. "
Скотт

Я перечитав вашу відповідь. Те, про що я питав, є щось на зразок там, мається на увазі під описаним вами процесом. Жодна справедливість не змушує мене думати. :-)
fixer1234

@ fixer1234: Я радий, якщо ти знайшов те, що шукав. Я припускаю, що ви прочитали, що таке PATH та інші змінні середовища, і як я можу їх встановити чи використовувати? ; і, якщо ви вважаєте, що нічого там не відповідає, що відповідає на питання "Що таке змінні середовища?", я не цілком згоден.  Відповідь користувача945389, можливо, найближча: "Змінні середовища ... зберігають різні значення, щоб програми могли отримати необхідну інформацію про ОС або" Навколишнє середовище ". Наприклад, USERPROFILE та MAIL…. ”… (Продовження)
Скотт

4

Кому належать змінні середовища?

Кожен процес має власні змінні середовища.

Примітки:

  • Кожен процес має блок середовища, який містить набір змінних середовища та їх значення.

  • Змінні середовища успадковуються від батьківського процесу і є копією батьківського блоку.

  • За замовчуванням дочірній процес успадковує змінні середовища свого батьківського процесу.

  • Процес може вибрати передачу іншого середовища дочірнього процесу, створивши новий блок оточення та передавши це дочірньому процесу, коли він створений.

  • Неможливо жоден процес змінити будь-які інші змінні середовища.


Що таке гетенв

getenv є функцією в бібліотеці Standard C.

Ім'я

getenv, secure_getenv - отримати змінну середовища Synopsis

#include <stdlib.h>

char *getenv(const char *name);

char *secure_getenv(const char *name);

Вимоги до макросів тесту для функцій glibc (див. Особливість_тест_макрос (7)):

secure_getenv (): _GNU_SOURCE

Опис

Функція getenv () здійснює пошук у списку середовища, щоб знайти ім'я змінної середовища, і повертає вказівник на відповідний рядок значення.

Специфічна для GNU функція secure_getenv () подібна до getenv (), за винятком того, що вона повертає NULL у випадках, коли потрібне "безпечне виконання".

...

Джерело getenv (3) - сторінка man Linux


Подальше читання

getenv() вихідний код


"Я намагаюся зрозуміти, що саме таке" змінні середовища "."

Дивіться відповідь https://superuser.com/a/932191/337631 по Скотту для докладного пояснення з точки зору кодування.


Я клоную Glibc для перегляду бази даних. Я хочу знати, що стоїть позаду getenv. manне допоможе мені тут.
nowox

Я вже посилався на джерело у своїй відповіді, а також надавав вам посилання, що пояснює змінні середовища. Якщо ви ще не розумієте, що вони там читають, вихідний код c, ймовірно, вам не допоможе.
DavidPostill

Ну, я цього не бачив. Спасибі
nowox

Гаразд, я бачу, що я знову заплутався і відчув себе у питанні XY. getenv.cпосилається на те, __environщо оголошено в, posix/environ.cа потім локальним для поточного процесу. Я не розумію, як процес може успадкувати змінні середовища від свого батьківського.
nowox

@nowox Тут дуже добре допомагає сторінка man. Ви можете виявити посилання на man 5 environта там extern char **environ;у ньому, таблицю, яку процес успадковує від свого батьківського і яку ви також можете змінити.
ott--

2

getenvє частиною бібліотеки Standard C. Отже, в C вам потрібно було б включити stdlib.h.


Мені потрібно буде побачити джерела цієї функції, щоб зрозуміти, що стоїть. Як ця функція може отримати інформацію з оболонки.
nowox

man getenv відкриє сторінку керівництва для цього в Linux.
DarkHorseMan91

1
@nowox Дивіться мою відповідь на посилання на версію вихідного коду (я не маю уявлення, чи це останній код Linux)
DavidPostill
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.