команды, и внести больше смысла в одну команду.
Первые два командных файла являются пре- и постпроцессорами для
команды ls. Команда lc выводит файловую информацию по столбцам, коман-
да ll перечисляет файлы в длинном формате. Эти командные файлы допол-
нены опциями команды ls, чтобы сделать распечатки более информативны-
ми. Так как команда ls используется довольно часто, упаковка наиболее
часто применяемых нажатий клавиш в командные файлы представляется це-
лесообразной. Упаковка уменьшает количество постоянно набираемых сим-
волов и упрощает использование команд, исключает необходимость запоми-
нания подробного синтаксиса.
Третье инструментальное средство - это kind. Kind - еще один ко-
мандный файл препроцессорного типа, использующий команду UNIX file.
Команда file читает указанный файл и затем сообщает, является ли этот
файл текстовым, архивным или исполняемым. Поскольку распечатки команды
file не выбирают файлы заданного типа, возникает необходимость в соз-
дании для этого специальной утилиты. Команда kind работает с распечат-
кой команды file. Kind выводит на экран имена файлов только заданного
типа.
Еще один командный файл - m, который облегчает работу со стан-
дартной командой more системы UNIX, уменьшая количество необходимых
для запуска команды символов и упрощая интерфейс. Делается это без по-
тери гибкости: так же, как вы можете использовать команду more для
файла или передать команде more данные по программному каналу, вы мо-
жете сделать то же самое для m.
Следующий командный файл - это mmm. Он состоит из одной заготов-
ленной командной строки для программы nroff системы UNIX. Существует
много способов вызова команды nroff и множество различных опций к ней.
Если же вы редко используете nroff, у вас могут возникнуть трудности в
запоминании специфических опций, необходимых для вашей работы с коман-
дой. Эти проблемы отпадут, если у вас есть команда mmm. Определите оп-
ции, которые вы обычно используете, и введите их в командный файл mmm
(о том, как это сделать практически, речь пойдет ниже). Теперь доста-
точно набрать mmm - и вы имеете возможность работать с вашей командой
nroff.
Последняя утилита - pall. Pall обходит файловое дерево, ведя по-
иск файлов заданного типа, и готовит их к выводу на принтер. Команда
pr системы UNIX используется для разбивки на страницы всех файлов
вместе и включения заголовков. Эта команда предлагает на рассмотрение
принтеру один большой файл и наиболее полезна в тех случаях, когда у
вас имеется множество каталогов с текстовыми файлами или с исходными
файлами программ.
Определив в общем основные наши задачи, перейдем к более близкому
знакомству с упомянутыми инструментальными средствами.
2.1. ПОИСК ФАЙЛОВ
2.1.1. tree - визуализация файлового дерева
---------------------------------------------------------------------------
ИМЯ: TREE
---------------------------------------------------------------------------
tree - вывод на экран структуры файлового дерева
НАЗНАЧЕНИЕ
Находит все файлы в файловом дереве и выводит на экран имена фай-
лов, показывая иерархическую структуру файлового дерева.
ФОРМАТ ВЫЗОВА
tree [dir]
ПРИМЕР ВЫЗОВА
$ tree $HOME
Выводит структуру файлового дерева регистрационного каталога.
ТЕКСТ ПРОГРАММЫ
1 :
2 # @(#) tree v1.0 Visual display of a file tree Author: Russ Sage
2а вывод на экран структуры файлового дерева
4 if [ "$#" -gt 1 ]
5 then echo "tree: wrong arg count">&2
6 echo "usage: tree [dir]" >&2
7 exit 2
8 fi
9 if [ "$#" -eq 1 ]
10 then if [ ! -d $1 ]
11 then echo "$0: $1 not a directory">&2
12 echo "usage: tree [dir]" >&2
13 exit 2
14 fi
15 fi
17 find ${1:-.} -print | sort | sed -e "1p" -e "1d" \
18 -e "s|[^/]*/| /|g" \
19 -e "s|[^ */|/|" \
20 -e "s|/\([^/]*\)$|\1|"
ОПИСАНИЕ
ЗАЧЕМ НАМ НУЖЕН КОМАНДНЫЙ ФАЙЛ tree?
Как мы уже отмечали, вся система UNIX строится вокруг файловой
системы, которая похожа на дерево. Дерево, с которым мы работаем в
системе UNIX, растет вверх ногами: корень находится вверху, а ветви и
листва растут вниз от корня. Физическая структура реальных деревьев и
файловых деревьев, используемых в системе UNIX, очень сходна: один ко-
рень (начальная точка) и один ствол. Как глубоко и как далеко могут
уходить ветви от основного ствола - не ограничивается ничем, кроме ог-
раничений физического пространства. Аналогично, число листьев, которые
может иметь каждая ветвь, фактически не ограничено.
Многое в системе UNIX задумано для того, чтобы приспособиться к
дереву. Некоторые команды обходят дерево и сообщают о его компонентах,
но обычно их сообщения выдаются в форме, не очень удобной для чтения
человеком. Это делает командные файлы весьма мощными инструментами.
Перевести необработанные, недружественные сообщения командных файлов в
удобный, информативный вид довольно легко.
Команда tree является комбинацией команд системы UNIX, которые
представляют логическую файловую структуру в наглядной форме. Эта ко-
манда полезна для получения глобальной картины файлов, их расположения
в иерархической структуре файлового дерева, гнездовой структуры ката-
логов и подкаталогов.
ЧТО ДЕЛАЕТ tree?
Команда tree - это постпроцессор для команды UNIX find. Find
просматривает сегмент файлового дерева и полные имена всех файлов, ко-
торые соответствуют заданному критерию. Команда tree использует утили-
ту sed системы UNIX, чтобы перевести выход команды find в наглядную
форму.
Входным параметром для команды tree является имя каталога, кото-
рое может быть указано в любом абсолютном виде, например,
/usr/spool/uucp, или в относительном, например, ../../bin. Если ника-
кого имени не указано, подразумевается ., что является текущим катало-
гом.
Имя каталога является началом (или корнем) отображаемого дерева.
Чтобы показать глубину дерева, все файлы, подчиненные данному катало-
гу, отображаются с отступом. Для удобства представления гнездовой
структуры, между следующими друг за другом ответвлениями печатается
косая черта (/).
Рассмотрим пример структуры каталога. Пусть корневым каталогом
будет /tmp с двумя каталогами: a и b. В каталоге a находится подката-
лог aa, который содержит файл file1, а в каталоге b , соответственно,
подкаталог bb, содержащий файл file2. Команда find выдаст распечатку
такого вида:
# find /tmp -print
/tmp
/tmp/a
/tmp/a/aa
/tmp/a/aa/file1
/tmp/b
/tmp/b/bb
/tmp/b/bb/file2
Как видно из этого листинга, файлы a и aa есть каталоги, а файл
file1 находится внизу файлового дерева. Сравните этот результат с ре-
зультатом, который выдает команда tree, используя утилиту sed.
# tree /tmp
/tmp
/ a
/ / aa
/ / / file1
/ b
/ / bb
/ / / file2
Корневым каталогом в этом листинге является каталог /tmp. Там,
где дерево переходит на более глубокий уровень, печатаются только сим-
волы косой черты. Первый уровень - /tmp, под этим уровнем находятся
файлы-каталоги a и b, затем, соответственно, их подкаталоги aa и bb.
Исходя из этого листинга, мы делаем вывод, что на первом уровне ката-
лога находятся два файла (и эти файлы в действительности являются ка-
талогами) и что два файла находятся в подчиненных каталогах. Отметим,
что мы смогли идентифицировать aa и bb как каталоги только потому, что
в них присутствуют файлы file1 и file2.
Сравните этот листинг с выходом "необработанной" команды find.
Выход команды tree исключает отвлекающее внимание повторение элементов
путей доступа при каждом переходе к более низкому уровню. Благодаря
этому, сразу же видно СУЩЕСТВЕННУЮ информацию. Вот что мы имеем в ви-
ду, когда говорим о создании более наглядного для человека интерфейса
с системой UNIX.
ПРИМЕРЫ
1. $ tree
Использует подразумеваемый каталог (текущий каталог, что рав-
носильно команде "$ tree .") в качестве начала файлового дерева.
2. $ tree /
Печатает древовидный листинг для КАЖДОГО файла всей системы. Ко-
манда find при таком ее запуске начинает с корневого каталога и выдает
информацию о всех файлах системы.
3. $ tree $HOME/..
Показывает древовидный формат для всех других пользователей
системы (предполагается, что все пользовательские каталоги находятся в
одном и том же каталоге, например /usr/*).
ПОЯСНЕНИЯ
Первая строка содержит только знак двоеточия (:) - "нулевую ко-
манду". Это связано с тем, что все командные файлы, описываемые в этой
книге, сделаны так, чтобы их можно было запускать в среде интерпрета-
тора Bourne shell. Наш комментарий в строке 2, идентифицирующий
версию, начинается со знака решетки (#). Си-shell ищет этот знак как
первый знак командного файла. Если он найден, то предпринимается по-
пытка выполнить данный командный файл. В противном случае Си-shell пе-
редает командный файл интерпретатору Bourne shell. Вот почему мы не
хотим начинать первую строку со знака #. Мы, конечно, могли бы оста-
вить первую строку чистой, но чистая строка невидима и может быть слу-
чайно удалена. Соответственно мы будем использовать чистые строки в
других случаях, чтобы выделить важные участки программы.
Строка 2 идентифицирует версию. Символьная строка @(#) есть спе-
циальная последовательность в строке комментария, которая распознается
как строка "what" ("что"). Команда what в системе UNIX читает файл и
печатает сообщение, которое следует за строкой "what". Чтобы идентифи-
цировать версию данного командного файла, наберите
# what tree
и будет напечатано следующее сообщение:
tree:
tree v1.0 Visual display of a file tree Author: Russ Sage
Строки 4-7 проверяют, не слишком ли много аргументов было переда-
но командной строке. Это осуществляется путем исследования переменной
$#, которая представляет собой счетчик числа позиционных параметров
командной строки. Если насчитывается более одного параметра, печата-
ется соответствующее сообщение об ошибке в стандартный файл ошибок
(stderr) и программа останавливается с плохим значением статуса.
Отметим, что команда echo обычно печатает в стандартный выход
(stdout). Мы можем перенаправить stdout в другой файловый дескриптор,
указав его. В данном случае мы собираемся печатать в stderr. Синтаксис
переводится так: "вывести эту строку и перенаправить ее в файловый
дескриптор (&) стандартного файла ошибок (2)". Печать сообщений об
ошибках в stderr обеспечивает согласованное поведение командного файла
независимо от среды, в которой он запущен.
Отметим также, что коды статуса выхода в интерпретаторе shell
противоположны тем, которые используются при программировании на языке
Си. В Си истинное значение есть 1, ложное отлично от 1. При программи-
ровании на языке shell успешным статусом выхода (истиной) является 0,
а плохим статусом (ложью) ненулевое значение.
Вы, возможно, удивитесь, почему мы так беспокоимся о том, чтобы
вернуть ложный статус выхода, если командный файл собирается просто
напечатать сообщение об ошибке и прекратить работу. Дело в том, что
все инструментальные средства системы UNIX должны быть спроектированы
так, чтобы они могли быть связаны с другими командами и процессами, в
которые они могут быть встроены. Возможно, что другой команде необхо-
димо будет вызвать команду tree и проверить, корректно ли она отрабо-
тала. Хорошим стилем проектирования программных средств является прог-
нозирование и разрешение многих способов использования программы.