Страница:
ного файла интерпретатора shell. Поскольку они знакомы с существующими
ресурсами системы UNIX, они могут рассмотреть проблему и выбрать стра-
тегию, использующую наименее сложное средство, выполняющее данную ра-
боту с приемлемым уровнем производительности. В порядке возрастания
сложности, это могут быть непонятная, но существующая команда и/или
опция, псевдоним, командный файл интерпретатора shell или программа на
языке Си.
ЧТО ДЕЛАЕТ lc?
Общий подход к разработке этой команды заключается в том, чтобы
собрать вместе некоторые опции и сделать новую команду с более мощным
интерфейсом. Чтобы достичь этой мощи, мы можем сделать пре- или пост-
процессор для обычной команды системы UNIX.
Главная задача здесь - печать колонок, поэтому мы смотрим на оп-
ции команды ls, чтобы задействовать их. Конечно, мы включаем опцию -C.
Какие еще опции ls нам нужны? Обычно UNIX не печатает файлы, имена ко-
торых начинаются с точек, например, .profile, если только вы не указы-
ваете ls -a. Это забывается при просмотре этих важных файлов, поэтому
мы конструируем нашу команду так, чтобы она печатала их по умолчанию.
Никакие файлы не скрываются от нас. Для пользователей System V и BSD
(или для любого, кто имеет опцию -F), листинг улучшается за счет выво-
да "/" после имени каталога и "*" после исполняемого файла. Ранняя ко-
манда ls системы UNIX не имела возможности печатать в таком стиле. От-
метим, что данное использование термина "исполняемый" означает показ
того, что флаги прав доступа имеют бит "x", а не то, что это файл типа
a.out с магическим числом. Это отличие важно тем, что делает наш ко-
мандный файл более полезным.
Если ожидается длинная распечатка, как это бывает обычно для ре-
курсивных каталогов, то вы хотите иметь доступ к команде more. Мы
встраиваем команду more так, чтобы ее можно было активировать с по-
мощью опции -m. Опция -m должна быть первой опцией после имени коман-
ды, из-за способа, которым она проверяется внутри программы. Если она
передается после первой опции, она переходит к команде UNIX ls и ин-
терпретируется как печать в потоковом формате. Это такой формат, в ко-
тором все имена расположены в строках, разделенных запятыми (,). Как
мы уже отмечали, вы можете сделать интерфейс этого командного файла
более гибким за счет дополнительной работы над ним.
1. $ lc `path lc`
Получает полное имя для lc и распечатывает файловую информацию в
виде колонок.
2. $ lc -m -R /
Печатает колоночный список ВСЕХ файлов в системе, рекурсивно про-
ходя вниз по иерархии системного дерева и пропуская распечатку через
команду more.
Еще один маленький фокус: этот синтаксис был использован для соз-
дания другой команды, названной expose. Командная строка "lc -m -R $@"
давала бы рекурсивный список всех файлов в любом каталоге по вашему
выбору в приятном постраничном формате.
3. $ lc -m -R /usr/lib
Рекурсивно распечатывает список всех файлов во всех каталогах,
начиная с /usr/lib, и пропускает листинг через команду more.
4. $ lc -m . | more
Выдает список файлов в текущем каталоге и пропускает листинг че-
рез команду more, а затем снова пропускает все через more. Работает ли
это ? Никоим образом. Возникает полная путаница, и клавиша прерывания
обычно является наилучшим способом выхода из данной ситуации.
В строках 4-8 проверяется, является ли первым аргументом команд-
ной строки -m - опция команды more. Если эта опция найдена, то в пере-
менную MORE заносится указание конвейера и команда more. Тем самым
устанавливается постобработка, которую следует применить к выходу ко-
манды ls. Затем эта опция убирается из командной строки. Это делается
для того, чтобы остаток командной строки можно было передать команде
ls, не вызвав при этом нежелательных эффектов. Если первой опцией не
является -m, переменной MORE присваивается нулевое значение, чтобы она
впоследствии не влияла на командную строку.
Строка 10 - это командная строка, которую вы бы использовали на
старой UNIX-машине типа Version 7 или System III. Она не имеет ни
встроенной опции для печати символов косой черты (/) и звездочек (*),
ни возможности печати в виде колонок. Вы должны пожертвовать первой
возможностью, а распечатки в виде нескольких колонок можно получить с
помощью команды pr системы UNIX. Команда pr использована с опцией
"-5t", поэтому она печатает в пять колонок (что обычно приемлемо, но
если встречаются длинные имена файлов, то пяти колонок может оказаться
слишком много) и не печатает верхний и нижний колонтитулы. Благодаря
отказу от колонтитулов, 24-строчный формат не слишком неудобен для
вас.
Отметим, что здесь использована команда eval. Это специальная
встроенная команда интерпретатора shell, которая выполняет перевы-
числение текущей строки, подлежащей выполнению. Интерпретатор shell
повторно анализирует эту строку, чтобы раскрыть значение имен перемен-
ных в командной строке и обеспечить распознавание переменных как тако-
вых. Здесь мы перевычисляем переменную MORE. Напомним, что мы помести-
ли в эту переменную конвейер. Если мы не перевычислим командную стро-
ку, то команда pr попытается открыть файлы "|" и "more", которые не
существуют. Для того, чтобы shell вместо этого воспринял эти символы
как указания конвейеров и программ, и используется команда eval.
Строка 10 имеет еще одну особенность. В командной строке уже есть
один конвейер. Откуда shell знает, трактовать ли символ "|" как имя
файла или как конвейер? Благодаря тому, что аргумент команды eval зак-
лючен в кавычки. Это указывает команде eval сохранить все, что нахо-
дится в кавычках, без изменений, но раскрыть значение переменной MORE
и поместить его в конец командной строки, находящейся в кавычках.
Несколько непонятно, но если вы думаете об этом пару лет, оно стано-
вится осмысленным.
Для тех из вас, кто имеет новую команду ls (System V, версия 2
или BSD 4.2), не требуется два конвейера в команде. Как показывает
строка 11, мы получаем подходящий колоночный формат из самой команды
ls, вместе с показом всех файлов и специальными символами / и * для
каталогов и исполняемых файлов. Обозначение $@ относится ко всему со-
держимому командной строки, т.е. к вашим дополнительным опциям команды
ls и к именам файлов, список которых вы хотите распечатать. Поступая
таким образом, мы создаем фундамент (опции a,C,F), а вы можете
надстраивать его (используя опции R,t и т.д.). Скромный, но элегантный
фокус заставить ls сообщить свои опции заключается в том, чтобы выз-
вать ее с неверной опцией. Большинство команд не используют опции z
или ?, поэтому вызов "ls -z" или "ls -?" приведет к такому результату:
--------------------------------
|
| ls: illegal option -- z
| usage: -1ACFRabcdfgilmnopqrstux [files]
|
Все эти опции представляют определенный интерес. Если вы часто
используете какие-либо из них, поместите их в командный файл lc, и вы
получите вашу собственную адаптированную команду.
Вы обратили внимание, что все обычные команды системы UNIX,
используемые в нашем командном файле, имеют полные маршрутные имена?
Это может показаться несколько странным, но причина указания полных
маршрутных имен в том, что когда shell запускает команду, он не должен
возвращаться к анализу переменной PATH и искать, где расположена ко-
манда. Если вы обращаетесь к командам относительным способом, время
поиска файлов представляет собой большие накладные расходы. Когда вы
вызываете lc, интерпретатор shell ищет эту команду, затем lc вызывает
ls, которую тоже нужно найти. Если после этого результаты пропускаются
через more или pr, то требуется дополнительный поиск. А полные марш-
рутные имена распознаются интерпретатором shell сразу же (он видит,
что первым символом является /), и нужная команда может быть вызвана
быстро. Издержки на поиск - единственные издержки команды lc.
Использование полных имен, естественно, требует, чтобы вы знали,
где в системе размещены утилиты, к которым вы хотите обратиться. Вы
можете применить команду paths, чтобы получить корректные полные имена
для жесткого указания их в тексте вашего командного файла, а можете
переписать данный командный файл при переходе в другую систему. Это
просто еще одна иллюстрация универсального компромисса между скоростью
и эффективностью, с одной стороны, и гибкостью и мобильностью, с дру-
гой.
2.2.2. ll - вывод файловой информации в длинном формате
-------------------------------------------------------------
ИМЯ: ll
-------------------------------------------------------------
ll Выдает список файлов в длинном формате
Выдает список файлов в длинном формате (-l). Распечатку можно
пропустить через команду more.
ll [-m] [ls options] file [file...]
ll *.c Выдача списка файлов с исходными текстами на
языке Си в длинном формате.
1 :
2 # @(#) ll v1.0 Long listing of files Author: Russ Sage
2а Выводит список файлов в длинном формате
4 if [ "$1" = "-m" ]
5 then MORE="| /usr/bin/more"
6 shift
7 else MORE=""
8 fi
10 eval /bin/ls -al $@ MORE
MORE Содержит строку передачи результатов по
конвейеру команде more
ОПИСАНИЕ
ЗАЧЕМ НАМ НУЖЕН КОМАНДНЫЙ ФАЙЛ ll?
Мотивы для создания команды ll те же, что мы обсудили ранее для
команды lc. Мы можем использовать ll для нескольких целей. Она умень-
шает количество требуемых нажатий на клавиши, позволяет избежать необ-
ходимости помнить специальные опции и вообще настраивает систему соот-
ветственно нашим требованиям вместо того чтобы нам приспосабливаться к
системе.
ЧТО ДЕЛАЕТ ll?
Основой этой команды является известная команда "ls -l". Она,
если вы помните, дает очень емкую информацию о каждом файле, включая
права доступа, связи, имя владельца, размер и так далее. (Кстати,
программисты, использующие язык Си, могут получить эту информацию при
помощи системного вызова stat(2).) Поскольку такой список при наличии
множества файлов может легко переполнить экран, то предоставляется оп-
ция -m. Она обеспечивает постраничный вывод с помощью команды more.
Отметим, что если используется эта опция, то она должна стоять первой.
Строка символов, соответствующая этой опции, удаляется командой shift,
так что она не смешивается с именами файлов и обычными опциями команды
ls, которые передаются как аргументы.
После опции -m (если она есть) ll допускает указание любых других
допустимых опций команды ls. Можно также использовать любую комбинацию
имен файлов. Здесь применимы обычные средства порождения имен файлов:
* соответствует любым символам, ? - одному символу, а символы [] зада-
ют диапазон из некоторого набора символов. В итоге мы получили команду
ls, которая по умолчанию работает как "ls -l", вызывает команду more с
помощью одной опции вместо необходимости указания конвейера в команд-
ной строке и при этом сохраняет гибкость команды ls.
1. $ ll /etc/*mount*
Выводит список всех файлов в каталоге /etc, имена которых содер-
жат в каком-либо месте слово mount (например, mount, umount,
unmountable).
2. $ ll -i `who|awk '{print "/dev/" $2}'`
Сперва выполняется команда who, затем результат ее работы по кон-
вейеру передается команде awk, которая вырезает имя устройства и при-
писывает ему префикс /dev/. В результате список полных маршрутных имен
ко всем терминальным устройствам, зарегистрированным в настоящий мо-
мент, помещается в командную строку команды ls -li. В распечатке ука-
зана вся информация об индексном дескрипторе файла (inode) для каждого
терминального устройства.
3. $ ll `kind -a /lib`
Выводит в длинном формате список всех файлов архива в каталоге
/lib. Этот каталог содержит библиотеки компиляторов всех языков систе-
мы UNIX. (Команда kind, которая отбирает файлы по их типу, рассматри-
вается в следующем разделе.)
4. $ ll -m -i /dev
Выводит всю обычную информацию плюс номер индексного дескриптора
для всех файлов в каталоге /dev. Выдача на экран происходит с помощью
команды more.
Если первым позиционным параметром является -m, то в строке 4
инициализируется переменная MORE для подключения конвейера и программы
/usr/bin/more. (Вопрос о том, почему используется абсолютное маршрут-
ное имя, обсуждался в предыдущем разделе.) Затем символьная строка -m
командой shift убирается из командной строки. Если же первой опцией не
является -m, то переменная MORE устанавливается в нуль, чтобы не вли-
ять на повторный разбор командной строки, выполняемый с помощью коман-
ды eval (строка 10).
В строке 10 команда eval использована для получения результирую-
щей командной строки. Команда ls вызывается с опциями -al (выдача
списка всех файлов в длинном формате), которые мы установили по умол-
чанию. Затем берутся аргументы командной строки (минус первый аргу-
мент, если это был -m, который мы убрали командой shift). Этими аргу-
ментами могут быть дополнительные опции команды ls плюс имена файлов
или каталогов. В конце строки значение переменной MORE обеспечивает
конвейер с командой more, если была указана опция -m. В противном слу-
чае значение переменной MORE равно нулю и не оказывает никакого влия-
ния на анализ содержимого командной строки.
Что произошло бы, если бы пользователь указал опцию -m в качестве
второй (или последующей) опции? В этом случае опция -m передалась бы
команде ls. Команда ls трактовала бы эту опцию как "потоковый вывод",
а это совсем не то, что мы хотели. Однако команда ls была вызвана так-
же с опцией -l, которая отменяет опцию -m в соответствии с текстом
программы ls. Вы не получили бы вывод с помощью команды more, но ваши
выходные данные по-прежнему были бы выведены в правильном формате.
2.2.3. kind - вывод однотипных файлов
-------------------------------------------------------------
ИМЯ: kind
-------------------------------------------------------------
kind Выдача списка имен файлов определенного вида
Выбирает и выводит имена всех файлов в указанном каталоге (ката-
логах), имеющих указанный тип. Если не указан никакой тип, выбираются
текстовые файлы.
kind [-a] [-d] [-t] [-x] [file...]
more `kind /etc/*`
Вывод командой more всех текстовых файлов, имеющихся в катало-
ге /etc.
1 :
2 # @(#) kind v1.0 Prints files of the same kind Author: Russ Sage
2а Выводит список файлов определенного вида
4 if [ $# -gt 0 ]
5 then if [ `echo $1 | cut -c1` = "-" ]
6 then case #1 in
7 -a) KIND='archive'
8 shift;;
9 -d) KIND='data'
10 shift;;
11 -t) KIND='text'
12 shift;;
13 -x) KIND='executable'
14 shift;;
15 *) echo "kind: arg error" >&2
16 echo "usage: kind [-a] [-d] [-t] [-x] [file...]" >&2
17 echo " -a archive" >&2
18 echo " -d data" >&2
19 echo " -t text, default" >&2
20 echo " -x executable" >&2
21 echo " if no args, reads stdin" >&2
22 exit 1;;
23 esac
24 fi
25 fi
27 : ${KIND:='text'}
29 case $# in
30 0) while read FILE
31 do
32 file $FILE | fgrep $KIND | cut -d: -f1
33 done;;
34 *) file $@ | fgrep $KIND | cut -d: -f1;;
35 esac
FILE Содержит имена файлов по мере их чтения из stdin
(стандартного ввода)
KIND Содержит строку, определяющую тип файла
ОПИСАНИЕ
ЗАЧЕМ НУЖЕН КОМАНДНЫЙ ФАЙЛ kind?
Файловая система UNIX имеет строгие стандарты при рассмотрении
файлов. Имеется три вида файлов: обычные файлы (тексты, данные, испол-
няемые файлы), каталоги и устройства. Каждый вид файлов имеет свое
предназначение и обычно имеет особые команды или файлы данных, которые
работают с ним.
Давайте рассмотрим, как некоторые из существующих команд системы
UNIX рассматривают типы файлов. Команда ls делает различие между ката-
логами и другими файлами, поэтому она может быть полезна. Другой важ-
ной командой является команда file. Она сообщает вам, какой тип имеет
данный файл, что потенциально полезно, но слишком мало. Для того чтобы
извлечь из команды file какую-либо полезную информацию, вы должны
надстроить над ней некоторую программу. Что нам действительно нужно,
так это некий гибрид команд ls и file, т.е. утилита, которая выводит
имена всех файлов указанного типа.
Примером полезности такого рода утилиты может служить анализ со-
держимого каталогов. Возьмем, например, каталог /etc. Он содержит
программы, файлы данных и текстовые файлы. Для каждого из этих типов
требуется свой собственный тип анализа. Программы анализируются коман-
дами ls, size, nm и file. Файлы данных анализируются командой od.
Текстовые файлы анализируются командами more, wc, head, tail и други-
ми. Таким образом, обычно вам необходимо работать в данный момент вре-
мени с файлами какого-нибудь одного типа.
ЧТО ДЕЛАЕТ kind?
Командный файл kind - это утилита, которая распечатывает имена
всех файлов, имеющих указанный тип. Она имеет интерфейс, похожий на
интерфейс команды ls, т.е. вы можете передать ей опции и имена файлов
или символы расширения имен файлов. При выводе отображаются полные
имена, если они были указаны, но вы можете избежать появления лишней
информации при выводе, если предварительно перейдете в нужный каталог
с помощью команды cd. Например, если бы я находился в моем регистраци-
онном каталоге (/usr/russ) и ввел команду
$ kind -d /etc/*
то вывод мог бы выглядеть так:
--------------------------------
|
| /etc/mnttab
| /etc/utmp
| /etc/wtmp
|
То есть, вывелся список всех файлов данных. А если бы я выполнил
такую последовательность команд:
$ cd /etc
$ kind -d *
то при выводе убрался бы маршрут, использованный в вызывающей последо-
вательности, и напечаталось бы следующее:
-----------------------------------------------
|
| mnttab
| utmp
| wtmp
|
Затем выход в таком виде может быть использован во внешней коман-
де для распечатки и анализа файловой информации.
Допустимыми опциями команды kind являются -a для файлов архивов,
-d для файлов данных, -t для текстовых файлов (что является умолчани-
ем) и -x для исполняемых файлов. Определение этих типов соответствует
команде UNIX file. Заметим, что критерии того, что файл является
исполняемым, в команде file отличаются от тех, которые применяет ко-
манда ls: ls проверяет биты x в индексном дескрипторе файла, в то вре-
мя как file проверяет, являются ли первые несколько байтов содержимого
файла "магическим числом". Это магическое число является идентификато-
ром структуры a.out (см. /usr/include/a.out.h), который сообщает "Я
являюсь скомпилированной Си-программой".
Имена файлов появляются в командной строке после опций. Эти имена
могут быть порождены любым стандартным методом системы UNIX. Если в
командной строке нет имен файлов, то kind превращается в фильтр и чи-
тает стандартный ввод для получения списка имен файлов. (Обратите вни-
мание, что я сказал "имен файлов", а не "файлов". Можно использовать
опции, поскольку они убираются из командной строки командой shift по
мере того, как они встречаются.) Таким образом, вы можете использовать
другие команды для того, чтобы передать по конвейеру список файлов
утилите kind. Она отфильтровывает и выводит только те из них, которые
соответствуют нужному вам типу.
1. $ od `kind -d /etc/*`
Выглядит так, как будто это должно работать, но команда od не ра-
ботает с набором имен файлов. Она может обрабатывать только один файл
в данный момент времени.
2. $ ll `sh -x kind -a /lib/*` | m
Это длинный пример. Выводит в длинном формате список всех файлов
архивов, которые находятся в каталоге /lib. Мы запускаем shell в отла-
дочном режиме выполнения, так что вы можете увидеть каждую командную
строку перед ее выполнением. Результат по конвейеру передается команде
more.
3. # find / -print | kind -x | while read FILE
> do
> ll $FILE
> done > /tmp/filelist
Данный цикл обнаруживает все действительно исполняемые файлы. Для
каждого из них выполняется команда "ls -l". Отметим, что здесь команда
ll вызывается для каждого имени файла.
Вы могли бы выполнить ту же операцию при помощи такого оператора
find:
# find / -perm -0111 -exec ll {} \;
но опция perm в данном случае опять же проверяет биты прав доступа в
индексном дескрипторе файла, а не ищет магическое число в структуре
a.out, как описано ранее. Кстати, для того, чтобы вы могли успешно за-
пустить команду file (и тем самым kind) на системных файлах, вы должны
иметь права чтения, чтобы можно было прочитать магическое число.
4. $ for F in `kind /bin/* /usr/bin/* /etc/*`
> do
> fgrep "trap" $F /dev/null
> done
$ fgrep "trap" `kind /bin/* /usr/bin/* /etc/*`
$ find /bin /usr/bin /etc -exec fgrep "trap" {} \;
Это три различных способа поиска слова "trap" во всех текстовых
файлах.
Опции, которые могут быть указаны в командной строке, должны быть
самым первым аргументом. Это создает более строгий синтаксис, по кото-
рому можно выловить ошибку. Но это несколько ограничивает гибкость.
Как было ранее отмечено, вы можете, если хотите, по-своему разрешить
компромисс между эффективностью и гибкостью путем дополнительного
программирования.
В строке 4 проверяется, включены ли какие-либо параметры. Если
параметры есть, то они обрабатываются. Если не используются никакие
параметры, ничего не делается и управление передается на строку 27.
Если были использованы какие-либо аргументы и первым символом яв-
ляется знак минуса (-), то выполняется оператор case для определения
того, какой тип файла указан. Переменная KIND устанавливается в соот-
ветствии с типом файла, и данный параметр удаляется из командной стро-
ки командой shift. Если аргумент не совпадает ни с одной из допустимых
опций, то ему соответствует случай *, что означает ошибку. На стан-
дартное устройство регистрации ошибок выводится соответствующее сооб-
щение об ошибке и синтаксическая подсказка, после этого kind заверша-
ется с плохим статусом выполнения.
В строке 27 производится проверка того, установлена переменная
KIND или равна нулю. Если она равна нулю, в нее подставляется символь-
ная строка "text". Если KIND уже установлена, то она не меняется. Это
неплохой оператор присвоения значения по умолчанию. Таким образом,
пользователь не обязан указывать опцию -t в командной строке. Если же
опция -t была указана, то ей есть что сопоставить в операторе case.
Оставшаяся часть программы в строках 29-35 представляет собой еще
один оператор case, который проверяет количество аргументов, остав-
шихся в командной строке после обработки ошибок. Если была указана ка-
кая-либо опция, то переменная KIND установлена и опция убрана командой
shift. В командной строке могли остаться только аргументы, которые яв-
ляются именами файлов или маршрутами. Если к тому времени, когда мы
уже готовы к заключительной обработке, не осталось никаких аргументов,
то значит в командной строке не было указано ни одного имени файла.
В этом случае в строках 30-33 организовывается цикл, который чи-
тает имена файлов из стандартного ввода, запускает команду file и
использует команду fgrep для определения того, соответствует ли тип
файла, выданный командой file, интересующему нас типу (хранимому в пе-
ременной KIND). Затем мы используем команду cut для выделения того,
что нам нужно. Обычный вывод команды file содержит имя файла, двоето-
чие и затем описание. Нам нужно только имя файла, поэтому мы вырезаем
первое поле, используя разделитель ":". Когда никакие данные больше не
поступают, цикл while завершается, мы попадаем в конец оператора case
и выходим из программы.
Если же аргументы НАЙДЕНЫ в командной строке, то вместо всего
этого выполняется ветвь оператора case в строке 34. С помощью обозна-
чения $@, имена всех файлов в командной строке включены в команду
file. Таким образом, не нужен никакой цикл. Во всем остальном обработ-
ка идентична строке 32.
Было бы неплохо, если бы командный файл kind мог работать однов-
ременно с разными типами файлов. Это означает наличие несколько опций
в командной строке, например -a и -d. Вам могла бы понадобиться
составная строка, в которой каждая часть была бы отделена символом |.
Затем эта строка могла бы быть использована в команде egrep, например,
"egrep 'archive|data'". Вам пришлось бы организовать цикл по командной
строке вместо использования фиксированных позиций и убедиться в том,
что вы не получите зациклившийся конвейер, когда задана только одна
опция.
2.2.4. m - простой доступ к команде more
-------------------------------------------------------------
ИМЯ: m
-------------------------------------------------------------
m Простой доступ к команде more
Обеспечивает быстрый и простой способ постраничного вывода
m [more options] [file ...]
m * Вывод командой more всех файлов текущего каталога
1 :
2 # @(#) m v1.0 Easy access to more
2а Простой доступ к команде more
4 /usr/bin/more $@
ОПИСАНИЕ
ЗАЧЕМ НУЖЕН КОМАНДНЫЙ ФАЙЛ m?
Система UNIX сильно загромождается по мере своего функционирова-
ния. В ней обычно имеется множество текстов и данных. Просмотр громад-
ного количества данных требует многократного нажатия на клавиши, если
вы должны вручную управлять постраничным выводом или периодически вы-
зывать команду more. Нам необходимы программные средства, которые по-
могут нам ускорить эту работу. Одним из таких средств является m. Оно
очень короткое и простое, но это не значит, что оно бесполезно.
Имеется два основных способа вывода данных на экран. Первый
способ - непосредственный вызов команды, например, "more datafile". Вы
направляете данные на экран самой командой. Второй способ - использо-
вать какую-нибудь команду для получения данных, а затем в конце перех-
ватить их командой more, например "od -c . | more". В обоих этих слу-
чаях мы вводим с клавиатуры много символов. Сделав так, чтобы команда
more вызывалась по одному символу, мы могли бы уменьшить последние две
команды на шесть нажатий на клавиши. За целый день это хоть немного
предохранит клавиатуру от разрушения! (Если ваша система поддерживает
ресурсами системы UNIX, они могут рассмотреть проблему и выбрать стра-
тегию, использующую наименее сложное средство, выполняющее данную ра-
боту с приемлемым уровнем производительности. В порядке возрастания
сложности, это могут быть непонятная, но существующая команда и/или
опция, псевдоним, командный файл интерпретатора shell или программа на
языке Си.
ЧТО ДЕЛАЕТ lc?
Общий подход к разработке этой команды заключается в том, чтобы
собрать вместе некоторые опции и сделать новую команду с более мощным
интерфейсом. Чтобы достичь этой мощи, мы можем сделать пре- или пост-
процессор для обычной команды системы UNIX.
Главная задача здесь - печать колонок, поэтому мы смотрим на оп-
ции команды ls, чтобы задействовать их. Конечно, мы включаем опцию -C.
Какие еще опции ls нам нужны? Обычно UNIX не печатает файлы, имена ко-
торых начинаются с точек, например, .profile, если только вы не указы-
ваете ls -a. Это забывается при просмотре этих важных файлов, поэтому
мы конструируем нашу команду так, чтобы она печатала их по умолчанию.
Никакие файлы не скрываются от нас. Для пользователей System V и BSD
(или для любого, кто имеет опцию -F), листинг улучшается за счет выво-
да "/" после имени каталога и "*" после исполняемого файла. Ранняя ко-
манда ls системы UNIX не имела возможности печатать в таком стиле. От-
метим, что данное использование термина "исполняемый" означает показ
того, что флаги прав доступа имеют бит "x", а не то, что это файл типа
a.out с магическим числом. Это отличие важно тем, что делает наш ко-
мандный файл более полезным.
Если ожидается длинная распечатка, как это бывает обычно для ре-
курсивных каталогов, то вы хотите иметь доступ к команде more. Мы
встраиваем команду more так, чтобы ее можно было активировать с по-
мощью опции -m. Опция -m должна быть первой опцией после имени коман-
ды, из-за способа, которым она проверяется внутри программы. Если она
передается после первой опции, она переходит к команде UNIX ls и ин-
терпретируется как печать в потоковом формате. Это такой формат, в ко-
тором все имена расположены в строках, разделенных запятыми (,). Как
мы уже отмечали, вы можете сделать интерфейс этого командного файла
более гибким за счет дополнительной работы над ним.
1. $ lc `path lc`
Получает полное имя для lc и распечатывает файловую информацию в
виде колонок.
2. $ lc -m -R /
Печатает колоночный список ВСЕХ файлов в системе, рекурсивно про-
ходя вниз по иерархии системного дерева и пропуская распечатку через
команду more.
Еще один маленький фокус: этот синтаксис был использован для соз-
дания другой команды, названной expose. Командная строка "lc -m -R $@"
давала бы рекурсивный список всех файлов в любом каталоге по вашему
выбору в приятном постраничном формате.
3. $ lc -m -R /usr/lib
Рекурсивно распечатывает список всех файлов во всех каталогах,
начиная с /usr/lib, и пропускает листинг через команду more.
4. $ lc -m . | more
Выдает список файлов в текущем каталоге и пропускает листинг че-
рез команду more, а затем снова пропускает все через more. Работает ли
это ? Никоим образом. Возникает полная путаница, и клавиша прерывания
обычно является наилучшим способом выхода из данной ситуации.
В строках 4-8 проверяется, является ли первым аргументом команд-
ной строки -m - опция команды more. Если эта опция найдена, то в пере-
менную MORE заносится указание конвейера и команда more. Тем самым
устанавливается постобработка, которую следует применить к выходу ко-
манды ls. Затем эта опция убирается из командной строки. Это делается
для того, чтобы остаток командной строки можно было передать команде
ls, не вызвав при этом нежелательных эффектов. Если первой опцией не
является -m, переменной MORE присваивается нулевое значение, чтобы она
впоследствии не влияла на командную строку.
Строка 10 - это командная строка, которую вы бы использовали на
старой UNIX-машине типа Version 7 или System III. Она не имеет ни
встроенной опции для печати символов косой черты (/) и звездочек (*),
ни возможности печати в виде колонок. Вы должны пожертвовать первой
возможностью, а распечатки в виде нескольких колонок можно получить с
помощью команды pr системы UNIX. Команда pr использована с опцией
"-5t", поэтому она печатает в пять колонок (что обычно приемлемо, но
если встречаются длинные имена файлов, то пяти колонок может оказаться
слишком много) и не печатает верхний и нижний колонтитулы. Благодаря
отказу от колонтитулов, 24-строчный формат не слишком неудобен для
вас.
Отметим, что здесь использована команда eval. Это специальная
встроенная команда интерпретатора shell, которая выполняет перевы-
числение текущей строки, подлежащей выполнению. Интерпретатор shell
повторно анализирует эту строку, чтобы раскрыть значение имен перемен-
ных в командной строке и обеспечить распознавание переменных как тако-
вых. Здесь мы перевычисляем переменную MORE. Напомним, что мы помести-
ли в эту переменную конвейер. Если мы не перевычислим командную стро-
ку, то команда pr попытается открыть файлы "|" и "more", которые не
существуют. Для того, чтобы shell вместо этого воспринял эти символы
как указания конвейеров и программ, и используется команда eval.
Строка 10 имеет еще одну особенность. В командной строке уже есть
один конвейер. Откуда shell знает, трактовать ли символ "|" как имя
файла или как конвейер? Благодаря тому, что аргумент команды eval зак-
лючен в кавычки. Это указывает команде eval сохранить все, что нахо-
дится в кавычках, без изменений, но раскрыть значение переменной MORE
и поместить его в конец командной строки, находящейся в кавычках.
Несколько непонятно, но если вы думаете об этом пару лет, оно стано-
вится осмысленным.
Для тех из вас, кто имеет новую команду ls (System V, версия 2
или BSD 4.2), не требуется два конвейера в команде. Как показывает
строка 11, мы получаем подходящий колоночный формат из самой команды
ls, вместе с показом всех файлов и специальными символами / и * для
каталогов и исполняемых файлов. Обозначение $@ относится ко всему со-
держимому командной строки, т.е. к вашим дополнительным опциям команды
ls и к именам файлов, список которых вы хотите распечатать. Поступая
таким образом, мы создаем фундамент (опции a,C,F), а вы можете
надстраивать его (используя опции R,t и т.д.). Скромный, но элегантный
фокус заставить ls сообщить свои опции заключается в том, чтобы выз-
вать ее с неверной опцией. Большинство команд не используют опции z
или ?, поэтому вызов "ls -z" или "ls -?" приведет к такому результату:
--------------------------------
|
| ls: illegal option -- z
| usage: -1ACFRabcdfgilmnopqrstux [files]
|
Все эти опции представляют определенный интерес. Если вы часто
используете какие-либо из них, поместите их в командный файл lc, и вы
получите вашу собственную адаптированную команду.
Вы обратили внимание, что все обычные команды системы UNIX,
используемые в нашем командном файле, имеют полные маршрутные имена?
Это может показаться несколько странным, но причина указания полных
маршрутных имен в том, что когда shell запускает команду, он не должен
возвращаться к анализу переменной PATH и искать, где расположена ко-
манда. Если вы обращаетесь к командам относительным способом, время
поиска файлов представляет собой большие накладные расходы. Когда вы
вызываете lc, интерпретатор shell ищет эту команду, затем lc вызывает
ls, которую тоже нужно найти. Если после этого результаты пропускаются
через more или pr, то требуется дополнительный поиск. А полные марш-
рутные имена распознаются интерпретатором shell сразу же (он видит,
что первым символом является /), и нужная команда может быть вызвана
быстро. Издержки на поиск - единственные издержки команды lc.
Использование полных имен, естественно, требует, чтобы вы знали,
где в системе размещены утилиты, к которым вы хотите обратиться. Вы
можете применить команду paths, чтобы получить корректные полные имена
для жесткого указания их в тексте вашего командного файла, а можете
переписать данный командный файл при переходе в другую систему. Это
просто еще одна иллюстрация универсального компромисса между скоростью
и эффективностью, с одной стороны, и гибкостью и мобильностью, с дру-
гой.
2.2.2. ll - вывод файловой информации в длинном формате
-------------------------------------------------------------
ИМЯ: ll
-------------------------------------------------------------
ll Выдает список файлов в длинном формате
Выдает список файлов в длинном формате (-l). Распечатку можно
пропустить через команду more.
ll [-m] [ls options] file [file...]
ll *.c Выдача списка файлов с исходными текстами на
языке Си в длинном формате.
1 :
2 # @(#) ll v1.0 Long listing of files Author: Russ Sage
2а Выводит список файлов в длинном формате
4 if [ "$1" = "-m" ]
5 then MORE="| /usr/bin/more"
6 shift
7 else MORE=""
8 fi
10 eval /bin/ls -al $@ MORE
MORE Содержит строку передачи результатов по
конвейеру команде more
ОПИСАНИЕ
ЗАЧЕМ НАМ НУЖЕН КОМАНДНЫЙ ФАЙЛ ll?
Мотивы для создания команды ll те же, что мы обсудили ранее для
команды lc. Мы можем использовать ll для нескольких целей. Она умень-
шает количество требуемых нажатий на клавиши, позволяет избежать необ-
ходимости помнить специальные опции и вообще настраивает систему соот-
ветственно нашим требованиям вместо того чтобы нам приспосабливаться к
системе.
ЧТО ДЕЛАЕТ ll?
Основой этой команды является известная команда "ls -l". Она,
если вы помните, дает очень емкую информацию о каждом файле, включая
права доступа, связи, имя владельца, размер и так далее. (Кстати,
программисты, использующие язык Си, могут получить эту информацию при
помощи системного вызова stat(2).) Поскольку такой список при наличии
множества файлов может легко переполнить экран, то предоставляется оп-
ция -m. Она обеспечивает постраничный вывод с помощью команды more.
Отметим, что если используется эта опция, то она должна стоять первой.
Строка символов, соответствующая этой опции, удаляется командой shift,
так что она не смешивается с именами файлов и обычными опциями команды
ls, которые передаются как аргументы.
После опции -m (если она есть) ll допускает указание любых других
допустимых опций команды ls. Можно также использовать любую комбинацию
имен файлов. Здесь применимы обычные средства порождения имен файлов:
* соответствует любым символам, ? - одному символу, а символы [] зада-
ют диапазон из некоторого набора символов. В итоге мы получили команду
ls, которая по умолчанию работает как "ls -l", вызывает команду more с
помощью одной опции вместо необходимости указания конвейера в команд-
ной строке и при этом сохраняет гибкость команды ls.
1. $ ll /etc/*mount*
Выводит список всех файлов в каталоге /etc, имена которых содер-
жат в каком-либо месте слово mount (например, mount, umount,
unmountable).
2. $ ll -i `who|awk '{print "/dev/" $2}'`
Сперва выполняется команда who, затем результат ее работы по кон-
вейеру передается команде awk, которая вырезает имя устройства и при-
писывает ему префикс /dev/. В результате список полных маршрутных имен
ко всем терминальным устройствам, зарегистрированным в настоящий мо-
мент, помещается в командную строку команды ls -li. В распечатке ука-
зана вся информация об индексном дескрипторе файла (inode) для каждого
терминального устройства.
3. $ ll `kind -a /lib`
Выводит в длинном формате список всех файлов архива в каталоге
/lib. Этот каталог содержит библиотеки компиляторов всех языков систе-
мы UNIX. (Команда kind, которая отбирает файлы по их типу, рассматри-
вается в следующем разделе.)
4. $ ll -m -i /dev
Выводит всю обычную информацию плюс номер индексного дескриптора
для всех файлов в каталоге /dev. Выдача на экран происходит с помощью
команды more.
Если первым позиционным параметром является -m, то в строке 4
инициализируется переменная MORE для подключения конвейера и программы
/usr/bin/more. (Вопрос о том, почему используется абсолютное маршрут-
ное имя, обсуждался в предыдущем разделе.) Затем символьная строка -m
командой shift убирается из командной строки. Если же первой опцией не
является -m, то переменная MORE устанавливается в нуль, чтобы не вли-
ять на повторный разбор командной строки, выполняемый с помощью коман-
ды eval (строка 10).
В строке 10 команда eval использована для получения результирую-
щей командной строки. Команда ls вызывается с опциями -al (выдача
списка всех файлов в длинном формате), которые мы установили по умол-
чанию. Затем берутся аргументы командной строки (минус первый аргу-
мент, если это был -m, который мы убрали командой shift). Этими аргу-
ментами могут быть дополнительные опции команды ls плюс имена файлов
или каталогов. В конце строки значение переменной MORE обеспечивает
конвейер с командой more, если была указана опция -m. В противном слу-
чае значение переменной MORE равно нулю и не оказывает никакого влия-
ния на анализ содержимого командной строки.
Что произошло бы, если бы пользователь указал опцию -m в качестве
второй (или последующей) опции? В этом случае опция -m передалась бы
команде ls. Команда ls трактовала бы эту опцию как "потоковый вывод",
а это совсем не то, что мы хотели. Однако команда ls была вызвана так-
же с опцией -l, которая отменяет опцию -m в соответствии с текстом
программы ls. Вы не получили бы вывод с помощью команды more, но ваши
выходные данные по-прежнему были бы выведены в правильном формате.
2.2.3. kind - вывод однотипных файлов
-------------------------------------------------------------
ИМЯ: kind
-------------------------------------------------------------
kind Выдача списка имен файлов определенного вида
Выбирает и выводит имена всех файлов в указанном каталоге (ката-
логах), имеющих указанный тип. Если не указан никакой тип, выбираются
текстовые файлы.
kind [-a] [-d] [-t] [-x] [file...]
more `kind /etc/*`
Вывод командой more всех текстовых файлов, имеющихся в катало-
ге /etc.
1 :
2 # @(#) kind v1.0 Prints files of the same kind Author: Russ Sage
2а Выводит список файлов определенного вида
4 if [ $# -gt 0 ]
5 then if [ `echo $1 | cut -c1` = "-" ]
6 then case #1 in
7 -a) KIND='archive'
8 shift;;
9 -d) KIND='data'
10 shift;;
11 -t) KIND='text'
12 shift;;
13 -x) KIND='executable'
14 shift;;
15 *) echo "kind: arg error" >&2
16 echo "usage: kind [-a] [-d] [-t] [-x] [file...]" >&2
17 echo " -a archive" >&2
18 echo " -d data" >&2
19 echo " -t text, default" >&2
20 echo " -x executable" >&2
21 echo " if no args, reads stdin" >&2
22 exit 1;;
23 esac
24 fi
25 fi
27 : ${KIND:='text'}
29 case $# in
30 0) while read FILE
31 do
32 file $FILE | fgrep $KIND | cut -d: -f1
33 done;;
34 *) file $@ | fgrep $KIND | cut -d: -f1;;
35 esac
FILE Содержит имена файлов по мере их чтения из stdin
(стандартного ввода)
KIND Содержит строку, определяющую тип файла
ОПИСАНИЕ
ЗАЧЕМ НУЖЕН КОМАНДНЫЙ ФАЙЛ kind?
Файловая система UNIX имеет строгие стандарты при рассмотрении
файлов. Имеется три вида файлов: обычные файлы (тексты, данные, испол-
няемые файлы), каталоги и устройства. Каждый вид файлов имеет свое
предназначение и обычно имеет особые команды или файлы данных, которые
работают с ним.
Давайте рассмотрим, как некоторые из существующих команд системы
UNIX рассматривают типы файлов. Команда ls делает различие между ката-
логами и другими файлами, поэтому она может быть полезна. Другой важ-
ной командой является команда file. Она сообщает вам, какой тип имеет
данный файл, что потенциально полезно, но слишком мало. Для того чтобы
извлечь из команды file какую-либо полезную информацию, вы должны
надстроить над ней некоторую программу. Что нам действительно нужно,
так это некий гибрид команд ls и file, т.е. утилита, которая выводит
имена всех файлов указанного типа.
Примером полезности такого рода утилиты может служить анализ со-
держимого каталогов. Возьмем, например, каталог /etc. Он содержит
программы, файлы данных и текстовые файлы. Для каждого из этих типов
требуется свой собственный тип анализа. Программы анализируются коман-
дами ls, size, nm и file. Файлы данных анализируются командой od.
Текстовые файлы анализируются командами more, wc, head, tail и други-
ми. Таким образом, обычно вам необходимо работать в данный момент вре-
мени с файлами какого-нибудь одного типа.
ЧТО ДЕЛАЕТ kind?
Командный файл kind - это утилита, которая распечатывает имена
всех файлов, имеющих указанный тип. Она имеет интерфейс, похожий на
интерфейс команды ls, т.е. вы можете передать ей опции и имена файлов
или символы расширения имен файлов. При выводе отображаются полные
имена, если они были указаны, но вы можете избежать появления лишней
информации при выводе, если предварительно перейдете в нужный каталог
с помощью команды cd. Например, если бы я находился в моем регистраци-
онном каталоге (/usr/russ) и ввел команду
$ kind -d /etc/*
то вывод мог бы выглядеть так:
--------------------------------
|
| /etc/mnttab
| /etc/utmp
| /etc/wtmp
|
То есть, вывелся список всех файлов данных. А если бы я выполнил
такую последовательность команд:
$ cd /etc
$ kind -d *
то при выводе убрался бы маршрут, использованный в вызывающей последо-
вательности, и напечаталось бы следующее:
-----------------------------------------------
|
| mnttab
| utmp
| wtmp
|
Затем выход в таком виде может быть использован во внешней коман-
де для распечатки и анализа файловой информации.
Допустимыми опциями команды kind являются -a для файлов архивов,
-d для файлов данных, -t для текстовых файлов (что является умолчани-
ем) и -x для исполняемых файлов. Определение этих типов соответствует
команде UNIX file. Заметим, что критерии того, что файл является
исполняемым, в команде file отличаются от тех, которые применяет ко-
манда ls: ls проверяет биты x в индексном дескрипторе файла, в то вре-
мя как file проверяет, являются ли первые несколько байтов содержимого
файла "магическим числом". Это магическое число является идентификато-
ром структуры a.out (см. /usr/include/a.out.h), который сообщает "Я
являюсь скомпилированной Си-программой".
Имена файлов появляются в командной строке после опций. Эти имена
могут быть порождены любым стандартным методом системы UNIX. Если в
командной строке нет имен файлов, то kind превращается в фильтр и чи-
тает стандартный ввод для получения списка имен файлов. (Обратите вни-
мание, что я сказал "имен файлов", а не "файлов". Можно использовать
опции, поскольку они убираются из командной строки командой shift по
мере того, как они встречаются.) Таким образом, вы можете использовать
другие команды для того, чтобы передать по конвейеру список файлов
утилите kind. Она отфильтровывает и выводит только те из них, которые
соответствуют нужному вам типу.
1. $ od `kind -d /etc/*`
Выглядит так, как будто это должно работать, но команда od не ра-
ботает с набором имен файлов. Она может обрабатывать только один файл
в данный момент времени.
2. $ ll `sh -x kind -a /lib/*` | m
Это длинный пример. Выводит в длинном формате список всех файлов
архивов, которые находятся в каталоге /lib. Мы запускаем shell в отла-
дочном режиме выполнения, так что вы можете увидеть каждую командную
строку перед ее выполнением. Результат по конвейеру передается команде
more.
3. # find / -print | kind -x | while read FILE
> do
> ll $FILE
> done > /tmp/filelist
Данный цикл обнаруживает все действительно исполняемые файлы. Для
каждого из них выполняется команда "ls -l". Отметим, что здесь команда
ll вызывается для каждого имени файла.
Вы могли бы выполнить ту же операцию при помощи такого оператора
find:
# find / -perm -0111 -exec ll {} \;
но опция perm в данном случае опять же проверяет биты прав доступа в
индексном дескрипторе файла, а не ищет магическое число в структуре
a.out, как описано ранее. Кстати, для того, чтобы вы могли успешно за-
пустить команду file (и тем самым kind) на системных файлах, вы должны
иметь права чтения, чтобы можно было прочитать магическое число.
4. $ for F in `kind /bin/* /usr/bin/* /etc/*`
> do
> fgrep "trap" $F /dev/null
> done
$ fgrep "trap" `kind /bin/* /usr/bin/* /etc/*`
$ find /bin /usr/bin /etc -exec fgrep "trap" {} \;
Это три различных способа поиска слова "trap" во всех текстовых
файлах.
Опции, которые могут быть указаны в командной строке, должны быть
самым первым аргументом. Это создает более строгий синтаксис, по кото-
рому можно выловить ошибку. Но это несколько ограничивает гибкость.
Как было ранее отмечено, вы можете, если хотите, по-своему разрешить
компромисс между эффективностью и гибкостью путем дополнительного
программирования.
В строке 4 проверяется, включены ли какие-либо параметры. Если
параметры есть, то они обрабатываются. Если не используются никакие
параметры, ничего не делается и управление передается на строку 27.
Если были использованы какие-либо аргументы и первым символом яв-
ляется знак минуса (-), то выполняется оператор case для определения
того, какой тип файла указан. Переменная KIND устанавливается в соот-
ветствии с типом файла, и данный параметр удаляется из командной стро-
ки командой shift. Если аргумент не совпадает ни с одной из допустимых
опций, то ему соответствует случай *, что означает ошибку. На стан-
дартное устройство регистрации ошибок выводится соответствующее сооб-
щение об ошибке и синтаксическая подсказка, после этого kind заверша-
ется с плохим статусом выполнения.
В строке 27 производится проверка того, установлена переменная
KIND или равна нулю. Если она равна нулю, в нее подставляется символь-
ная строка "text". Если KIND уже установлена, то она не меняется. Это
неплохой оператор присвоения значения по умолчанию. Таким образом,
пользователь не обязан указывать опцию -t в командной строке. Если же
опция -t была указана, то ей есть что сопоставить в операторе case.
Оставшаяся часть программы в строках 29-35 представляет собой еще
один оператор case, который проверяет количество аргументов, остав-
шихся в командной строке после обработки ошибок. Если была указана ка-
кая-либо опция, то переменная KIND установлена и опция убрана командой
shift. В командной строке могли остаться только аргументы, которые яв-
ляются именами файлов или маршрутами. Если к тому времени, когда мы
уже готовы к заключительной обработке, не осталось никаких аргументов,
то значит в командной строке не было указано ни одного имени файла.
В этом случае в строках 30-33 организовывается цикл, который чи-
тает имена файлов из стандартного ввода, запускает команду file и
использует команду fgrep для определения того, соответствует ли тип
файла, выданный командой file, интересующему нас типу (хранимому в пе-
ременной KIND). Затем мы используем команду cut для выделения того,
что нам нужно. Обычный вывод команды file содержит имя файла, двоето-
чие и затем описание. Нам нужно только имя файла, поэтому мы вырезаем
первое поле, используя разделитель ":". Когда никакие данные больше не
поступают, цикл while завершается, мы попадаем в конец оператора case
и выходим из программы.
Если же аргументы НАЙДЕНЫ в командной строке, то вместо всего
этого выполняется ветвь оператора case в строке 34. С помощью обозна-
чения $@, имена всех файлов в командной строке включены в команду
file. Таким образом, не нужен никакой цикл. Во всем остальном обработ-
ка идентична строке 32.
Было бы неплохо, если бы командный файл kind мог работать однов-
ременно с разными типами файлов. Это означает наличие несколько опций
в командной строке, например -a и -d. Вам могла бы понадобиться
составная строка, в которой каждая часть была бы отделена символом |.
Затем эта строка могла бы быть использована в команде egrep, например,
"egrep 'archive|data'". Вам пришлось бы организовать цикл по командной
строке вместо использования фиксированных позиций и убедиться в том,
что вы не получите зациклившийся конвейер, когда задана только одна
опция.
2.2.4. m - простой доступ к команде more
-------------------------------------------------------------
ИМЯ: m
-------------------------------------------------------------
m Простой доступ к команде more
Обеспечивает быстрый и простой способ постраничного вывода
m [more options] [file ...]
m * Вывод командой more всех файлов текущего каталога
1 :
2 # @(#) m v1.0 Easy access to more
2а Простой доступ к команде more
4 /usr/bin/more $@
ОПИСАНИЕ
ЗАЧЕМ НУЖЕН КОМАНДНЫЙ ФАЙЛ m?
Система UNIX сильно загромождается по мере своего функционирова-
ния. В ней обычно имеется множество текстов и данных. Просмотр громад-
ного количества данных требует многократного нажатия на клавиши, если
вы должны вручную управлять постраничным выводом или периодически вы-
зывать команду more. Нам необходимы программные средства, которые по-
могут нам ускорить эту работу. Одним из таких средств является m. Оно
очень короткое и простое, но это не значит, что оно бесполезно.
Имеется два основных способа вывода данных на экран. Первый
способ - непосредственный вызов команды, например, "more datafile". Вы
направляете данные на экран самой командой. Второй способ - использо-
вать какую-нибудь команду для получения данных, а затем в конце перех-
ватить их командой more, например "od -c . | more". В обоих этих слу-
чаях мы вводим с клавиатуры много символов. Сделав так, чтобы команда
more вызывалась по одному символу, мы могли бы уменьшить последние две
команды на шесть нажатий на клавиши. За целый день это хоть немного
предохранит клавиатуру от разрушения! (Если ваша система поддерживает