Искусство программирования для Unix
Шрифт:
Дуг Макилрой.
Некоторые программы имеют конструкторские модели, подобные фильтрам, но еще проще (и, что существенно, их проще включать в сценарий). Ими являются заклинания (cantrips), источники (sources) и приемники (sinks).
11.6.2. Модель заклинаний
Модель заклинаний является простейшей из моделей проектирования интерфейсов. Нет ни ввода, ни вывода данных, только вызов и числовой код завершения. Режим работы заклинания контролируется только условиями запуска. Не существует другого типа программ, которые проще было бы использовать в сценариях, чем заклинания.
Таким образом, модель заклинаний является замечательным стандартом в ситуациях, когда программе во время выполнения не требуется взаимодействовать с пользователем,
На практике Unix-разработчики учатся противостоять соблазну написания более интерактивных программ, когда для решения задачи вполне подходят заклинания. Набором заклинаний всегда можно управлять из интерактивного упаковщика или shell-программы, но включать в сценарии интерактивные программы сложнее. Следовательно, хороший стиль программирования требует, чтобы разработчик пытался найти конструкцию заклинания для своего средства, прежде чем поддаваться соблазну написания интерактивного интерфейса, который сложнее включать в сценарии. А в ситуациях, когда интерактивность кажется обязательной, необходимо помнить характерную для операционной системы Unix модель проектирования с отделением ядра от интерфейса. Нередко верным решением является написание на каком-либо языке сценариев интерактивного упаковщика, который для выполнения реальной работы вызывает заклинание.
Консольная утилита clear(1), которая просто очищает экран, является заклинанием в чистейшей из возможных его форм. Данная утилита даже не принимает параметров командной строки. Другими классическими примерами являются утилиты гт(1) и touch(1). Программа startx(1), которая применяется для запуска Х-сервера, представляет собой комплексный пример, типичный для целого класса программ вызова демонов.
Несмотря на то, что данная модель проектирования является довольно распространенной, она не получила традиционного названия; термин "заклинания" (cantrips) придуман автором. (Cantrips — шотландское слово, первоначально буквально означающее магическое заклинание, которое было подобрано в популярной фантастической ролевой игре для обозначения волшебного слова, которое может быть применено немедленно с минимальной подготовкой или без подготовки.)
11.6.3. Модель источника
Источником (source) является фильтр-подобная программа, которая не требует входных данных, а ее вывод управляется только начальными условиями. Принципиальными примером является утилита Ь( 1), программа для отображения содержимого каталогов в Unix. В число других классических примеров входят программы who(1)nps(1).
В операционной системе Unix генераторы отчетов, такие как ls( 1), ps( 1) и who( 1), строго руководствуются моделью источника, так что их вывод можно фильтровать с помощью стандартных инструментальных средств.
Понятие "источник" (source) является, как отмечал Дуг Макилрой, весьма традиционным. Оно менее широко распространено, чем могло бы быть, поскольку термин "источник" имеет другие важные толкования.
11.6.4. Модель приемника
Приемник (sink) — фильтр-подобная программа, которая принимает данные на стандартном вводе, но не отправляет никаких данных на стандартный вывод. Как и в двух предыдущих моделях, действия программы управляются только стартовыми условиями.
Данная модель интерфейсов необычна, и существует только несколько широко известных примеров. Одним из них является программа 1рг(1), спулер печати в Unix, которая помещает в очередь для печати текст, переданный ей на стандартном вводе. Как и многие программы-приемники, данная утилита также обрабатывает файлы, указанные в командной строке. Другим примером является программа mail( 1) в режиме отправки почты.
Многие программы, которые на первый взгляд могут показаться приемниками, принимают управляющую информацию, как и данные на стандартном вводе, и фактически являются вариантами модели ed (рассматривается ниже).
Понятие "губка" (sponge) иногда применяется
именно для программ-приемников, подобных утилите sort(1), которые должны полностью считать входные данные, прежде чем смогут обрабатывать любую их часть.Термин "приемник" является традиционным и общепринятым.
11.6.5. Модель компилятора
Программы, подобные компиляторам, не используют ни стандартный вывод, ни стандартный ввод; однако они способны отправлять сообщения об ошибках в соответствующий поток данных (stderr). Вместо этого программы данного типа принимают имена файлов или ресурсов из командной строки, определенным образом преобразовывают имена данных ресурсов и отправляют вывод в файлы с трансформированными именами. Как и заклинания, программы, подобные компиляторам, после запуска не нуждаются во взаимодействии с пользователем.
Данная модель названа так потому, что основным образцом для нее служит компилятор языка С, сс(1) (или gcc(1) в Linux и многих других современных Unix-системах). Однако данная модель также широко применяется для программ, осуществляющих (например) преобразование или компрессию/декомпрессию графических файлов.
Хорошим примером программ-конвертеров является утилита gif2png( 1), которая применяется для преобразования формата GIF (Graphic Interchange Format) в PNG (Portable Network Graphics)80. Хорошими примерами программ компрессии/декомпрессии являются GNU-утилиты gzip(1) и gunzip(1), несомненно, поставляемые с большинством Unix-систем.
Как правило, модель компилятора хорошо применима при проектировании конструкции интерфейса, когда разрабатываемой программе часто приходится оперировать с множеством именованных ресурсов и ее можно написать так, чтобы она не требовала высокой интерактивности (т.е. когда управляющая информация предоставляется во время запуска программы). Программы, подобные компиляторам, можно легко включать в сценарии.
Понятие "компиляторный интерфейс" (compiler-like interface) для данной модели понятно многим в Unix-сообществе.
11.6.6. Модель редактора ed
Для всех предыдущих моделей характерна весьма низкая интерактивность. В них используется только управляющая информация, переданная во время запуска и обособленная от данных. Однако многим программам после запуска требуется управление с помощью продолжительного диалога с пользователем.
Традиционно для Unix, простейшая модель проектирования интерактивного интерфейса иллюстрируется на примере строчного редактора ed(1). В число других классических примеров включаются ftp(1) и sh(1), оболочка Unix. Программа ed(1) принимает в качестве аргумента имя файла и модифицирует данный файл. На входе программа принимает командные строки. Некоторые из команд отражаются на выходных данных на стандартном выводе для немедленного просмотра пользователем, как часть диалога с программой.
Реальный пример сеанса работы в редакторе ed(1) включен в главу 13.
Многие программы в Unix, подобные браузерам и редакторам, придерживаются данной модели, даже когда редактируемые ими именованные ресурсы не являются текстовыми файлами. В качестве примера можно упомянуть символьный GNU-отладчик gdb(1).
Программы, подчиняющиеся модели ed, не так широко можно использовать в сценариях, как можно было бы использовать более простые типы интерфейсов, аналогичные фильтрам. Таким программам можно передать команды через стандартный ввод, но генерировать последовательности команд (и интерпретировать любой их вывод) сложнее, чем просто устанавливать значения переменных окружения и параметры командной строки. Если действие команд не является настолько предсказуемым, что они могут выполняться вслепую (например, с потоковым документом (here document) в качестве входных данных и игнорируя вывод), то управление ^-подобными программами требует протокола и соответствующего конечного автомата в вызывающем процессе. Это приводит к проблемам, отмеченным в главе 7 при обсуждении управления подчиненными процессами.