Категории
Самые читаемые
RUSBOOK.SU » Компьютеры и Интернет » Программное обеспечение » Искусство программирования для Unix - Эрик Реймонд

Искусство программирования для Unix - Эрик Реймонд

Читать онлайн Искусство программирования для Unix - Эрик Реймонд

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 49 50 51 52 53 54 55 56 57 ... 161
Перейти на страницу:

Таким образом, если пользователь вводит команду "ps | more", передавая вывод утилиты ps(1) на ввод more(1), на экране последовательно после каждого нажатия клавиши будут отображаться страницы списка процессов.

Подобная возможность комбинировать программы является чрезвычайно полезной. Но действительный выигрыш в данном случае не сводится к изящным комбинациям. Именно благодаря тому, что существуют каналы и программа more(1), другие программы могут быть проще. Использование каналов означает, что в таких программах, как ls(1) (и других, записывающих данные в стандартный вывод), не требуется культивировать собственные средства постраничного вывода (пейджеры), а пользователи избавлены от тысяч встроенных пейджеров (каждый из которых, естественно, обладает собственными особенностями применения). Благодаря каналам, предотвращается раздувание кода и сокращается глобальная сложность.

В дополнение к этому, если потребуется настроить режим работы пейджера, то это можно сделать в одном месте путем изменения одной программы. Действительно, может существовать множество пейджеров и все они будут полезны для каждого приложения, которое записывает информацию в стандартный вывод.

Фактически дело обстоит именно так. В современных Unix-системах more(1) почти полностью заменена утилитой less(1), в которой добавлена возможность просматривать страницы отображенного файла не только сверху вниз, но и снизу вверх[68]. Ввиду того, что less(1) отделена от использующих ее программ, существует возможность просто связать ее псевдонимом с "more" в оболочке, установить значение переменной среды PAGER равным "less" (см. главу 10) и получить все преимущества лучшего пейджера со всеми Unix-программами, написанными соответствующим образом.

7.2.2.2. Учебный пример: создание списков слов

Более интересным является пример, в котором программы, объединенные в конвейер, взаимодействуют в целях трансформации данных, для реализации которой в других менее гибких средах потребовалось бы писать специальный код.

Рассмотрим следующий конвейер

tr -с '[:alnum:]' '[n*]' | sort -iu | grep -v '^[0-9]*$'

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

7.2.2.3. Учебный пример: pic2graph

Исходный shell-код для программы pic2graph(1) поставляется вместе с пакетом инструментальных средств для форматирования текстов groff, созданным Фондом свободного программного обеспечения. Данная программа преобразовывает диаграммы, написанные на языке PIC, в растровые изображения. В примере 7.1 показан конвейер, находящийся в главной части кода.

Пример 7.1. Конвейер pic2graph

(echo ".EQ"; echo $eqndelim; echo ".EN"; echo ".PS"; cat; echo ".PE")|

 groff -e -p $groffpic_opts -Tps >${tmp}.ps

 && convert -crop 0x0 $convert_opts ${tmp}.ps ${tmp}.${format}

 && cat ${tmp}.${format}

Реализация программы pic2graph иллюстрирует то, как много способен сделать один конвейер, просто вызывая уже имеющиеся инструменты. Работа программы начинается с преобразования входных данных в соответствующую форму. Затем полученные данные обрабатываются groff(1) для создания PostScript-представления. На завершающей стадии PostScript конвертируется в растровое изображение. Все описанные детали скрыты от пользователя, который просто видит то, как в программу с одной стороны поступает исходный PIC-код, а с другой стороны из нее выходит растровое изображение, готовое для включения в Web-страницу.

Данный пример примечателен тем, что он иллюстрирует способность каналов и фильтров адаптировать программы для неожиданного применения. Программа, интерпретирующая PIC-код, pic(1), первоначально разрабатывалась только для внедрения диаграмм в форматированные документы. Большинство остальных программ в данной инструментальной связке были частью почти отжившей в настоящее время конструкции. Однако PIC остается удобным языком для нового применения, такого как описание диаграмм, встраиваемых в HTML-документы. Он получил право на существование, поскольку инструменты, подобные pic2graph(1), способны связывать все механизмы, необходимые для преобразования вывода утилиты pic(1) в более современный формат.

