вится осмысленным.
Для тех из вас, кто имеет новую команду 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. Он содержит
программы, файлы данных и текстовые файлы. Для каждого из этих типов
требуется свой собственный тип анализа. Программы анализируются коман-