Рассел Сейдж. Приемы профессиональной работы в unix перевод "Tricks of the unix masters" by Russel G

Вид материалаДокументы

Содержание


Возможные модификации
Формат вызова
Формат вызова
Переменные среды выполнения
Подобный материал:
1   ...   5   6   7   8   9   10   11   12   ...   45

могут быть порождены любым стандартным методом системы 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 вызывалась по одному символу, мы могли бы уменьшить последние две

команды на шесть нажатий на клавиши. За целый день это хоть немного

предохранит клавиатуру от разрушения! (Если ваша система поддерживает

вызов команд по псевдонимам (aliasing), то, как указывалось ранее, вы

могли бы использовать в этом случае команду alias: "alias m more".)


ЧТО ДЕЛАЕТ m?


Надеемся, все ваши системы имеют команду more или хотя бы ее за-

мену. Постраничный вывод имеет важное значение при работе с текстом

большого объема.

Все опции и аргументы передаются в командной строке. Вы можете

указать опции команды more в командной строке команды m. Они переда-

ются без изменений. Можно указать имена файлов. Если они указаны, ко-

манда more выводит их. В противном случае ожидается поступление данных

со стандартного ввода. Таким образом, m может быть использована в ка-

честве "перехватчика" или как фильтр, как и команда more.

Для тех, кто не слишком знаком с опциями команды more, отметим,

что существуют две изящные возможности: 1) вход в редактор vi в том

месте, где находится курсор при выводе командой more; 2) выход из more

для запуска команды shell и возврат в то место, откуда вы вышли. Пер-

вая опция выполняется при нажатии клавиши "v" в строке состояния ко-

манды more. (То есть когда more отобразила полный экран текста и ждет

продолжения.) Вторая опция запускается при вводе ":!cmd" или "!cmd".

Когда команда выполнится, more вернется в то же место. Как видите, это

синтаксис командной строки ex. Команда more в самом деле имеет неболь-

шую часть редактора ex, спрятанную внутри нее. Вы можете выполнить

многие команды редактора, указывая их после подсказки в строке состоя-

ния команды more.


Обычный сеанс работы выглядит так:


------------------------------------------------------------------------


|

| m `path termcap` <-поиск таблицы описания тер-

| минала (termcap) и вывод

| . ее командой more

.

.

--More--(5%) <-строка состояния more

v vi /etc/termcap

vi +210 /etc/termcap <-командная строка для редак-

тора vi получена от more

.

.

:q <-выход из vi

--More--(5%) <-возврат в more

:!sh порождение нового shell'а

$ date запуск команды date

Wed Apr 23 07:15:04 PST 1986

$ d <-убрать порожденный shell

--More--(5%) <-возврат в more

:f распечатка имени файла,

выводимого командой more

"/etc/termcap" line 54 выход команды f

--More--(5%)

f <-команда more для пропуска

полного экрана

.skipping 23 lines

.

.

--More--(9%) <-пропуск и выдача текста

q выход из команды more


ПРИМЕРЫ


1. $ ll -R / | m


Начиная с корневого каталога (/), вывести в длинном формате (ll)

все файлы (опция -a подразумевается в ll) всей системы (-R) и постра-

нично распечатать на экран (| m).


2. $ m `path inittab rc passwd`


Обнаружить и вывести с помощью more системные файлы inittab, rc и

passwd. Неприятность здесь заключается в том, что данный маршрут ско-

рее всего относится к каталогу /bin/passwd, а не /etc/passwd (посколь-

ку каталог /etc размещается в конце каталогов), а это означает, что вы

можете попытаться вывести на экран исполняемый файл. В зависимости от

того, какую из версий команды more вы запустили, это может привести к

чему угодно начиная с сообщения команды more о том, что это был не

текстовый файл, и заканчивая тем, что ваш терминал начнет показывать

непонятные символы и даже зависнет.


ПОЯСНЕНИЯ


Поскольку в этом командном файле не так много текста, то все до-

