кой возможности было бы желательным, поскольку при экспериментировании
с командой nroff вам необходимо пробовать различные опции, чтобы уви-
деть, как они действуют. Было бы тяжелой работой выполнять редактиро-
вание текста mmm, чтобы добавить одноразовые опции, которые могут вам
никогда не понадобиться или опции, которые вы должны постоянно менять.
Один из путей достижения большей гибкости - посмотреть, имеет ли
какой-либо аргумент дефис в качестве первого символа. Если да, перех-
ватить эту опцию и убрать ее из списка имен файлов. После этого вы бы
имели список опций, которые нужно включить в командную строку, и
список имен файлов, подлежащих обработке.
Отметим, что место, занятое в нашем командном файле указанием па-
кета mm, можно вместо этого заполнить ссылкой на другие макропакеты,
имеющиеся в вашей системе, например -ms или -me, в зависимости от нуж-
ного вам формата. Отказ от поиска макросов, которые вам не нужны,
ускорит обработку: подробности вы найдете в документации по nroff или
troff.
2.2.6. pall - печать всех файлов в дереве
---------------------------------------------------------------------------
ИМЯ: pall
---------------------------------------------------------------------------
pall Распечатка всех файлов в дереве каталогов
НАЗНАЧЕНИЕ
Находит все файлы в заданном каталоге в соответствии с некоторым
критерием, разбивает файлы на страницы и помещает результат в один
файл, готовый к распечатке на принтере.
ФОРМАТ ВЫЗОВА
pall [-t|-d] directory
ПРИМЕР ВЫЗОВА
pall /usr/lib
Выводит на печать постранично все текстовые файлы в каталоге
/usr/lib
ТЕКСТ ПРОГРАММЫ
1. :
2 # @(#) pall v1.0 Print all files in a tree Author: Russ Sage
2а Печатает все файлы в дереве
4 if [ $# -eq 0 -o $# -gt 2 ]
5 then echo "pall: wrong argument count" >&2
6 echo "usage: pall [-t|-d] dir" >&2
7 echo " -t text (default)" >&2
8 echo " -d dev (.c,.h,.mk,.s)" >&2
9 exit 1
10 fi
12 NAME=""
13 if [ `echo $1 | cut -c1` = "-" ]
14 then case $1 in
15 -t) NAME=""
16 shift;;
17 -d) NAME="-name \"*.[chms]*\""
18 shift;;
19 *) echo "pall: invalid arg $1" >&2
20 echo "usage: pall [-t|-d] dir" >&2
21 echo " -t text (default)" >&2
22 echo " -d dev (.c,.h,.mk,.s)" >&2
23 exit 1;;
24 esac
25 fi
27 echo "creating output file: /tmp/lpr$$"
29 eval find $1 -type f $NAME -print | sort | while read FILE
30 do
31 if file $FILE |
32 egrep 'exec|data|empty|reloc|cannot open' >/dev/null 2>&1
33 then continue
34 else file $FILE > /dev/tty
35 pr $FILE
36 fi
37 done >> /tmp/lpr$$
39 echo "\nSend /tmp/lpr$$ to line printer (y/n): \c"
40 read CMD
41 if [ "$CMD" = "y" ]
42 then lpr /tmp/lpr$$
43 fi
ПЕРЕМЕННЫЕ СРЕДЫ ВЫПОЛНЕНИЯ
FILE Содержит имя каждого файла, который должен быть
обработан в цикле while
NAME Содержит строку поиска для определения местона-
хождения указанных файлов
CMD Содержит команду выдачи результатов на принтер
ОПИСАНИЕ
ЗАЧЕМ НУЖЕН КОМАНДНЫЙ ФАЙЛ pall?
Эта утилита объединяет концепции обхода дерева файлов и вывода
содержимого файлов. Даже когда файлы упрятаны в подкаталогах, мы все
равно хотим найти их. Нам необходима для этого утилита, которая обхо-
дит древовидную структуру файлов, находит файлы нужного нам типа, го-
товит их к распечатке и ставит в очередь для вывода на принтер.
Такого рода утилита особенно полезна, если исходные тексты или
файлы с документацией хранятся в иерархическом дереве. Дело осложня-
ется тем, что обычно эти текстовые файлы смешаны с исполняемыми файла-
ми (откомпилированными программами), файлами данных и, возможно, с ар-
хивными файлами. Необходимо иметь возможность отфильтровать все непри-
годные для печати файлы и подготовить текстовые файлы. Должны быть
проверены все файлы с тем, чтобы ни один не был пропущен.
Для выполнения всего этого процесса вручную требуется, чтобы вы
по команде cd переходили в каждый уровень дерева файлов, находили
текстовые файлы, обрабатывали их (обычно командой pr системы UNIX или
каким-либо другим текстовым процессором) и распечатывали их. После вы-
полнения всей этой работы вы еще должны собрать все отдельные распе-
чатки вместе в строго определенном порядке. Это большая работа, под-
верженная ошибкам со стороны человека. Почему бы не позволить машине
выполнять эту работу? Сейчас мы имеем концепции и средства, необходи-
мые для создания такой утилиты.
В дополнение к возможности управления файлами, pall также может
управлять устройством печати. Обычно каждое задание, поставленное в
очередь на выполнение к принтеру, имеет заголовок, который печатается
первым. Это значит, что если вы поставили в очередь на печать десять
отдельных заданий, то впереди каждого из них будет две-три страницы,
которые должны быть убраны вручную. Помножьте это на сотни файлов, и
вы будете иметь кучу бумаг, которые должны быть выброшены.
Pall исключает эти потери, поскольку все обработанные данные со-
бираются в один большой текстовый файл. Когда вся обработка выполнена,
этот один файл может быть поставлен в очередь на печать или сохранен
для некоторых других целей. Единственное ограничение при таком подходе
заключается в максимальном размере файла, который вы можете создать.
Этот размер вычисляется умножением значения ulimit на размер блока.
Например, мое значение ulimit равно 4096. Размер блока в данном случае
равен 512, а не 1024. Максимальный размер файла равен 2097152. Вы мо-
жете вычислить это прямо с клавиатуры, как показано ниже:
$ ulimit
4096
$ expr 4096 \* 512
2097152
Этого значения достаточно для большинства случаев.
ЧТО ДЕЛАЕТ pall?
Командный файл pall предназначен для поиска указанных файлов, об-
работки их командой UNIX pr и сборки всех результатов в один файл.
После того как все исходные файлы будут обработаны командой pr, вам
будет задан вопрос о том, хотите ли вы поставить выводной файл в оче-
редь на печать к принтеру. Результирующий файл сохраняется в каталоге
/tmp, где его можно использовать для других целей или удалить.
Опциями pall являются -t и -d. Опция -t используется по умолчанию
и нет необходимости ее указывать. Она предназначена для документации и
указана в командной строке, чтобы более ясно показать действие, кото-
рое будет выполнено.
Если выбрана текстовая опция, ищутся все файлы в древовидной
структуре и затем отбираются только текстовые файлы. Если указана оп-
ция разработки -d (development), то ищутся только файлы, связанные с
разработкой программ. Затем эти файлы отфильтровываются с целью полу-
чения текстовых файлов. Считается, что к разработке программ относятся
файлы, имена которых имеют вид *.c для исходных файлов на языке Си,
*.h для включаемых файлов заголовков, *.mk для файлов построения прог-
рамм (makefiles) и *.s для исходных файлов на ассемблере. Если требу-
ются какие-либо другие шаблоны, то такие символы могут быть легко по-
мещены в текст программы.
Прежде чем начнет выполняться поиск файлов, на экран выводится
имя временного файла, чтобы вы знали, как обратиться к нему после за-
вершения выполнения команды. Все результаты, полученные после обработ-
ки файлов, направляются в этот один файл. Командный файл pall также
выводит на экран сообщения, когда он обрабатывает файлы. Вывод файлов
выполняется в реальном времени по мере обработки файлов. Распечатка
производится при помощи обычной команды UNIX'а file. По распечатке вы
можете судить о том, файлы какого типа обрабатываются в данный момент.
Если какой-либо норовистый файл проскользнет, то вы знаете, где он
размещен и какого он типа. Это делает отладку гораздо более простой.
Для файлов выполняется обработка, которая является действием по
умолчанию команды pr. Она разбивает файл на страницы и ставит заголо-
вок в начале каждой страницы. Заголовок содержит дату, имя файла и но-
мер страницы. Нет никакого иного способа передать заголовок командному
файлу pall во время его работы, поскольку он предполагает, что вы хо-
тите знать имя каждого файла таким, как оно есть на диске. Изменение
строки заголовка вызвало бы только неприятности и дополнительную рабо-
ту.
Способ вызова pall влияет на формат имени файла в заголовке. Если
вы вызвали pall, используя абсолютное имя каталога, то в распечатке
используются полные маршрутные имена. Если вы вызвали pall с относи-
тельными маршрутными именами, то они и используются при выводе на пе-
чать. Внутри pall используется команда find системы UNIX. Команда find
использует данные из командной строки, т.е. те, которые ввел пользова-
тель. Выводимый заголовок изменяется в зависимости от того, что указа-
но в командной строке, которую использует find. Если вы вызываете
pall, используя следующую командную строку, то заголовок содержит пол-
ное маршрутное имя:
---------------------------------------------------------------------------
|
| $ pall /usr/include
|
| May 5 10:39 1986 /usr/include/a.out.h Page 1
| .
| .
| .
| May 5 10:39 1986 /usr/include/ar.h Page 1
| .
| .
| .
Если вы вызываете pall с помощью относительной нотации, то имена
файлов также являются относительными, что не очень хорошо. Если у вас
есть несколько каталогов, в которых имеются одинаковые имена файлов,
то вы не сможете быть уверены, что смотрите на правильную распечатку.
Вот как это может выглядеть:
---------------------------------------------------------------------------
|
| $ cd /usr/include
| $ pall .
|
| May 5 10:39 1986 ./a.out.h Page 1
| .
| .
| .
May 5 10:39 1986 ./ar.h Page 1
.
.
.
ПРИМЕРЫ
1. $ pall /usr/include
Выводит ВСЕ файлы заголовков. Сюда включаются файлы заголовков в
подкаталоге sys и во всех других каталогах, которые могут распола-
гаться ниже каталога /usr/include. Это и есть причина, по которой был
написан командный файл pall. Он создает один огромный листинг всех
файлов заголовков в отсортированном порядке с печатью в заголовке
страниц полного имени.
2. $ pall $HOME/src
Обходит все каталоги, находящиеся ниже каталога исходных текстов,
и распечатывает все файлы.
ПОЯСНЕНИЯ
В самом начале производится проверка на наличие ошибок в команд-
ной строке. Если в ней нет аргументов или их больше двух, выводится
сообщение об ошибке, синтаксическая подсказка и программа завершается
с неудачным статусом возврата.
В строке 12 инициализируется переменная NAME. Это действие выпол-
няется по умолчанию, поэтому данная строка дает возможность не указы-
вать опцию в командной строке. Оператор if в строке 13 означает: "Если
первым символом первого аргумента является дефис", то нужно проверить,
какая это опция.
Если установлена опция -t, то переменная NAME инициализируется
нулевым значением, что совпадает с действием по умолчанию, поэтому на
самом деле ничего не меняется. Затем эта опция удаляется из командной
строки.
Если установлена опция -d, то переменная NAME инициализируется
для поиска символьной строки, соответствующей именам файлов программ-
ной разработки. Обратите внимание, что двойные кавычки внутри операто-