Как показано на рис. 6.1, массивы argv и environ, а также строки, на которые они изначально указывают, находятся в одной непрерывной области памяти непосредственно над стеком процесса. (Массив environ, содержащий список переменных среды, будет рассмотрен в следующем разделе.) Предусмотрено верхнее ограничение общего количества байтов, сохраняемых в этой области. Согласно SUSv3 этот лимит можно определить через константу ARG_MAX (определенная в ) или вызов sysconf(_SC_ARG_MAX). (Описание sysconf() дается в разделе 11.2.) В SUSv3 требуется, чтобы значение ARG_MAX было не меньше значения _POSIX_ARG_MAX, равного 4096 байт. Во многих реализациях UNIX допускается существенно более высокое ограничение. В SUSv3 не указано, входят ли в ограничение, определяемое ARG_MAX, служебные байты, характерные для реализации (завершающие нулевые байты, выравнивающие байты и массивы указателей argv и environ).

В Linux исторически сложилось так, что под ARG_MAX выделяется 32 страницы (то есть 131 072 байта в Linux/x86-32), включая пространство для служебных байтов. Начиная с версии ядра 2.6.23, ограничением на общее пространство, используемым для argv и environ, можно управлять через ограничение ресурса RLIMIT_STACK, и для argv и environ допускается гораздо большее значение. Это ограничение вычисляется как одна четвертая нежесткого ограничения ресурса RLIMIT_STACK, имевшего место на время вызова execve(). Дополнительные подробности можно найти на странице руководства execve(2).

Многие программы (включая примеры, приведенные в этой книге) проводят анализ ключей командной строки (то есть аргументов, начинающихся с дефиса), используя для этого библиотечную функцию getopt().

6.7. Список переменных среды

У каждого процесса есть связанный с ним строковый массив, который называется списком переменных среды (окружения) или просто средой (окружением). Каждая из его строк является определением вида имя=значение. Таким образом, среда представляет собой набор пар «имя — значение», которые могут применяться для хранения произвольной информации.

Когда создается новый процесс, он наследует копию среды своего родителя. Это простая, но часто используемая форма межпроцессного взаимодействия (IPC) — среда предоставляет способ переноса информации от родительского процесса его дочернему процессу или процессам. Поскольку дочерний процесс при создании получает копию среды своего родительского процесса, этот перенос информации является односторонним и однократным. После создания дочернего процесса любой процесс может изменить свою собственную среду, и эти изменения будут незаметны для других процессов.

Переменные среды часто используются оболочкой. Помещая значения в свою собственную среду, оболочка может обеспечить передачу этих значений процессам, создаваемым ею для выполнения пользовательских команд. Например, для переменной среды SHELL в качестве значения определяется путевое имя самой программы оболочки. Многие программы интерпретируют данную переменную в качестве имени оболочки, и она может быть задействована для вызова оболочки изнутри программы.

Некоторые библиотечные функции позволяют изменять свое поведение путем установки переменных среды. Это дает возможность пользователю управлять поведением приложения без изменения кода приложения или его перекомпоновки с использованием соответствующей библиотеки.

В большинстве оболочек значение может быть добавлено к среде с помощью команды:

export: $ SHELL=/bin/bash Создание переменной оболочки

$ export SHELL Помещение переменной в среду процесса оболочки

В оболочках bash и Korn можно воспользоваться следующей сокращенной записью:

$ export SHELL=/bin/bash

В оболочке C shell применяется альтернативная команда setenv:

% setenv SHELL /bin/bash

Показанные выше команды навсегда добавляют значение к среде оболочки, после чего эта среда наследуется всеми создаваемыми оболочкой дочерними процессами. Переменная среды может быть в любой момент удалена командой unset (unsetenv в оболочке C shell).

В оболочке Bourne shell и ее потомках (например, bash и Korn) для добавления значений к среде, применяемой для выполнения одной программы без влияния на родительскую оболочку (и последующие команды), может использоваться такой синтаксис:

$ NAME=value program /* ИМЯ=значение программа */

Перейти на страницу:

Похожие книги