Основы программирования в Linux
В спецификации UNIX определено множество стандартных переменных окружения, применяемых для самых разных целей, включая тип терминала, имена редакторов, установленных по умолчанию, названия часовых поясов и т.д. Программа на языке С может получить доступ к переменным окружения с помощью функций
иputenv.getenv<b>#include <stdlib.h></b><b>char *getenv(const char *name);</b><b>int putenv(const char *string);</b>Окружение состоит из строк вида
. Функцияимя=значениеищет в окружении строку с заданным именем и возвращает значение, ассоциированное с этим именем. Она вернетgetenv, если требуемая переменная не существует. Если переменная есть, но ее значение не задано, функцияNULLзавершится успешно и вернет пустую строку, в которой первый байт равенgetenv. Строка, возвращаемаяNULL, хранится в статической памяти, принадлежащей функции, поэтому для ее дальнейшего использования вы должны скопировать эту строку в другую, поскольку она может быть перезаписана при последующих вызовах функцииgetenv.getenvФункция
принимает строку видаputenvи добавляет ее в текущее окружение. Она даст сбой и вернет -1, если не сможет расширить окружение из-за нехватки свободной памяти. Когда это произойдет, переменной<i>имя=значение</i>будет присвоено значениеerrno.ENOMEMВ упражнении 4.4 вы напишeте программу для вывода значения любой выбранной вами переменной окружения. У вас также будет возможность задать значение, если вы укажете второй аргумент программы.
Упражнение 4.4. Функциииgetenvputenv1. Первые несколько строк после объявления функции
гарантируют корректный вызов программы environ.c с только одним или двумя аргументами:main#include <stdlib.h>#include <stdio.h>#include <string.h>int main(int argc, char *argv[]) {char *var, *value;if (argc == 1 || argc > 3) {fprintf(stderr, "usage: environ var [value]\n");exit(1);}2. Сделав это, вы извлекаете значение переменной из окружения с помощью функции
:getenvvar = argv[1];value = getenv(var);if (value)printf("Variable %s has value %s\n", var, value);elseprintf("Variable %s has no value\n", var);3. Далее проверьте, был ли при вызове программы указан второй параметр. Если был, вы задаете значение этого аргумента, конструируя строку вида
и затем вызывая функцию<i>имя=значение</i>:putenvif (argc == 3) {char *string;value = argv[2];string = malloc(strlen(var)+strlen(value)+2);if (!string} {fprintf(stderr, "out of memory\n");exit(1);}strcpy(string, var);strcat(string, "=");strcat(string, value);printf("Calling putenv with: %s\n", string);if (putenv(string) != 0) {fprintf(stderr, "putenv failed\n");free(string);exit(1);}4. В заключение вы узнаете новое значение переменной, вызвав функцию getenv еще раз:
value = getenv(var);if (value)printf("New value of %s is %s\n", var, value);elseprintf("New value of %s is null??\n", var);}exit(0);}Когда вы выполните эту программу, то сможете увидеть и задать переменные окружения:
$ <b>./environ НОМЕ</b>Variable HOME has value /home/neil$ <b>./environ FRED</b>Variable FRED has no value$ <b>./environ FRED hello</b>Variable FRED has no valueCalling putenv with: FRED=helloNew value of FRED is hello$ <b>./environ FRED</b>Variable FRED has no valueОбратите внимание на то, что окружение локально по отношению к программе. Изменения, которые вы делаете в программе, не отражаются вне ее, поскольку значения переменных не передаются из дочернего процесса (вашей программы) в родительский (командную оболочку).
Применение переменных окружения
Программы часто применяют переменные окружения для изменения способа своей работы. Пользователи могут задать значения этих переменных окружения либо в их стандартном окружении с помощью файла .profile, читаемого их регистрационной командной оболочкой, использующей специальный файл запуска (rc) оболочки, либо заданием переменных в командной строке командной оболочки. Например,
$ <b>./environ FRED</b>Variable FRED has no value$ <b>FRED=hello ./environ FRED</b>