вольно понятно, нет ни обработки ошибок, ни других дополнений. Просто

нехитрый вызов команды more. Полное имя здесь указано с целью повыше-

ния быстродействия, как мы обсуждали ранее. Вы должны перепроверить

местонахождение вашей команды more. В системе Berkeley она может нахо-

диться в каталоге /usr/ ucb/more. Воспользуйтесь командой path more

для определения этого места и вставьте соответствующий маршрут вместо

указанного нами.

Кстати, фокус попадания этой символьной строки в текст вашего ко-

мандного файла состоит в том, чтобы войти в редактор и вызвать следую-

щую команду:


:.!path more


Здесь происходит переход в shell и запуск команды path (:!), за-

тем выход команды path (который представляет собой полное маршрутное

имя) помещается в буфер редактора в самом начале текущей строки (.).

После этого вы имеете эти данные в вашем редактируемом файле и при не-

обходимости можете отредактировать их.


2.2.5. mmm - обработка программой nroff макрокоманд для рукописей


------------------------------------------------------------------------


ИМЯ: mmm

------------------------------------------------------------------------


mmm Командная строка nroff для макросов обработки

рукописей


НАЗНАЧЕНИЕ


Вызывает текстовый процессор nroff со специальными опциями, кото-

рые инициализируют макросы обработки рукописей.


ФОРМАТ ВЫЗОВА


mmm file [...]


ПРИМЕР ВЫЗОВА


mmm memo Обработать с помощью nroff файл моих заметок

memo и отобразить его на экран


ТЕКСТ ПРОГРАММЫ


1 :

2 # @(#) mmm v1.0 Nroff command line with mm macros Author: Russ Sage

2а Командная строка nroff с макросами mm


4 if [ "$#" -eq 0 ]

5 then echo "mmm: wrong arg count" >&2

6 echo "usage: mmm file [...]" >&2

7 exit 1

8 fi


10 LIST=""

11 for ARG in $*

12 do

13 if [ ! -f $ARG ]

14 then echo "mmm: $ARG is not a regular file" >&2

15 else LIST="$LIST $ARG"

16 fi

17 done


19 nroff -r0O -mm $LIST


ПЕРЕМЕННЫЕ СРЕДЫ ВЫПОЛНЕНИЯ


ARG Содержит каждый позиционный параметр командной

строки

LIST Содержит список проверяемых имен файлов


ОПИСАНИЕ


ЗАЧЕМ НУЖЕН КОМАНДНЫЙ ФАЙЛ mmm?


Одним из фактов делового мира является работа с бумагами. Мы про-

изводим заметки, письма, контракты, документы, руководства и так да-

лее. Если вы знакомы со стилем производства документации в системе

UNIX, то ваши текстовые файлы в основном представлены в одном из фор-

матов программы nroff.

Однако различные программы форматирования текстов служат различ-

ным целям. Имеется стандартный nroff и nroffс дополнениями, такими

как макросы ms и mm. Для подготовки графической информации и выполне-

ния типографских работ разработана программа troff. Система AT&T имеет

целую программную среду под названием Writers Workbench, и система

Berkeley имеет аналогичные возможности.

Большинство наших задач по написанию каких-либо текстов может

быть сведено к нескольким стандартным форматам, таким как письма, ру-

кописи вообще, страницы руководств и так далее. Не так легко запомнить

опции команды nroff (или другой команды), которые следует использовать

в данном случае, да мы и не должны делать это. Наша команда mmm служит

иллюстрацией программы, которую мы можем запускать всякий раз, когда

нам нужен определенный формат. Вы можете создать несколько версий

программы, которые удовлетворяют вашим собственным нуждам при написа-

нии текстов.

Использование заготовленных заранее команд означает, что мы можем

делать полезную работу, даже если некоторое время мы не выполняли ра-

боту определенного вида. Мы также можем избежать многократных нажатий

на клавиши. Мастера UNIX'а периодически уединяются в своих горных убе-

жищах, где штудируют справочные руководства в поисках полезных, но

