Linux программирование в примерах - Роббинс Арнольд
2.4.2. Окружение в целом: environ
Правильным способом работы с окружением является использование функций, описанных в предыдущем разделе. Однако, стоит взглянуть на то, как это работает «под капотом».
Внешняя переменная environ предоставляет доступ таким же способом, как argv предоставляет доступ к аргументам командной строки. Вы сами должны объявить переменную. Хотя она и стандартизирована POSIX, environ намеренно не объявлена ни в одном стандартном заголовочном файле (Это, кажется, прослеживается из исторической практики.) Вот объявление:
extern char **environ; /* Смотрите, нет заголовочного файла POSIX */
Как и в argv, завершающим элементом environ является NULL. Однако, здесь нет переменной «числа строк окружения», которая соответствовала бы argc. Следующая простая программа распечатывает все окружение:
/* ch02-printenv.c --- Распечатать окружение. */
#include <stdio.h>
extern char **environ;
int main(int argc, char **argv) {
int i;
if (environ != NULL)
for (i = 0; environ[i] != NULL; i++)
printf("%sn", environ[i]);
return 0;
}
Хотя это и маловероятно, перед попыткой использовать environ эта программа проверяет, что она не равна NULL.
Переменные хранятся в окружении в случайном порядке. Хотя некоторые оболочки Unix хранят переменные окружения в отсортированном по именам переменных виде, это формально не требуется, и многие оболочки не сортируют их.
В качестве уловки реализации можно получить доступ к окружению, объявив третий параметр main():
int main(int argc, char **argv, char **envp) {
...
}
Затем можно использовать envp также, как environ. Хотя это иногда можно увидеть в старом коде, мы не рекомендуем такое использование; environ является официальным, стандартным, переносимым способом получения доступа ко всему окружению, если это вам необходимо.
2.4.3. GNU env
Чтобы завершить главу, рассмотрим GNU версию команды env. Эта команда добавляет переменные к окружению в ходе выполнения одной команды. Она может использоваться также для очищения окружения в ходе этой команды или для удаления отдельных переменных окружения. Программа обеспечивает нас двойной функциональностью, поскольку проявляет возможности как getopt_long(), так и несколько других возможностей, обсуждавшихся в этом разделе. Вот как вызывается программа:
$ env --help
Usage: env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]
/* Устанавливает соответствующее VALUE для каждого NAME и запускает COMMAND */
-i, --ignore-environment /* запустить с пустым окружением */
-u, --unset=NAME /* удалить переменную из окружения */
--help /* показать этот экран справки и выйти */
--version /* вывести информацию о версии и выйти */
/* Простое - предполагает -1. Если не указана COMMAND, отображает
имеющееся окружение.
Об ошибках сообщайте в <[email protected]>. */
Вот несколько примеров вызовов команды:
$ <b>env - myprog arg1</b> /* Очистить окружение, запустить программу с args */
$ <b>env - РАТН=/bin:/usr/bin myprog arg1</b> /* Очистить окружение, добавить PATH, запустить программу */
$ <b>env -u IFS PATH=/bin:/usr/bin myprog arg1</b> /* Сбросить IFS, добавить PATH, запустить программу */
Код начинается со стандартной формулировки авторских прав GNU и разъясняющего комментария. Мы для краткости их опустили. (Формулировка авторского права обсуждается в Приложении С «Общедоступная лицензия GNU». Показанного ранее вывода --help достаточно для понимания того, как работает программа.) За объявленным авторским правом и комментарием следуют подключаемые заголовочные файлы и объявления. Вызов макроса 'N_("string")' (строка 93) предназначен для использования при локализации программного обеспечения, тема, освещенная в главе 13 «Интернационализация и локализация». Пока вы можете рассматривать его, как содержащий строковую константу.
80 #include <config.h>
81 #include <stdio.h>
82 #include <getopt.h>
83 #include <sys/types.h>
84 #include <getopt.h>
85
86 #include "system.h"
87 #include "error.h"
88 #include "closeout.h"
89
90 /* Официальное имя этой программы (напр., нет префикса 'g'). */
91 #define PROGRAM_NAME "env"
92
93 #define AUTHORS N_ ("Richard Mlynarik and David MacKenzie")
94
95 int putenv();
96
97 extern char **environ;
98
99 /* Имя, посредством которого эта программа была запущена. */
100 char *program_name;
101
102 static struct option const longopts[] =
103 {