Змінні оточення

Матеріал з Wiki TNEU
Версія від 13:25, 6 грудня 2011; Gerasymchuk (Обговорення)

(різн.) ← Попередня версія • Поточна версія (різн.) • Новіша версія → (різн.)
Перейти до: навігація, пошук

Раніше ми познайомилися з тим, як отримувати параметри в програмі за допомогою сімейства функцій getopt (детальніше читайте "Крок 10 - Передача опцій в програму - getopt" та "Крок 11 - Передача довгих опцій в програму - getopt_long"). Але існує ще один метод - змінні оточення або змінні середовища. З ними ми встигли вже познайомитися раніше в кроці "Крок 13 - Отримання інформації про користувача". За допомогою даних змінних можна передавати в програму додаткові специфічні параметри, які можуть використовуватися кількома програмами одночасно і вони характеризують "середовище", в якій виконується програма.

Наприклад, якщо Ви розробляєте якусь систему що складається з декількох програм працюють незалежно, то наприклад, Ви захочете повідомити всім програмам робочий каталог, тимчасову директорію або який-небудь інший специфічний параметр. Тоді змінні оточення, це єдиний розумний метод, адже передавати такі параметри через командний рядок нерозумно. Чому?! Ну, наприклад, наведу скрипт запуску якої-небудь складної системи:

  1. ! / Bin / bash

/ Yoyosystem / cheduler - time = 60 - work-dir = / yoyosystem / data - temp-dir = / tmp / yoyosystem / Yoyosystem / counter-c 25-w 31 - work-dir = / yoyosystem / data - temp-dir = / tmp / yoyosystem / Yoyosystem / pusher - stack-size = 512-m 12 - work-dir = / yoyosystem / data - temp-dir = / tmp / yoyosystem

Ну, як?! Громодко! А ось як більш красиво:

  1. ! / Bin / bash

export YOYO_WORK_DIR = "/ yoyosystem / data" export YOYO_TEMP_DIR = "/ tmp / yoyosystem"

/ Yoyosystem / cheduler - time = 60 / Yoyosystem / counter-c 25-w 31 / Yoyosystem / pusher - stack-size = 512-m 12

Кожна із зазначених програм буде брати параметри про використовувані директоріях з змінних середовища YOYO_WORK_DIR і YOYO_TEMP_DIR, що значно спрощує написання і модифікацію скрипта запуску системи, а також убереже від помилок і пов'язаних з цим помилок. Тому змінні середовища досить важливі і Ви завжди повинні пам'ятати про їх зручність.

А тепер власне давайте познайомимося з цими змінними середовища. Бібліотека glibc надає весь спектр функцій для роботи з ними в заголовному файлі stdlib.h.

Спочатку познайомимося з самим масивом змінних оточення, що визначений в заголовному файлі unistd.h в такому вигляді: / * NULL-terminated array of "NAME = VALUE" environment variables. * / extern char ** __environ;

  1. Ifdef __USE_GNU

extern char ** environ;

  1. Endif

Представлет собою масив покажчиків на рядка формату "ім'я = значення" та закінчується нульовим покажчиком NULL. Давайте спробуємо написати програму виведення всіх змінних:

  1. Include <stdlib.h>
  2. Include <unistd.h>

int main (int argc, char ** argv) {

   int i = 0;
   while (__environ [i]! = NULL) {
       printf ("% s \ n", __environ [i]);
       i + +;
   };
   return 0;

};

Дана програма виведе весь список змінних середовища оточення, які доступні програмі: root @ darkstar :/@@@@@@#. / a.out MANPATH = / usr / local / man: / usr / man: / usr/X11R6/man: / usr / lib / java / man HOSTNAME = darkstar.example.net SHELL = / bin / bash TERM = xterm USER = root MC_TMPDIR = / tmp / mc-root T1LIB_CONFIG = / usr/share/t1lib/t1lib.config MINICOM =- c on PATH = / usr / local / sbin: / usr / sbin: / sbin: / usr / local / bin: / usr / bin: / bin: / usr/X11R6/bin: MAIL = / var / mail / root LC_COLLATE = C PWD =/@@@@@ INPUTRC = / etc / inputrc JAVA_HOME = / usr / lib / java LANG = en_US PS1 = \ u @ \ h: \ w \ $ HISTCONTROL = ignorespace PS2 => HOME = / root SHLVL = 2 LOGNAME = root LESS =- M LESSOPEN = | lesspipe.sh% s OLDPWD = / usr / include _ =. / A.out

Я звичайно вирізав деякі змінні, які занадто великі, але все одно достатньо інформативно і можна вважати, що програма знає про середовище в якій запущена практично все.

Для доступу до змінних оточення, є кілька функцій: char * getenv (const char * name) - повертає покажчик на значення змінної з ім'ям name, якщо змінна середовища не знайдена, то повертається NULL. Не рекомендується модифіковані значення отриманого рядка, так як вона вказує безпосередньо в масив змінних середовища, і можна зіпсувати їх значення. У зв'язку з цим також не потрібно виділення додаткової пам'яті для збереження результату. int setenv (const char * name, const char * value, int replace) - додає нове або замінює старе значення в масиві змінних середовища з ім'ям name і значенням value (навіть якщо value порожній рядок). Під нову змінну виділяється пам'ять і заноситься рядок виду "ім'я = значення". Якщо в змінних середовища вже є змінна з ім'ям name, то процес заміни контролюється параметром replace, якщо він дорівнює нулю, то ніяких дій не проводиться. int putenv (char * string) - додає або видаляє змінну оточення. Щоб додати або змінити змінної використовуйте рядок формату "ім'я = значення", для видалення просто "ім'я". На відміну від setenv () функція putenv () не виділяє пам'ять для параметра, а використовує покажчик на значення string, тому після виклику цієї функції будь-яка зміна рядка string автоматично призведе до зміни змінної середовища. Також перед видаленням рядка з пам'яті, слід спочатку видалити цю змінну з масиву змінних оточення. int unsetenv (const char * name) - видаляє повністю з масиву змінних оточення змінну з ім'ям name. int clearenv (void) - повністю очищає масив змінних оточення.

Використовуючи набір даних функцій ви можете повністю управляти змінними середовища, які доступні вашій програмі.

  1. Include <stdlib.h>

int main (int argc, char ** argv) {

   char * HOME = getenv ("HOME");
   char * USER = getenv ("USER");
   printf ("Home directory: \"% s \ "\ n", HOME);
   printf ("User name: \"% s \ "\ n", USER);
   return 0;

};

При виклику даної програми ви дізнаєтеся свій домашній каталог та ім'я користувача. Наприклад: root @ darkstar :/@@@@@@#. / a.out Home directory: "/ root" User name: "root"

Використання змінних оточення корисно не тільки, коли Вам потрібно налаштувати в декількох програмах якісь параметри, але і для обміну даними між процесами. Тобто в одній програмі Ви створюєте змінну, а в іншій отримуєте значення цієї змінної. Таким чином можна налагодити обмін простими короткими даними між процесами. Але, звичайно, все-таки не варто сильно зловживати цією можливістю

Особисті інструменти
Простори назв

Варіанти
Дії
Навігація
Інструменти