Искусство программирования для Unix - Эрик Реймонд
Шрифт:
Интервал:
Закладка:
10.3.2. Переносимость на другие операционные системы
Общесистемные конфигурационные файлы являются конструкторской тактикой, которую можно применять почти во всех операционных системах, однако довольно трудно найти соответствие файлам профилей в не-Unix-окружении. Критическим элементом, недостающим в большинстве операционных систем, отличных от Unix, является действительная поддержка многопользовательской работы и понятие начального каталога для каждого пользователя. В операционной системе DOS и версиях Windows вплоть до ME (включая Windows 95 и 98), например, такая идея полностью отсутствует; вся конфигурационная информация должна храниться либо в общесистемных файлах конфигурации в фиксированной области, реестре Windows, либо в том же каталоге, из которого запускается программа. В Windows NT имеется некоторое понятие о начальных каталогах пользователей (которое послужило началом пути к Windows 2000 и XP), но оно только недостаточно поддерживается инструментальными средствами системы.
10.4. Переменные окружения
Когда запускается какая-либо Unix-программа, доступная ей среда включает в себя набор связей "имя-значение" (как имена, так и значения являются строками). Некоторые из них устанавливаются пользователем вручную, другие — системой во время регистрации пользователя, либо оболочкой или эмулятором терминала (если таковой используется). В операционной системе Unix в переменных окружения хранится информация о путях поиска файлов, системных установках по умолчанию, номер процесса и идентификатор текущего пользователя, а также другие сведения о среде выполнения программ. Команда set, введенная в приглашении shell, отображает полный список определенных в текущий момент переменных оболочки.
В языках С и С++ значения данных переменных запрашиваются с помощью библиотечной функции getenv(3). В языках Perl и Python во время запуска инициализируются объекты словарей среды. В других языках, как правило, используется одна из двух перечисленных моделей.
10.4.1. Системные переменные окружения
Существует множество широко известных переменных окружения, значения которых программа может получить при запуске из оболочки Unix. Данные переменные (особенно НОМЕ) часто требуется оценить до считывания локального файла профиля.
USER
Регистрационное имя учетной записи, под которым инициируется данный сеанс (BSD-соглашение).
LOGNAME
Регистрационное имя учетной записи, под которым инициируется данный сеанс (соглашение System V).
HOME
Начальный каталог пользователя, инициализирующего данный сеанс.
COLUMNS
Количество символьных столбцов управляющего терминала или окна эмулятора терминала.
LINES
Количество символьных строк управляющего терминала или окна эмулятора терминала.
SHELL
Имя командной оболочки данного пользователя (часто используется командами, создающими подоболочку).
PATH
Список каталогов, которые просматривает оболочка при поиске исполняемых команд, соответствующих заданному имени.
TERM
Тип терминала для консоли сеанса или окна эмулятора терминала (предварительные сведения представлены в учебном примере terminfo в главе 6). TERM — переменная, специально используемая в таких программах для создания удаленных сеансов через сеть (таких как telnet и ssh), предполагается, что они передают и устанавливают значение данной переменной в удаленном сеансе.
(Данный список характерен для Unix-систем, однако он не является исчерпывающим.)
Переменная HOME особенно важна, поскольку многие программы используют ее для поиска файлов профилей вызывающего пользователя (другие программы вызывают некоторые функции в динамической C-библиотеке для выяснения начального каталога вызывающего пользователя).
Следует отметить то, что некоторые или все данные системные переменные окружения могут не устанавливаться во время запуска программы, если программа запускается методом, отличным от создания подпроцесса в shell. В частности, демоны-слушатели какого-либо TCP/IP-сокета часто не имеют таких установленных переменных, а если имеют, то их значения едва ли будут полезны.
Наконец, следует отметить, что существует традиция (проиллюстрированная переменной PATH) использования двоеточия в качестве разделителя, когда переменная окружения должна содержать несколько полей, особенно если данные поля можно интерпретировать как некоторые пути поиска. Заметим, что некоторые оболочки (особенно bash и ksh) всегда интерпретируют разделенные двоеточиями поля в переменной окружения как имена файлов. Это, в частности, означает, что символ ~ в таких полях преобразовывается в путь к начальному каталогу данного пользователя.
10.4.2. Пользовательские переменные окружения
Несмотря на то, что приложения могут свободно интерпретировать переменные окружения за пределами определенного системой набора, в настоящее время фактическое использование такой возможности является довольно необычным. Значения переменных окружения в действительности непригодны для передачи структурированной информации в программу (хотя в принципе это реализуемо посредством синтаксического анализа значений). Вместо этого в современных Unix-приложениях используются конфигурационные файлы, а также файлы профилей.
Существует, однако, несколько конструкторских моделей, в которых могут оказаться полезными переменные окружения, определяемые пользователем.
Независимые от приложения настройки, которые должны совместно использоваться большим количеством различных программ. Данный набор "стандартных" настроек изменяется исключительно медленно, поскольку множеству программ требуется опознать каждую настройку до того, как она станет полезной[98]. Ниже приводятся стандартные переменные.
EDITOR
Имя предпочтительного для пользователя редактора (часто используется командами, создающими подоболочку)[99].
MAILER
Имя предпочтительного для пользователя почтового агента (часто используется командами, создающими подоболочку).
PAGER
Имя предпочитаемой пользователем программы для просмотра простого текста.
BROWSER
Имя предпочитаемой пользователем программы для просмотра информации в Web. Данная переменная до сих пор считается новой и еще широко не распространена.
10.4.3. Когда использовать переменные окружения
Общим для пользовательских и системных переменных окружения является то обстоятельство, что в них содержатся данные, хранение которых в большом количестве конфигурационных файлов было бы утомительным. И крайне утомительным было бы изменение данной информации во всех файлах конфигурации при изменении настроек. Обычно пользователи задают значения данных переменных в своих файлах начальной конфигурации shell-сеанса.
Значение отличается в нескольких совместно использующих файл профиля контекстах, или родительский процесс должен передать информацию множеству дочерних процессов. Ожидается, что некоторые блоки конфигурационной информации будут отличаться между несколькими контекстами, в которых вызывающий пользователь совместно использовал бы общие файлы конфигурации и файлы профиля. В качестве примера системного уровня можно рассмотреть несколько shell-сеансов, открытых через окна эмулятора терминала на рабочем столе системы X. Все они считывают одни и те же файлы профилей, но могут иметь различные значения переменных COLUMNS, LINES и TERM. (Данный метод широко использовался в shell-программировании старой школы, а в make-файлах используется до сих пор.)
Значение изменяется слишком часто для файлов профилей, но не при каждом запуске. Определяемая пользователем переменная окружения может (например) использоваться для передачи расположения файловой системы или Internet-ресурса, являющегося корнем дерева файлов, с которыми должна работать программа. Так, например, система контроля версий CVS интерпретирует переменную CVSROOT. Несколько клиентских программ чтения новостей, доставляющих новости от серверов с помощью протокола NNTP, интерпретируют переменную NNTPSERVERкак расположение запрашиваемого сервера.
Уникальное для процесса переназначение параметров необходимо выразить таким образом, чтобы не требовалось изменять командную строку вызова. Определяемая пользователем переменная среды может быть полезна в ситуациях, когда, по какой-либо причине, может быть неудобно изменять файл профиля приложения или задавать параметры командной строки (возможно, ожидается, что приложение обычно будет использоваться внутри shell-упаковщика или make-файла). Особенно важным контекстом для такого использования является отладка. Например, в Linux использование переменной LD_LIBRARY_PATH, связанной с компонующим загрузчиком ld(1), позволяет изменить место загрузки библиотек — возможно, для выбора версий, которые выполняют проверку переполнения буфера или профилирование (profiling).