Linux программирование в примерах
2.4.2. Окружение в целом:
environПравильным способом работы с окружением является использование функций, описанных в предыдущем разделе. Однако, стоит взглянуть на то, как это работает «под капотом».
Внешняя переменная
предоставляет доступ таким же способом, какenvironпредоставляет доступ к аргументам командной строки. Вы сами должны объявить переменную. Хотя она и стандартизирована POSIX,argvнамеренно не объявлена ни в одном стандартном заголовочном файле (Это, кажется, прослеживается из исторической практики.) Вот объявление:environextern 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("%s\n", environ[i]);return 0;}Хотя это и маловероятно, перед попыткой использовать
эта программа проверяет, что она не равнаenviron.NULLПеременные хранятся в окружении в случайном порядке. Хотя некоторые оболочки Unix хранят переменные окружения в отсортированном по именам переменных виде, это формально не требуется, и многие оболочки не сортируют их.
В качестве уловки реализации можно получить доступ к окружению, объявив третий параметр
:main()int main(int argc, char **argv, char **envp) {...}Затем можно использовать
также, какenvp. Хотя это иногда можно увидеть в старом коде, мы не рекомендуем такое использование;environявляется официальным, стандартным, переносимым способом получения доступа ко всему окружению, если это вам необходимо.environ2.4.3. GNU
envЧтобы завершить главу, рассмотрим GNU версию команды
. Эта команда добавляет переменные к окружению в ходе выполнения одной команды. Она может использоваться также для очищения окружения в ходе этой команды или для удаления отдельных переменных окружения. Программа обеспечивает нас двойной функциональностью, поскольку проявляет возможности какenv, так и несколько других возможностей, обсуждавшихся в этом разделе. Вот как вызывается программа:getopt_long()$ env --helpUsage: 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' (строка 93) предназначен для использования при локализации программного обеспечения, тема, освещенная в главе 13 «Интернационализация и локализация». Пока вы можете рассматривать его, как содержащий строковую константу.N_("string")80 #include <config.h>81 #include <stdio.h>82 #include <getopt.h>83 #include <sys/types.h>84 #include <getopt.h>8586 #include "system.h"87 #include "error.h"88 #include "closeout.h"8990 /* Официальное имя этой программы (напр., нет префикса 'g'). */91 #define PROGRAM_NAME "env"9293 #define AUTHORS N_ ("Richard Mlynarik and David MacKenzie")9495 int putenv();9697 extern char **environ;9899 /* Имя, посредством которого эта программа была запущена. */100 char *program_name;101102 static struct option const longopts[] =103 {