Определение будет добавлено к среде только того дочернего процесса, который выполняет указанную программу. Если нужно, то перед именем программы можно добавить сразу несколько присваиваний (отделенных друг от друга пробелами).
Команда env запускает программу, используя измененную копию списка переменных среды оболочки. Список переменных среды может быть изменен как с добавлением, так и с удалением определений из списка, копируемого из оболочки. Более подробное описание можно найти на странице руководства env(1).
Текущий список переменных среды выводится на экран командой printenv. Вот как выглядит пример выводимой ею информации:
$ printenv
LOGNAME=mtk
SHELL=/bin/bash
HOME=/home/mtk
PATH=/usr/local/bin:/usr/bin:/bin:.
TERM=xterm
Назначение большинства перечисленных выше переменных среды будет рассмотрено в последующих главах (эти сведения также можно найти на странице руководства environ(7)).
Из показанного выше примера вывода видно, что список переменных среды неотсортирован. По сути, это не создает никакой проблемы, так как обычно нужно обращаться к отдельно взятым переменным среды, а не к какой-то упорядоченной их последовательности.
Список переменных среды любого процесса можно изучить, обратившись к характерному для Linux /proc/PID/environ, в котором каждая пара ИМЯ=значение заканчивается нулевым байтом.
Из программы на языке C список переменных среды может быть доступен с помощью глобальной переменной char **environ. (Она определяется кодом инициализации среды выполнения программ на языке C, и ей присваивается значение, указывающее на местоположение списка переменных среды.) Как и argv, переменная environ указывает на список указателей на строки, заканчивающиеся нулевыми байтами, а сам этот список заканчивается значением NULL. Структура данных списка переменных среды в том же порядке, как их вывела выше команда printenv, показана на рис. 6.5.
Рис. 6.5.
Программа, показанная в листинге 6.3, обращается к environ, чтобы вывести список всех переменных, имеющихся в среде процесса.
Листинг 6.3. Вывод на экран переменных среды процесса
proc/display_env.c
#include "tlpi_hdr.h"
extern char **environ;
int
main(int argc, char *argv[])
{
char **ep;
for (ep = environ; *ep!= NULL; ep++)
puts(*ep);
exit(EXIT_SUCCESS);
}
proc/display_env.c
Вывод программы совпадает с выводом команды printenv. Цикл в этой программе основан на использовании указателей для последовательного перебора содержимого массива environ. Даже если бы можно было рассматривать environ именно в качестве массива (как это делалось при использовании argv в листинге 6.2), это было бы менее естественно, поскольку элементы в списке переменных среды не располагаются в определенном порядке и нет переменной (соответствующей переменной argc), указывающей на размер списка переменных среды. (По той же причине элементы массива environ на рис. 6.5 не пронумерованы.)
Альтернативный метод обращения к списку переменных среды заключается в объявлении для функции main() третьего аргумента:
int main(int argc, char *argv[], char *envp[])
Этот аргумент может рассматриваться в том же качестве, что и environ, с той лишь разницей, что его область видимости является локальной для функции main(). Хотя это свойство широко реализовано в системах UNIX, его использования следует избегать, поскольку, вдобавок к ограничениям по области видимости, оно не указано в спецификации SUSv3.
Отдельные значения из среды процесса извлекаются с помощью функции getenv().
#include
char *getenv(const char *
Возвращает указатель на строку (значение) или NULL, если такой переменной не существует
Получив имя переменной среды, функция getenv() возвращает указатель на соответствующее строковое значение. Если в ранее рассмотренном примере среды в качестве аргумента name указать SHELL, будет возвращена строка /bin/bash. Если переменной среды с таким именем не существует, getenv() возвращает NULL.
При использовании getenv() нужно учитывать следующие условия обеспечения портируемости.
• В SUSv3 требуется, чтобы приложение не изменяло строку, возвращенную getenv(). Дело в том, что в большинстве реализаций она является фактически частью среды (то есть строка, предоставляющая в паре ИМЯ=значение ту часть, которая является значением). Если нужно изменить значение переменной среды, можно воспользоваться одной из рассматриваемых далее функций: либо setenv(), либо putenv().