Для решения этой проблемы необходимо знать, как управлять процессами в UNIX, о чем речь пойдет в разд. 7.4. Пока же примите к сведению, что использование стандартной библиотечной функции
system
может создать неприятности, однако
ttyin
работает правильно, если компилируется с версией
system
, описанной в гл. 7.
Итак, мы написали две программы
vis
и
p
, которые можно считать вариантами
cat
с некоторыми "украшениями". Может быть, им следует быть частью
cat
, доступной с помощью флагов
– v
и
– р
? Вопрос о том, писать ли новую программу или добавлять какие-то средства к старой, возникает всегда, как только у людей появляются новые идеи. Мы не можем со всей определенностью ответить на данный вопрос, но приведем здесь некоторые принципы, которые, возможно, вам помогут.
Основной принцип состоит в том, что программе следует выполнять только свою основную работу. Если у нее появляется слишком много функций, она становится большой, медленной, ее трудно сопровождать и использовать. В самом деле, ряд свойств часто остается невостребованным, поскольку пользователи никак не могут запомнить флаги.
Поэтому
cat
и
vis
совмещать не рекомендуется. Если
cat
просто копирует входной поток без изменений, то
vis
его трансформирует. Соединение их дает программу с двумя разными функциями. Это очевидно также для
cat
и
p
:
cat
предназначена для быстрого эффективного копирования страниц,
p
для их "перелистывания". Кроме того,
p
преобразует выходной поток. Каждый 22-й символ перевода строки пропускается. Три отдельные программы представляются в таком случае правильным решением.
Упражнение 6.6
Работает ли p нормально, если
pagesize
не является положительным?
Упражнение 6.7
Что еще можно было бы сделать с
p
? Оцените и реализуйте (если оно вам подходит) свойство вновь выводить части ранее введенного текста. (Это дополнительное средство нам очень нравится.) Добавьте возможность выводить неполное содержимое экрана после каждой паузы, а также просматривать текст вперед или назад по строкам, задаваемым номером или содержимым.
Упражнение 6.8
Используйте средства манипуляций файлами, встроенные в
exec
shell
(см. справочное руководство по
sh(1)
), чтобы фиксировать обращения к
system
с терминала
ttyin
.
Упражнение 6.9
Если вы забыли определить источник ввода для
p
, то программа "молча" ожидает ввода с терминала. Стоит ли искать эту возможную ошибку? Если да, то как? Подсказка:
isatty(3)
.
6.5 Пример:
pick
Версия
pick
из гл. 5, несомненно, увеличивает возможности
shell
. Версия на Си, приведенная ниже, в чем-то отличается от рассмотренной в гл. 5. Если эта версия имеет аргументы, то они обрабатываются так же, как и ранее, но если определен единственный аргумент
'-'
,
pick
обрабатывает свой стандартный входной поток.
Почему бы в отсутствие аргументов просто не читать стандартный входной поток? Рассмотрим вторую версию команды
предоставляет возможность диалогового выбора аргументов в одной программе. Это не только обеспечивает полезное средство, но и уменьшает потребность в "интерактивных" флагах для других команд.
Упражнение 6.10
Если есть
pick
, существует ли необходимость в
rm -i
?
6.6 Об ошибках и отладке
Если вы писали программы ранее, вам знакомо понятие ошибки. Однако важно не только создавать программы, свободные от ошибок, но и заботиться о том, чтобы ваш проект был прост, тщательно реализован и сохранял свою "чистоту" в процессе модификации.
В UNIX много инструментов, которые помогут вам находить ошибки, хотя ни один из них не является действительно первоклассным. Для того чтобы продемонстрировать их, нам нужна ошибка; все же программы в этой книге совершенны. Поэтому мы "создадим" типичную ошибку. Рассмотрим приведенную выше функцию
pick
, но на сей раз с ошибкой (заглядывать в первоначальный вариант нечестно):