Программа pic(1) подробнее рассматривается в главе 8 при обсуждении конструкций мини-языков.

7.2.2.4. Учебный пример: утилиты bc(1) и dc(1)

Частью классического инструментального набора, происходящего из Unix Version 7, является пара программ-калькуляторов. Программа dc(1) представляет собой простой калькулятор, принимающий на стандартный ввод текстовые строки, состоящие из обратных польских записей (Reverse-Polish Notation — RPN), и отправляющий результаты вычислений на стандартный вывод. Программа bc(1) допускает более сложный, инфиксный синтаксис, который подобен традиционной алгебраической форме записи. Кроме того, данная программа способна задавать и считывать значения переменных и определять функции для сложных формул.

Хотя современная GNU-реализация bc(1) является автономной, ее классическая версия передавала команды в программу dc(1) посредством канала. В этом разделении труда утилита bc(1) осуществляет подстановку значений переменных, разложение функций и преобразование инфиксной записи в обратную польскую, но сама, по существу, не выполняет вычислений. Вместо этого результаты RPN-преобразования входных выражений для расчета передаются программе dc(1).

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

В главе 8 данные программы рассматриваются в несколько другом свете, как узкоспециальные мини-языки.

7.2.2.5. Контрпример: почему программа fetchmail не выполнена в виде конвейера

В понятиях Unix fetchmail является неудобной большой программой, изобилующей различными параметрами. Рассматривая способ транспортировки почты, можно предположить, что данную программу можно было бы разложить на компоненты конвейера. Предположим, что она разбита на ряд программ: несколько программ доставки для получения почты с POP3- и IMAP-узлов, и локальный SMTP-инжектор. Конвейер мог бы передавать почтовый формат Unix. Существующую сложную конфигурацию fetchmail можно было бы заменить сценарием оболочки, содержащим строки команд. В такой конвейер можно также добавить фильтры для блокировки спама.

#!/bin/sh

imap [email protected] | spamblocker | smtp jrandom

imap [email protected] | smtp jrandom

# pop [email protected] | smtp jrandom

Такая конструкция была бы весьма изящной и соответствовала бы духу Unix, но не смогла бы работать. Причина рассматривалась выше — конвейеры являются однонаправленными.

Одной из функций программы доставки (imap или pop) было бы принятие решения о том, отправлять ли запрос на удаление каждого принимаемого сообщения. В существующей организации fetchmail отправка такого запроса POP- или IMAP-серверу может быть задержана до тех пор, пока программа не получит подтверждения о том, что локальный SMTP-слушатель взял на себя ответственность за данное сообщение. Версия программы, организованная в виде конвейера из небольших компонентов, потеряла бы данное свойство.

Рассмотрим, например, последствия аварийного завершения smtp-инжектора вследствие того, что SMTP-получатель сообщил о переполнении диска. Если программа доставки уже удалила почту, сообщения будут утеряны. Это означает, что программа доставки не может удалять почту до тех пор, пока не получит соответствующее уведомление от smtp-инжектора. Причем с данной проблемой связан ряд вопросов. Каким образом программы обменивались бы данными? Какое в точности сообщение было бы возвращено инжектором? Общая сложность такой системы и ее подверженность неочевидным ошибкам были бы выше, чем сложность монолитной программы.

1 ... 49 50 51 52 53 54 55 56 57 ... 161
Перейти на страницу:
На этой странице вы можете бесплатно скачать Искусство программирования для Unix - Эрик Реймонд торрент бесплатно.
Комментарии
Открыть боковую панель
Комментарии
Сергій
Сергій 25.01.2024 - 17:17
"Убийство миссис Спэнлоу" от Агаты Кристи – это великолепный детектив, который завораживает с первой страницы и держит в напряжении до последнего момента. Кристи, как всегда, мастерски строит