Раньше мы познакомились с тем, как получать параметры в программе с помощью семейства функций getopt (подробнее читайте "Шаг 10 - Передача опций в программу - getopt" и "Шаг 11 - Передача длинных опций в программу - getopt_long"). Но существует еще один метод - переменные окружения или переменные среды. С ними мы успели уже познакомиться раньше в шаге "Шаг 13 - Получение информации о пользователе". С помощью данных переменных можно передавать в программу дополнительные специфические параметры, которые могут использоваться несколькими программами одновременно и они характеризуют "среду", в которой выполняется программа.
Например, если Вы разрабатываете какую-то систему состоящую из нескольких программ работающих независимо, то к примеру, Вы захотите сообщить всем программам рабочий каталог, временную директорию или какой-нибудь другой специфичный параметр. Тогда переменные окружения, это единственный разумный метод, ведь передавать такие параметры через командную строку глупо. Почему ?! Ну, например, приведу скрипт запуска какой-нибудь сложной системы:
Каждая из указанных программ будет брать параметры об используемых директориях из переменных среды YOYO_WORK_DIR и YOYO_TEMP_DIR, что значительно упрощает написание и модификацию скрипта запуска системы, а также убережет от опечаток и связанных с этим ошибок. Поэтому переменные среды достаточно важны и Вы всегда должны помнить об их удобстве.
А теперь собственно давайте познакомимся с этими переменными среды. Библиотека glibc предоставляет весь спектр функций для работы с ними в заголовочном файле stdlib.h.
Сначала познакомимся с самим массивом переменных окружения, который определен в заголовочном файле unistd.h в таком виде:
Представлет собой массив указателей на строки формата "имя=значение" и заканчивается нулевым указателем NULL. Давайте попробуем написать программу вывода всех переменных:
#include <stdlib.h>#include <unistd.h> int main(int argc,char **argv) { int i=0; while (__environ[i] != NULL) { printf("%s\n",__environ[i]); i++; }; return 0;};
Данная программа выведет весь список переменных среды окружения, которые доступны программе:
Я конечно вырезал некоторые переменные, которые слишком большие, но все равно достаточно информативно и можно считать, что программа знает о среде в которой запущена практически все.
Для доступа к переменным окружения, есть несколько функций:
· 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) - полностью очищает массив переменных окружения.
Используя набор данных функций вы можете полностью управлять переменными среды, которые доступны вашей программе.
Использование переменных окружения полезно не только, когда Вам требуется настроить в нескольких программах какие-то параметры, но и для обмена данными между процессами. То есть в одной программе Вы создаете переменную, а в другой получаете значение этой переменной. Таким образом можно наладить обмен простыми короткими данными между процессами. Но, конечно, все-таки не стоит сильно злоупотреблять этой возможностью :)