доселе незамеченных опций, которые могут быть встроены в программные

средства для повседневной работы. Если слишком некритично полагаться

на ваш текущий набор инструментальных средств, то можно пропустить по-

лезные возможности.


ЧТО ДЕЛАЕТ mmm?


Командный файл mmm - это интерфейсный процессор для команды

nroff. Под словом "интерфейсный" мы подразумеваем, что он обрабатывает

вызывающую командную строку и устанавливает все опции для вызова прог-

раммы nroff. Некоторые из опций nroff жестко запрограммированы в вызо-

ве. Эти опции инициализируют отдельные части программы nroff.

Если вы не включаете никакие аргументы, mmm распознает это как

ошибку и выводит синтаксическую подсказку. Обратите внимание, что если

вы передадите mmm такой аргумент, как -z, то этот аргумент будет

рассматриваться как имя файла, а не как подлежащая передаче опция, и

это снова вызовет ошибку. Вторая ошибка не является фатальной, в то

время как первая фатальна.

После обработки всех аргументов программа nroff использует имена

файлов в качестве файлов с входными данными. По умолчанию вывод произ-

водится в stdout (стандартный вывод). Обычно это экран вашего термина-

ла, но вывод может быть переадресован или передан по конвейеру на уст-

ройство печати или куда-либо еще.


ПРИМЕРЫ


1. $ mmm nroffile | m


Запуск команды nroff применительно к файлу nroffile, вывод ре-

зультата на экран с передачей по конвейеру команде more. Это полезно

при изучении утилиты nroff, проведении экспериментов с различными ко-

мандами и наблюдения за соответствующими результатами.


2. $ for F in proj.?

do

mmm $F > $F.rf

done


Обработка в цикле всех файлов, имена которых содержат символьную

строку "proj.", за которой следует один символ. Это могут быть proj.1,

proj.2 и так далее по всему набору символов вплоть до proj.z, proj.{,

proj.|, proj.} и proj.~, если считать, что у вас есть файлы, имена ко-

торых содержат эти символы. Каждый файл обрабатывается, и выход nroff

перенаправляется в файл с таким же именем, дополненным символами .rf.


3. $ mmm status[12] | lpr -o5


Обработка командой nroff файлов status1 и status2. Выход в стан-

дартный вывод передается по конвейеру программе lpr. Программа lpr яв-

ляется фильтром и принимает или имена файлов в командной строке, или

непосредственно данные, передаваемые ей по конвейеру (но не то и дру-

гое сразу). Опция -o5 указывает lpr сместить страницу на 5 символов.


ПОЯСНЕНИЯ


В строке 4 проверяется, равно ли нулю количество аргументов в ко-

мандной строке. Если да, в стандартный файл ошибок выдается сообщение

об ошибке. Выводится также синтаксическая подсказка, и mmm завершается

с плохим статусом.

Переменная LIST инициализируется нулевым значением в строке 10.

Обычно переменные интерпретатора shell и так в начале равны нулю, но

предварительная установка значения является хорошим стилем программи-

рования.

Затем мы обрабатываем каждый аргумент командной строки в цикле

(строки 11-17). Все аргументы должны быть именами файлов, поэтому каж-

дый из них проверяется на то, существует ли он как обычный файл. Если

это не файл, то в стандартный файл ошибок выводится сообщение об ошиб-

ке. Тем не менее программа не завершается. Не следует аварийно прекра-

щать всю программу только потому, что нет указанного файла. Мы про-

пускаем его и идем до конца списка аргументов. Это особенно актуально,

если данная команда используется как фоновая во время выполнения дру-

гой работы. Пользователь скорее согласится с тем, чтобы было выполнено

побольше работы, чем не сделано вообще ничего. Это решение, принятое в

данной программе, и вы можете изменить его, если оно не подходит в ва-

шей ситуации.

Если имени соответствует допустимый файл, оно добавляется в

список хороших имен файлов. Этот список становится главным списком для

команды nroff.