Программирование командных оболочек в Unix, Linux и OS X [Стефан Кочан] (pdf) читать онлайн

Книга в формате pdf! Изображения и текст могут не отображаться!


 [Настройки текста]  [Cбросить фильтры]

4-е издание

Программирование
командных
оболочек
в Unix, Linux и OS Х

Программирование
командных оболочек
в Unix, Linux и OS Х
4-е издание

Programming in
Unix, Linux and OS Х

Shell

Fourth Edition

Stephen G. Kochen
Patrick Wood


......

Addison
Wes\ey
800 East 96th Street.
lndianapolis. lndiana 46240

Программирование
командных оболочек
в Unix, Linux и OS Х
4-е издание

Стефан Кочан и Патрик Вуд

Москва



Санкт-Петербург
2017



Киев

ББК 32.973.26-018.2.75
К75

УДК 681.3.07
Компьютерное издательство "Диалектика"
Зав. редакцией С. Н. Тригуб
Перевод с английского и редакция И.В. Берштейна
По общим вопросам обращайтесь в издательство "Диалектика" по адресу:
info@dialektika.com, http://www.dialektika.com

Кочан,

Стефан, Вуд, Патрик.
Программирование командных оболочек в Unix, Linux и OS Х, 4-е изд.: Пер. с англ. СпБ.: ООО ''Альфа-книга': 2017. - 432 с.: ил. - Парал. тит. англ.

К75

ISBN

978-5-9909445-3-4

(рус.)
ББК 32.973.26-018.2.75

Все названия 11рограммных продуктов являются зарегистрирова1111ыми торювыми марками соответ­
ствующих фирм.

1 lикакая

•1асть настоящего издания ни в каких целях не может быть 11оспроизведена в какой бы то 11и

бь1110 форме и какими бы то 11и было средствами. будь то злектроrшыс и11и мсха11и•1еские, вк11ю•1ан фотоко·
пирование и запись на магнитный носитель, если на зто нет пис1.мен11оt·о разреше11ин издатс11ьства Addison­

Wesley Publishiпg Company. lnc .

Authorized lranslation from the English laпguage cdition publishcd hy Addison-Wcsley l'uhlishiпg Company.

lnc. Copyright (cJ 2017 hy Pearsoп Education, !пс.
All rights rcscrved. No part of this hook shall hc reproduccd, stored i11 а retrieval system. or lransmittcd hy
а11у meaпs, electronic, mechanical, photocopyiпg. recordiпg. or othcrwise, without writtcn permission from thc
publisher.

Russian language editior1 is puhlished hy Williams Puhlishing l louse accordiпg

lo thc Agrecmcnt with R&I

E11terprist·s lnternationa\, Copyright CCJ 2017.

Научно-популярное издание

Стефан Кочан, Патрик Вуд

Программирование командных оболочек в Unix, Linux и OS Х
4-еиздание
Литературный редактор
Верстка
Художественный редактор
Корректор

И.А. Попова
Л.В. Чернокозинская
В.Г. Павлютин
Л.А. Гордиенко

llодписано в пс•rать 12.07.2017. Формат 70х100/16.
Гар11итура Tirnes. Пе•rать офсет11ая.
Усл. 11е•1. л. 34,8. У •1 .-юд. л. 17.8.
Тираж 300 эк з. Заказ

№ 4866.

Отпе•1ата1ю в АО «llервая Образцовая типоr·рафия»

Филиал «Чеховский llсчатный Лвор»
142300, Московская об11асть, г. Чехов, ул. Полиграфистов, д.1
ООО "Альфа-книга", 195027, Санкт-1 lеп:рбург, Магнитогорская ул" д. 30

ISBN 978-5-9909445-3-4

(рус.)

> для переадресаци и (л юбоп ытно, что для переадресаци и вво­
да имеется еще одна последовательность знаков, для переадресаци и вывода и интер­
претирует следующее слово в командной строке как имя файла, в который пере­
адресовывается резуп ьтат выполнения команды e cho (в дан ном случае - это
файл remi nde r). Если файл remi nde r существует и доступен для записи, то
прежнее его содержимое перезаписывается. А если этот файл или его каталог не
доступен для зап иси, то оболочка выдаст сообщение об ошибке.
Прежде чем начать выполнение требуемой программы, оболоч ка переадресо­
вывает стандартный вывод из программы в указанный файл. Практически в каж­
дом случае программе вообще неизвестно, что вывод результатов ее выполнения
переадресовывается. Она просто направляет результаты своего выполнен ия в
стандартный вывод, т.е. как обычно, на терминал, даже не подозревая, что обо­
лочка переадресовывает эти данные в файл.
Рассмотрим еще оди н пример применения двух практически оди наковых команд:
$ wc - 1 users
5 users
$ wc - 1 < users
5
$

В первом случае оболоч ка определяет в ходе си нтакси ческого анализа команд­
ной строки, что выполняемая программа носит имя wc, и передает ей два аргу­
мента: -1 и u s e r s (рис. 2. 1 2).

Р ис. 2 . 1 2 . П роцесс в ы пол нения кома нды wc - 1 users

Когда команда wc начинает свое выполнение, она обнаруживает, что ей пере­
даны два аргумента. Первы й аргумент, - 1 , предп исывает ей подсчитать количе­
ство строк, а второй аргумент обозначает имя файла, в котором подсчитываются
строки. Таким образом, команда wc открывает файл u s e r s , подсчитывает в нем
коли чество строк и вы водит получен ный подсчет вместе с именем файла.
А во втором случае команда wc действует несколько иначе. Просматривая ко­
мандную строку, оболочка обнаруживает символ < для переадресации ввода. По­
этому слово, которое следует после этого символа в командной строке, интерпре­
тируется как имя файла, из которого переадресовывается ввод. Проанализировав
выражение < u s e r s из командной строки , оболочка приступает к выполнению
команды wc, переадресовывая ей стандартный ввод из файла users и передавая
ей только оди н аргумент - 1 (рис. 2. 1 3).

70

Гл а в а 2. Назначение оболочки

Р ис. 2.13. П роцесс в ып ол нения кома нды

wc

-

1 <

users

Когда команда wc начинает свое выполнение, она на этот раз замечает, что ей
передан только один аргумент -1. А поскольку имя файла не указано, то к� манда
wc решает, что строки, количество которых следует подсчитать, должны посту­
пать не из файла, а из стандартного ввода. Таким образом, команда wc - 1 под­
считывает количество строк, даже не подозревая, что эти строки на самом деле
поступают из файла u s e r s . Конечный результат выполнения этой команды ото­
бражается как обыч но, но без и мени файла, поскольку оно не было передано ко­
манде wс.
Очень важно уяснить отличия в выполнении обеих рассмотренных выше ко­
манд. Если эти отличия по каким-то причи нам вам не ясны, внимател ьно прочи­
тайте этот раздел еще раз, прежде чем перейти к следующему разделу.
Подключение кон вейера

Оболочка просматривает командную строку в поисках не только символов для
переадресации ввода-вывода, но и символа канала ( 1 ) . При каждом совпадении с
этим символом оболочка подключает стандартный вывод из предыдущей коман­
ды к стандартному вводу последующей команды, а затем начи нает выполнение
обеих программ.
Так, если ввести следующую строку:
who 1 wc -1

оболочка обнаружит символ канала, разделяющий команды who и wc. При этом
она подключает стандартный вы вод из первой команды к стандартному вводу
второй команды, а затем начинает выполнение обеих команд. В результате своего
выполнения команда who производит список зарегистрированных пользователей
и направляет его в стандартный вывод, даже не подозревая, что это не терми нал,
а другая команда.
А когда выполняется команда wc, то она выясняет, что имя файла не указано,
и поэтому подсчитывает строки из стандартного ввода, даже не подозревая, что
стандартный ввод поступает не с терминала, а следует из результата, выводимого
командой who.
Как станет ясно в дальнейшем, конвейер можно образовать не только из двух
команд, но из сложной цепочки, состоящей из трех, четырех, пяти или больше­
го числа команд. И хотя это не легко уяснить поначалу, тем не менее, едва ли
не самый большой потенциал системы Unix кроется именно в конвейеризации
команд.

Обяза н ности о болочки

71

Контрол ь окружен ия

Оболоч ка предоставляет такие команды, которые дают вам возможность спе­
циально настраи вать свое окружение. В это окружение обыч но входит ваш на­
чальный каталог; символы, которые оболочка отображает, приглашая вас ввести
команду; а также список каталогов, который следует искать всякий раз, когда вы
запрашиваете выпол нение программы. Подробнее о контроле своего окружения
вы узнаете в главе 1О.
И нтерп рети руем ы й яз ы к п рогра м ми рования

У оболоч ки и меется свой встроенный язык программирования. Это интер­
претируемый язык, а следовательно, оболочка анализи рует каждый вводимый
оператор своего языка и выполняет любые команды, которые она посчитает до­
стоверными. Этим язык оболоч ки отл и чается от таких языков программирова­
ния, как С++ и Swift, где операторы, как правило, компилируются в исполняемый
машинный код перед их выпол нен ием.
Отлажи вать и видоизменять программы, разработан ные на и нтерпретируе­
мых языках программ ирования, как правило, проще, чем компилируемые про­
граммы. Но в то же время они выпол н я ются дольше, чем их ком пили руемые
аналоги .
Для программирования на языке оболочки предоставляются средства, кото­
рые можно обнаружить в больши нстве других языков программ ирования. В част­
ности, язык оболоч ки является процедурно-ориентированным и предоставляет
конструкции для организаци и ци клов, операторы выбора, переменные и функ­
ции. В современных оболочках, основанных на стандарте IEEE POSIX, и меются
и многие другие языковые средства, в том числе масси вы, типы дан ных, встроен­
ные арифметические операции.

Р а боч и е и нст рументы
В этой главе подробно описываются некоторые из наиболее употребительных
и нструментов для программирования на языке оболочки, в том числе команды
cut, pa s te, s ed, t r, g rep, un i q и sort. Чем лучше вы освоите эти инструмен ­
ты, тем проще вам будет писать эффективные сценари и оболоч ки.
Р егул я р н ые в ы р а же н ия

Прежде чем рассматри вать инструменты для программирован ия на языке
оболоч ки, необходимо разъясн ить понятие регулярных вь1ражений. Регулярные
выражения применяются в самых разных командах системы Uпix, включая ed,
sed, awk, g rep, и в меньше степен и в редакторе vi. Они предоставляют удобный
и согласованный способ указания шаблонов для сопоставления.
Как ни стран но, но оболочка распознает ограниченную форму регулярных вы­
ражен ий в подстановке имен файлов. Напомним, что знак звездочки ( * ) обозна­
чает совпадение с нулевым или большим количеством символов, знак вопроса
( ? ) - с любым оди ночным символом, а конструкция [ . . . ]
с любыми сим­
волами в квадратн ых скобках. Но подобные формы все же отличаются от более
формальных регулярных выражен ий, рассматриваемых в этой главе. Например,
оболоч ка интерпретирует знак ? как совпадение с любым оди ночным символом,
тогда как в регулярном выражении для этой цели служит знак точ ки ( . ).
Настоя щие регулярные выражен ия оказываются нам ного более сложными,
чем те их формы, которые распознаются оболочкой, и поэтому вопросам состав­
ления по- настоя щему сложных регулярных выражен ий посвящены целые книги.
Впрочем, чтобы оценить исти н н ы й потенциал регулярных выражен ий, совсем не
обязано быть их знатоком !
В этом разделе предполагается, что вы знакомы с такими строковыми редакто­
рами. как ех или ed. Более подробн ые сведения об этих редакторах можно найти,
обрати вш ись за справкой к соответствующей оперативной странице руководства
man по системе U11ix.
-

Совпадение с л юбы м одиноч н ы м си м вол ом : зна к точки ( . )

Знак точ ки ( . ) обозначает в регулярном выражении совпадение с любым оди ­
ночным сим волом, каким бы о н ни был. Таким образом, регулярное выражение
r.

означает совпадение с буквой r и л юбым последующим символом.

Гл а в а 3. Рабочие и нструменты

74

А
.

х

регулярное выражение

.

означает совпаден ие с буквой х, окруженной двумя любыми и необязательно оди ­
наковыми символами .
Немало регулярных выражений можно продемонстрировать, используя ed простой традицион ный строковый редактор, появивш ийся вместе с сисtемой
Linux. Например, следующая команда редактора ed:
/ . . . /

осуществляет прямой поиск в редактируемом файле первой строки, содержащей
любые три символа, окружен ные пробелами. Но прежде чем продемонстрировать
применение данного выражения на конкретном примере, следует заметить, что
сначала редактор ed отображает количество символов в файле ( 2 4 8 ) и что такие
команды, как р (т.е. печатать) , предваряются спецификатором диапазона, наибо­
лее характерным примером которого служит последовательность символов 1 , $ ,
обозначающая пределы о т первой д о последней строки в файле:
$ ed intro
248
Вывести в се строки
1 , $р
The U n i x ope ra t i ng s y s t em wa s p i on e e r ed Ьу Ke n
Thomp s o n and Den n i s Ri t c h i e a t Be l l Labo r a t o r i e s
i n t h e l a t e 1 9 6 0 s . One o f t h e p r ima r y goa l s i n
the de s i gn o f t h e Un i x s y s tem wa s t o c r e a t e a n
e n v i r o nme n t t h a t p romo t e d e f f i c i e n t p ro g r am
deve l opme n t .

Выше выведено содержи мое нашего рабочего файла.
торые регулярные выражения в следующем примере:

А

теперь опробуем неко­

На й ти три симв ола , окруженные про бела ми
/ . . . /
The U n i x ope r a t i n g s y s t em wa s p i on e e r e d Ьу Ke n
Пов торит ь по следний поиск
/
Thomp s o n and Denn i s R i t c h i e at Be l l Labo r a t o r i e s
З аменить в се комбина ц ии симв олов р . о на ХХХ
1 , $ s /p . o/XXX/ g
Посмотреть , что из э того вышл о
1 , $р
The U n i x ope r a t i n g s y s t em wa s XXXn e e r e d Ьу Ke n
T homXXXn and De n n i s R i t c h i e a t Be l l Labo r a t o r i e s
i n t h e l a t e 1 9 6 0 s . One o f t h e p r ima r y goa l s i n
t h e de s i gn o f t h e Un i x s ys tem wa s to c r e a t e a n
e n v i r o nme n t t h a t XXXmo t e d e f f i c i e n t XXX g r am
deve l opme n t .

При первом поиске редактор ed начинает действовать с самого начала фай­
ла, обнаруживая в первой же строке последовательность символов " wa s " , со­
впадающую с указанным шаблоном, а затем выводя ее. При повторении поиска

Регуля рные выраже н и я

75

(по команде / редактора ed) из файла выводится вторая строка, поскольку в ней
с указан ным шаблоном совпадает последовательность символов " and " .
В следующей далее команде подстановки s указывается, что все вхождения
символа р, после которого следует любой одиноч н ы й символ и далее символ о ,
должны быть заменены комби нацией символов ХХХ. Спецификатор 1 , $ , предва­
ряющий эту команду, указывает н а то, что его следует применить ко всем строкам
в файле, а подстановка обозначается в виде структуры s/прежнее/нов ое/g, где
s
подстановка, знаки косой черты ограничивают прежнее и нов ое значения,
а g - применен ие дан ной операции в каждой строке не оди н раз, а столько раз,
сколько потребуется.
-

Совпадение с нача л ом строки : з на к встав ки ( " )

Если знак вставки ( "' ) указывается в качестве первого символа в регулярном
выражении, он обозначает совпадение с началом строки. Таким образом, с регу­
лярным выражен ием
" Geo rge

символы George совпадают лишь в том случае, если они оказываются в начале
строки. В терм и нологии регулярных выражени й это называется укоренением сле­
ва по вполне очевидным причинам.
Рассмотрим следующий пример:
$ ed intro
248
/ the/
> > i n t h e l a t e 1 9 6 0 s . One o f t h e p r ima r y g oa l s i n
> > t he de s i gn o f t h e Un i x s ys tem wa s t o c r e a t e a n
На йтн строку , на чина ющуюся со слова th в
/ " the/
the de s i g n of t h e Un i x s ys tem wa s t o c r e a t e an
Вста вить зна ки >> в на чале каждой строки
1 , $ s / " />>/
1 , $р
> >The U n i x ope ra t i ng s y s t em wa s p i on e e r e d Ьу Ke n
> >Thomp s o n and Denn i s R i t ch i e a t Be l l Labo r a t o r i e s
> > i n t h e l a t e 1 9 6 0 s . One o f t h e p r ima r y g oa l s i n
> > t he de s i gn o f t h e Un i x s y s tem wa s t o c r e a t e a n
> >e п v i ronme n t t h a t p r omo t e d e f f i c i e n t p r o g r am
'
> >dev e l opme п t .

В приведенном выше примере также демонстрируется, что регулярное выра­
жен ие "' может быть использовано для совпадения с началом строки. В данном
случае оно используется для вставки знаков >> в начале каждой строки. А коман­
да, подобная следующей :
1 , $s/"/

/

обычно применяется для вставки пробелов в начале каждой строки (в данном
случае - четырех пробелов).

76

Гл а в а З . Ра б очие и нструменты

С овпадение с кон цом строки : з нак денежной еди н ицы ( $ )

Подобно применен и ю знака вставки ( " ) для совпаден ия с началом строки,
знак денежной еди н и цы ( $ ) служит для совпаден ия с кон цом строки. Таким об­
разом, со следующи м регулярным выражением:
contents$

комбинация символов content s совпадает лишь в том случае, если он и оказыва­
ются в ко нце строки. Как вы думаете, с чем совпадет приведен ное ниже регуляр­
ное выражен ие?
.$

Совпадет ли с ним только знак точ ки в кон це строки? Нет, не совпадет. Напом­
ним, что знак точки обозначает совпадение с любым сим волом, и поэтому с ним
совпадет любой символ в кон це строки, включая и знак точ ки.
Как же добиться совпаден ия с сами м знаком точки? В общем, если требуется
добиться совпадения с л юбыми символами , и меющими специальное назначение
в регулярном выражени и , их следует предварить знаком обратной косой черты
( \ ) , чтобы переопредел ить их специальное назначение. Например, со следующим
регулярным выражен ием:
\.$

совпадает любая строка, оканчи вающаяся точкой , а с регулярным выражен ием
"\ .

любая строка, нач и нающаяся с точки.
Если же в регулярном выражении требуется указать знак обратной косой чер­
ты как таковой, то его следует предварить еще одни м знаком обратной косой чер­
ты ( \ \). Ниже приведены характерные примеры поиска си мво1юв на совпаден ие
в конце строки .
$ ed intro
248
На йт и строку , ока нч11в ающуюся то чк ой
/ \ . $/
deve l opme n t .
1 , $ s / $ / >>/
До б а вить зна ки > > в ко нце каждой с тр ок 11
1 , $р
The U n i x ope ra t i n g s y s tem wa s p i on e e red Ьу Ke n > >
T homp s o n a n d Denn i s R i t c h i e a t Be l l Labora t o r i e s > >
i n t h e l a t e 1 9 6 0 s . One o f t h e p r ima ry goa l s i n > >
t h e de s i gn o f t h e Un i x s y s t em wa s t o c r e a t e a n > >
e nv i r onme n t t h a t p romo t e d e f f i c i e n t p r o g ram > >
deve l opmen t . > >
Удалить дв а симв ола из ка ждой с тро ки
l , $s/ . . $//
1 , $р

Регулярные в ы ражения

77

T h e Un i x ope r a t i n g s y s t em w a s p i o n e e r e d Ь у Ke n
Thomp s on and De nn i s R i t ch i e a t Be l l L a b o r a t o r i e s
i n t he l a t e 1 9 6 0 s . One o f t h e p r i ma ry goa l s i n
the de s i gn o f t h e U n i x s y s t em w a s t o c r e a t e a n
e n v i r o nme n t t ha t p r omo t e d e f f i c i e n t p r og ram
deve l opme n t .

Знаки " и $ обычно применяются в следующем регулярном выражени и :
"$

с которым совпадает любая строка, вообще не содержащая ни одного символа.
Однако это регулярное выражен ие отличается от при веденного ниже регулярно­
го выражения, с которым совпадает любая строка, состоящая из одного символа
пробела.
л

$

Совпадение с набором сим вол ов: конструкция [

]
Допустим, что в процессе редактирования файла требуется найти первое
вхождение символов the. В редакторе ed для этого достаточно ввести следую­
щую команду:
.

.

.

/ the/

В итоге прямой поиск в буфере редактора ed будет осуществляется до тех пор,
пока не обнаружится строка, содержащая указанную последовательность симво­
лов. И первая же найденная строка отобразится в редакторе ed, как показано ниже.
$ ed intro
248
/ the/
На йтн стр о ку , содержа щую сло в о the
in the l a t e 1 9 6 0 s . One o f t he p r ima r y goa l s i n

Обратите внимание н а то, что первая строка файла содержит также слово The
с теми же самыми символами, но оно начинается с прописной буквы Т. Регуляр­
ное выражение для поиск слова the или The может быть создано с помощью на­
бора с,и мволов, где знаки [ и ] служат для огран ичения сопоставляемого набора
символов. Напри мер, со следующим регулярным выражением:
[ tT ] he

совпадут строчная или прописная буква t и следующие за ней си мволы he:
$ ed intro

248

/ [ tT ] he/
На йти сло в о the и.ли Тhе
The Un i x ope r a t i n g s y s tem w a s p i o n e e r e d Ьу Ken
/
Пр одолжи ть п о и ск

78

Гл а в а 3 . Ра бочи е и н струмент ы

i n t h e l a t e 1 9 6 0 s . One o f t he p r ima r y goa l s i n
Пов торить п о и ск еще ра з
/
t h e de s i gn o f t h e U n i x s y s t em was t o c r e a t e a n
1 , $s / [ aeiouAE IOU ] / / g
Удалит ь в се гла сные буквы
1 , $р
Th nx p r t n g s ys tm ws p n r d Ьу Кn
Thmp s n nd Dnn s R t c h t B l l L b r t r s
n t h l t 1 9 6 0 s . n f t h p rmry g l s n
t h d s g n f t h nx s y s tm ws t c r t n
n v r nmn t t h t p rm t d f f c n t p r g rm
dv l pmn t .

Обратите внимание на то, что в приведенном выше примере с шаблоном
[ ae i ouAE I OU ] совпадает единственная гласная буква английского алфавита
(строчная или проп исная). Но это довольно неуклюжее обозначение можно за­
менить диапазоном символов, указанных в квадратных скобках через дефис (- ),
разделяющий начальный и конечный символы в диапазоне. Так, для совпадения
с символом любой цифры в пределах от О до 9 вместо регулярного выражения
( 0 12 3 4 5 6 7 8 9 ]

можно составить более лакони ч ное регулярное выражение:
(0-9]

Для совпадения с прописной буквой англ и йского алфавита подойдет такое ре­
гулярное выражение:
[A-Z ]
А для совпадения с прописной или строчной буквой английского алфавита приведенное н и же регулярное выражение.

[A-Za- z ]

Ниже приведены некоторые примеры применения регулярных выражен ий для
поиска на совпадение с набором символов в редакторе ed.
$ ed intro
248
/ (0-9] /
На й ти стр о ку , содержа шую ци фру
i n t he l a t e 1 9 6 0 s . One o f t h e p r ima r y goa l s i n
/ " [A-Z ] /
На й ти строку , на чина юшуюся с пр о пи с ной бук в ы
The U n i x ope r a t i n g s y s t em w a s p i o n e e r e d Ьу Ken
/
По в тори т ь по и ск
Thomp s o n and Den n i s R i t ch i e a t Be l l Labo r a t o r i e s
Замени ть в се прописные буквы на з на ки *
1 , $s / [A-Z ] / * / g
1 , $р
* he * n i x ope r a t i n g s y s t em was p i o n e e r e d Ьу * en
* homps o n and * e nn i s * i t c h i e a t * e l l * abo r a t o r i e s
i n t h e l a t e 1 9 6 0 s . * ne o f t h e p r ima ry goa l s i n

Регулярн ы е в ы ражения

79

t h e de s i g n o f t he * n i x s y s t em w a s t o c r e a t e a n
e n v i r o nme n t t h a t p r omo t ed e f f i c i e n t p r o g ram
deve l opme n t .

Как поясняется ниже, знак звездоч ки и меет специальное назначение в регу­
лярных выражен иях. Но его не нужно экранировать знаком обратной косой чер­
ты в строке замены, указываемой в команде подстановки, поскольку эта строка
замены составляется на другом языке выражени й ( как упоминалось ранее, с регу­
лярными выражениями не все так просто).
В редакторе ed такие последовательности регулярных выражени й , как * , ,
[
] , $ и " , и меют смысл только в строке поиска, но не и меют н икакого спе­
циального назначения в строке замены. Так, если знак вставки ( " ) оказывается
первым символом после левой (открывающей) квадратной скобки , то его смысл
меняется на обратный. (А в оболоч ке для этой же цели служит воскли цательный
знак ! , указываемы й вместе с наборами символов.) Например, со следующим ре­
гулярным выражением:
.

.

.

.

[ "A- Z ]

совпадет любой символ, кроме проп исной буквы. Аналогич но с регулярным вы­
ражением:
[ "A-Za- z ]

совпадет любой небуквен ный символ. В качестве примера ниже демонстрируется
удаление всех небуквенных символов из строк в рассматриваемом здесь тестовом
файле.
$ ed intro
248
1 , $s/ [ "a- zA-Z ] //g
Уда лить в се не бук в е нные симв олы
1 , $р
The U n i xope ra t i n g s y s t emwa s p i on e e r e dЬ yKen
Thomp s o n a ndDenn i s R i t c h i e a t B e l l L a bo r a t o r i e s
I n t he l a t e sOne o f t he p r i ma r ygoa l s i n
Thede s i g no f t h e U n i x s y s t emwa s t o c r e a t e a n
E n v i ronmen t t h a t p r omo t ede f f i c i e n t p r o g ram
de ve l opme n t

Совпаден ие с н ул евы м ил и бол ьш и м ко л ичеством
си мвол ов: знак звездоч ки ( * )

Знак звездоч ки ( * ) применяется в оболочке при подстановке и мен файлов для
совпадения с нулевым или большим количеством символов. И при составлени и
регулярных выражений знак звездоч ки служит для совпадения с нулевы м и л и
большим числом вхождений предшествующего е м у элемента регулярного выра­
жен ия, который сам может быть регулярным выражением.

Гn а в а З . Ра б очие и н струменты

80

Например, со следующим регулярным выражением:
Х*

совпадает нуль, одна, две, три заглавн ые букв Х и больше, тогда как с регулярным
выражением
ХХ*

совпадает одна заглавная буква Х или больше, поскольку в данном выражении
указан оди н символ Х, после которого следует нуль или больше символов Х. Того
же самого результата можно добиться и с помощью знака "плюс" ( + ) , которы й
обозначает совпадение с одним предшествующим выражением или больше. Так,
выражения ХХ * и Х+ выполняют одну и ту же функцию.
Аналогичный шаблон нередко применяется для сопоставления с одним пу­
стым пробелом или больше в строке, как демонстрируется в следующем примере:
$

ed lotsaspaces

85
1 , $р
Th i s
file
of

a n e xamp l e
is
con t a i n s
that
Ы a n k space s

1 , $s / * / /g
1 , $р
Th i s i s an e xamp l e o f а
f i le that conta i n s а lot
of Ьlank spaces

of
а

а

lot
З амени ть не с колько пу с тых
про б елов одино чными проб ел а ми

В данном при мере команда
l , $s /

* / /g

предписывает редактору ed заменить все вхождения пробела с последующим ну­
левым или больш и м коли чеством пробелов на еди нственный пробел - иными
словами, сократить весь пробельный материал в тексте до оди ноч ных пробелов.
Есл и совпадение произойдет с одиночным пробелом, то никакой замены не по­
следует. Но если произойдет совпадение, например, с тремя пробелами, то все
они будут заменены оди ночным пробелом.
Следующее регулярное выражен ие:
*

нередко служит для обозначения нулевого или большего коли чества вхождений
любых символов. Следует, однако, и меть в виду, что данное регулярное выраже­
ние сопоставляется с самой длинной символьной строкой, совпадающей с указан ­
ным в нем шаблоном. Следовательно, само это вы ражен ие всегда сопоставляется
со всей строкой текста.

Регуля рные в ы ражения

81

Еще одним примером сочетания знаков . и * служит следующее регулярное
выражение:
е . *е

с которым совпадают все сим во11ы от первой до последней буквы е в строке.
Однако данное выражение совсем не обязательно совпадает только со стро­
ками , начинающи мися и оканчивающимися на букву е. Ведь оно не укоренено н и
слева, н и справа, т.е. н е содержит знак " или $ в своем шаблоне. Ниже приведен
характерный тому при мер.
$ ed intro
248
l , $ s/e . * e/+++/
1 , $р
Th+++n
Thomp s o n and D + + + S
i n t h + + + p r ima ry goa l s i n
t h + + + an
+ + + n t p r og ram
d+++nt .

Рассмотрим еще одно любопытное регулярное выражение. Как вы думаете, с
чем оно совпадет?
[A-Za- z ] [A-Za- z ] *

Это регулярное выражение совпадет с любым буквенным символом, после ко­
торого следует нулевое или большее количество буквен ных символов. Оно очень
похоже на регулярное выражение, совпадающее со словами. Так, в при веденном
ниже примере оно применяется для замены всех слов буквой Х с сохранением
всех пробелов и знаков преп инания.
$ ed intro
248
l , $ s / [A- Za- z ] [A-Za- z ] * /X/9
1 , $р
х х х х х х х х
х х х х х х х
Х Х Х 1 9 6 0Х .
Х Х Х Х Х Х
х х х х х х х х х х
х х х х х
х.

С регулярным выражением в данном примере не совпала только числовая по­
следовательность символов 1 9 60. Чтобы учесть и эту последовательность цифр
как слово, регулярное выражение можно изменить следующим образом:

82

Гл а в а 3 .

Ра б очие и нструменты

$ ed intro
24 8

1 , $ s/ [A-Za- z 0 - 9 ] [A-Za- z0 - 9 ) * /X/g
1 , $р

х х х х х х х х
х х х х х х х
х х х х.
х х х х х х
х х х х х х х х х х
х х х х х
х.

Данное регулярное выражен ие можно было бы расширить таким образом,
чтобы учесть слова, которые п и ш утся через дефис или сокращенно (напри мер,
слово don ' t), но оставим это вам в качестве упражнен ия. Следует лишь заме­
тить, что если требуется сопоставлен ие с символом дефиса в наборе символов,
заключаемых в квадратные скобки, то этот символ следует указать первым по­
сле левой (открывающей ) квадратной скобки, но после знака обращен ия ", есл и
он присутствует в шаблоне, или же перед правой (закрывающей ) скобкой , чтобы
правильно его интерпретировать. Так, с л юбым из при веденных ниже регулярных
выражен и й совпадает оди ночный знак дефиса или цифры.
( -0 - 9 )
( 0-9- )

Аналогичным образом, есл и требуется сопоставление со знаком правой ква­
дратной скобки, его следует указать первым после левой (открывающей) квадрат­
ной скобки, но после знака обращения " , есл и он присутствует в шаблоне. Так, с
регулярным выражением
[ ] a-z ]

совпадает правая квадратная скобка или строчная буква английского алфавита.
Совпадение с точ н ы м кол ичеством
п одшаблонов: конструкци я \ { . . . \ }

В предыдущих примерах было показано, как пол ьзоваться знаком звездочки
для обозначения одного или нескольких совпадающих вхожден ий предшествую­
щего регулярного выражения. Например, следующее регулярное выражение:
ХХ*

означает совпадение с буквой Х, после которой следует нулевое или большее ко­
л ичество вхожден и й той же самой буквы Х. Аналогично регулярное выражение
ХХХ *

означает совпадение по меньшей мере с двумя подряд буквам и Х.

Регул я рные в ы раже н ия

83

Но, откровенно говоря, это не очень удобно, и поэтому и меется более общий
способ указать точ ное количество совпадающих символов, используя следующую
конструкцию:
\ { m.in , шах\ }

где шin обозначает минимал ьное коли чество совпадающих вхождений пред­
шествующего регулярного выражения, а .шах максимальное. Следует, однако,
иметь в виду, что фи гурные скобки необходимо экранировать знаком обратной
косой черты.
Так, со следующим регулярным выражением:
-

Х\ { 1 , 1 0 \ }

совпадает от одной до десяти следующих подряд букв Х. Всякий раз, когда появ­
ляется выбор, совпадение происходит с наибольшим шаблоном. Так, если вход­
ной текст содержит восемь букв Х подряд, то именно с таким количеством букв и
произойдет совпадение в приведенном выше регулярном выражении.
В качестве еще одного примера рассмотрим следующее регулярное выражение:
[A-Za - z ] \ { 4 , 7 \ }

с которым совпадает последовательность букв дли ной от четырех до сем и симво­
лов.
А теперь попробуем осуществить подстановку в следующем примере, исполь­
зуя рассмотрен ную выше конструкцию:
$ ed intro

24 8

l , $ s/ [A-Za-z ] \ { 4 , 7 \ } /X/g
1 , $р
The Х Xng Х wa s Xed Ьу Ken
Xn and Х Х at Х ХХ
in t he Х 1 9 6 0 s .
One o f t h e Х Х i n
t he Х o f t h e Х Х w a s t o Х a n
Х Х Х X d Xn t Х
хх .

Данный пример является особым случаем глобального поиска и замены в ре­
дакторе ed, а следовательно, и в редакторе v i , по шаблону s /прежнее/нов ое/.
В данном случае этот шаблон предваряется указанным диапазоном 1 , $ и завер­
шается флагом g, чтобы многочисленные замен ы происходили в каждой строке
там, где это уместно.
Особого внимания заслужи вает ряд специальных случаев применения рассма­
триваемой здесь конструкции. Так, если в фигурных скобках указано только одно
ч исло, как в следующем выражени и :

84

Гn а в n з . Рабочие и нструменты

\ { 1 0\ }

то оно обозначает, что предшествующее регулярное выражение должно совпа­
дать именно столько раз. Так, со следующи м регулярн ым выражением:
[ a- zA-Z ] \ { 7 \ }

точ но совпадают семь буквенных символов, а с регулярным выражен ием
. \ { 10\ }

десять сим волов, какими бы они н и был и, как показано в приведен ном ниже при­
мере.
$ ed intro
248
1 , $s/ " . \ { 10 \ } //
Удалить первые 10 симв ол о в из кажд ой строки
1 , $р
p e r a t i n g s y s t em w a s p i on e e r e d Ьу Ken
nd De nn i s R i t c h i e at Be l l Labo ra t o r i e s
е 1 9 6 0 s . One o f t he p r ima r y g o a l s i n
o f t h e Un i x s y s t em was t o c r e a t e a n
t t h a t p r omo t ed e f f i c i e n t p r o g ram
t.
1 , $s/ . \ { 5\ } $/ /
Удалить по след ни е 5 симв олов из кажд ой строки
1 , $р
p e r a t i n g s y s t em w a s p i o n e e r e d Ь
nd De nn i s R i t c h i e a t Be l l Labo r a t
е 1 960s .
One o f t h e p r ima r y g o a
o f t he Un i x s y s t em wa s t o c r ea
t that p r omo t e d e f f i c i e n t p r
t.

Обратите вн и мание на то, что в последней строке тестового файла не осталось
пяти символов при выполнении последней команды подстановки. Поэтому со­
впадения с этой строкой не произошло, а следовательно, она была оставлена без
изменен ия, поскольку в данной команде точно указано удал ить пять символов.
Если в фигурн ых скобках указано единствен ное число, после которого следует
запятая, то совпасть должно, по крайней мере, стол ько же вхождений предше­
ствующего регулярного выражения, хотя верхний предел не установлен. Так, со
следующи м регулярным выражением:
+\ { 5 , \ }

совпадет по меньшей мере пять следующих подряд знаков "плюс ': Если же во
входных дан н ых встречается больше пяти следующих подряд знаков "плюс", то
совпадение происходит с наибольшим их количеством. Ниже приведен характер­
ный пример применения подобной конструкции.

Регулярн ые вы ражения

85

$ ed intro
248

1 , $s/ [a- zA- Z ] \ { б , \ } /X/q

Заме нить н а бу кв у Х сл ов а ,
СОСТОЯЩJ tе х о тя бы нз 6 бук в

1 , $р
The U n i x Х Х wa s Х Ьу Ken
Х and Х Х at Be l l Х
in t h e l a t e 1 9 6 0 s . On e o f t he Х g o a l s i n
t h e Х o f t h e Un i x Х w a s t o Х a n
Х tha t Х Х Х
х.

Сохранение сов п ав ших си м вол ов : конструкция \ ( . . . \ )

Заключив символы в круглые скобки, экран ированные знаками обратной ко­
сой черты, можно ссылаться на них при сопоставлен и и с регулярным выражен и­
ем. Эти зафи ксирован ные символы сохраняются в предопределенных перемен ­
ных, назы ваемых регистрами си нтаксического анализатора регулярных выраже­
ний и нумеруемых от 1 до 9.
Такая конструкция кажется не совсем понятной и требует подробн ых разъ­
яснений. В качестве первого при мера рассмотрим следующее регулярное выра­
жение:
"\ ( . \ )

С этим вы ражением совпадает первый символ в строке, каким б ы о н ни был.
При этом совпавш ий сим вол сохраняется в регистре l.
Для извлечен ия сим волов, хранящихся к отдельном регистре, служит кон ­
струкция \n, где п
цифра от 1 до 9. Так, со следующим регулярным выраже­
нием:
-

"\ ( . \ ) \ 1

первоначально совпадает первый сим вол в строке, который сохраняется в реги ­
стре l, а затем сопоставление происходит с тем, что хранится в регистре l, как
указано в конструкции \ 1. Конеч ным результатом дан ного регулярного выраже­
ния яцляется совпадение первых двух символов в строке, при условии, что они
одинаковы. Хитро придумано, не так л и ?
А с о следующим регулярным выражением:
"\ ( . \ ) . *\1$

совпадают все строки, где первый символ ( ""' . ) такой же, к а к и последний ( \ 1 $ ) .
А шаблон . * означает совпадение с о всеми промежуточными символами.
Проанализируем данное регулярное выражение по частям. Напомним, что
знак ""' обозначает совпадение в начале строки, а знак $
в конце. В упрощен­
ном виде шаблон
* обозначает первый сим вол в строке ( первый знак . ), после
-

.

.

86

l il a в a 3 .

Ра бочие и нструменты

которого следует остальная часть строки ( . * ) . Чтобы сохран ить первый символ
в регистре l , вводится обозначение \ ( \ ) , а для ссылки на него - обозначение
\ 1 . Теперь вам должно быть ясно, каки м образом действует дан ное регулярное
выражение.
Если конструкция \ ( . . . \ ) следует несколько раз подряд, то совпавшие сим­
волы по очереди сохраняются в соответствующих регистрах. Так, если для сопо­
ставления с каким-нибудь текстом применяется следующее регулярное выра?Кение:
"\ ( . . . \) \ ( . . . \)

то первые три символа в строке сохраняются в регистре l , а следующие три сим­
вола - в регистре 2. Если присоединить к этому выражен ию шаблон \ 2 \ 1 , то в
итоге получится совпадение с 1 2-символьной строкой, где символы 1 -3 совпада­
ют с символами 1 0- 1 2, а символы 4-6 - с символами 7-9.
Когда регистр применяется в команде подстановки редактора ed, к нему мож­
но также обращаться из строки замены, что может быть очень эффективно, как
показано в следующем при мере:
$ ed phoneЬook
114
1 , $р
A l i c e Chebba
973-555-2 0 1 5
B a r b a r a Sw i n g l e 2 0 1 - 5 5 5 - 9 2 5 7
Li z S t a c h i w
2 12-555-2298
S u s a n Go l dbe rg
201-555-7776
973-555- 1 2 95
Tony I a n n i n o
\ ( . * \ ) /\2 \1/
1 , $s / \ ( . * \ )
1 , $р
9 7 3 - 5 5 5 - 2 0 1 5 A l i ce C h ebba
2 0 1 - 5 5 5 - 9 2 5 7 Ba rba ra Sw i n g l e
2 1 2 - 5 5 5 - 2 2 9 8 Li z S ta c h i w
2 0 1 - 5 5 5 - 7 7 7 6 S u s a n Go l dbe rg
9 7 3 - 5 5 5 - 1 2 9 5 T o n y I a n n i no

Поменя ть о ба п оля ме стами

Имена и номера телефонов отделяются друг от друга в файле phoneboo k од­
ним знаком табуляци и . Поэтому регулярное выражение
\ ( . *\)

\ ( . *\)

означает совпадение со всеми символами вплоть до первого знака табуляции,
т.е. последовательность символов . * между знаками \ ( и \) , которая присваива­
ется регистру l , а все совпавшие символ ы после знака табуляции присваиваются
регистру 2. В следующей строке замены:
\2 \ 1

указывается содержимое регистра 2, после которого следует пробел и содержи­
мое регистра 1 .

Регулярные в ы ражения

87

Когда редактор ed применяет команду подстановки к первой строке файла:
A l i ce Chebba

973-555-2 0 1 5

все, что совпадает вплоть до знака табуляции (Al i ce Chebba), сохраняется в ре­
гистре 1 , а все, что совпадает после знака табуляции ( 9 7 3 - 5 5 5 - 2 0 1 5 ) ,
в ре­
гистре 2. Сам же знак табуляции при этом теряется, поскольку он не заключен
в круглые скобки в рассматриваемом здесь регулярном выражении. После этого
редактор ed заменяет совпавшие си мволы (т.е. всю строку) содержимым реги­
стра 2 ( 9 7 3 - 5 5 5 - 2 0 1 5 ) , пробелом и содержимым регистра 1 (Al i ce Chebba).
И в конеч ном итоге получается следующая строка:
-

9 7 3 - 5 5 5 - 2 0 1 5 A l i ce Chebba

Как видите, регулярные выражения явля ются весьма эффективными и нстру­
ментальными средствами, допускающи ми сопоставление и манипулирование до­
вольно сложными шаблонами. Хотя порой они выглядят довольно запутанно!
В табл. 3. 1 сведен ы специальные символы, распознаваемые в регулярных вы­
ражениях, чтобы помочь вам луч ше понимать чужие регулярные выражения и
науч иться составлять собственные.
Табл ица

3.1. Специальные с и м волы, распознаваемые

в регулярных выражен иях
Обозна ч ение

Н азна чен ие
Любой

$

символ

П ример

С ч ем сов падает

а . .

Символ а и два любых по­
следующих символа
Слово wood, если оно появ­
ляется в начале строки
Буква х, если это последний
символ в строке
Строка, содержащая только
символы INSERT
Строка, не содержащая ни­
каких символов
Нулевое или большее коли­
чество следующих подряд
букв х

Начало строки

" wood

Конец строки

х$
" INSERT$

"$
*

Нулевое и большое количество вхождений
предшествующего ре­
гулярного выражения

х*

хх *
*

w . *s

Одна или бол ьше следую­
щих подряд букв х
Нулевое или большее коли­
чество любых символов
Буква w, нулевое или боль­
шее количество любьtх сим­
волов и буква s

88

Гп а в а 3. Рабочие инструменты

Окончание табл. 3. 1
Обозна ч ен ие

Н а зн аче н и е

П р и мер

С че м совпада ет

+

Одно или больше
вхождений предше­
ствующего регулярного выражения

х+

Одна или больше следую­
щих подряд букв х

хх+

Две или больше слеД ующих
подряд буквы х
Один символ или больше
Буква w, один ил и больше
сим волов и буква s
Строчная или прописная
буква t
Любая строчная буква ан ­
глийского алфавита
Любая строчная или пропис­
ная буква английского алфа­
вита
Любой нечисловой символ

.+
w . +s
[ cянsomi]

Любые указанные

[ tT ]

CЯНlilomJ

[a-z ]
[ a - zA- Z ]

[ " сянsо.rш]

Что угодно, только
не указанные cян­

[ "0-9]

so.m.z

[ " a - zA- Z ]
\ { m.in , .шах\ }

Количество вхожде­
ний п редшествующе­
го регулярного выра­
жения в переделах от
min дo .max

х\ { 1 , 5\ }

[ 0 - 9 ] \ { 3 , 9\ }
[ 0- 9 ] \ { 3\ }
[ 0- 9] \ { 3 , \ }
\ ( . . . \)

Сохранение в реги­
страх 1-9 совпавших
символов, указанных
в круглых скобках

"\ ( . \)

"\ ( . \) \1

"\ ( . \) \ ( . \)

Любой небуквенный символ
От l до 5 букв х

От 3 до 9 следующих подряд
цифр
Точно 3 цифры
Минимум 3 цифры
Первый символ в строке, со­
храняемый в регистре l

Первый и второй символы в
строке, сохраняемые в реги ­
стре \ , если он и одинаковы
Первый и второй С И М ВОЛЫ в
строке, сохраняемые в реги­
страх 1 и 2 соответственно

Ком а нда cut

89

К о м а нд а cu t

В этом разделе рассматривается очень полезная команда cut, которая очень
удобна для извлечения (буквально " вырезания") различ ных полей данн ых из
файла или результата, выводимого другой командой. Общая форма команды cut
выглядит следующим образом:
cut - с символы фа йл

где симв олы коли чество символов ( по местоположен и ю), которые требуется
извлечь из каждой строки, которую содержит указан ный фа йл. Этот набор сим­
волов может состоять из одного числа, например, - с 5 для извлечения пятого
символа из каждой строки входных дан н ых; разделенного запятыми списка ч и ­
сел, например, - c l , 1 3 , 5 0 для извлечения символов 1 , 1 3 и 5 0 ; или ж е диапазона
чисел, указываемых через дефис, например, - с 2 0 - 5 0 для извлечения символов в
пределах от 20 до 50 включ ительно. Чтобы извлечь символ ы в конце строки, вто­
рое число в указываемом диапазоне можно опустить. Так, по команде
-

cut - с 5 - da t a

извлекаются пять символов, отсч итываемых от кон ца каждой строки в файле
da ta, а полученный результат направляется в стандартн ый вывод.
Есл и же фа йл не указан, команда cut читает свои исходные данные из стан­
дартного ввода. Это означает, что ее можно использовать в качестве фильтра в
конвейере.
Рассмотри м еще раз результат, выводимый командой who:
$ who
root
s t e ve
george
dawn

con s o l e
t ty02
t t y0 8
ttylO

Feb
Feb
Feb
Feb

24
24
24
24

08 :
12 :
09 :
15:

54
55
15
55

$

Как видите, в системе зарегистрированы четыре пользователя. Допустим, тре­
буется узнать только имена зарегистрирован ных пользователей, не обращая вни­
мания на их терминалы или время входа в систему. Чтобы извлечь только и ме­
на зарегистрированных пользователей из результата выполнения команды who,
можно воспользоваться командой cu t следующим образом:
$ who 1 cut -cl - 8
root
s t e ve
george
dawn
s

Извле чь первые 8 символов

90

Гл а в а 3 . Рабочие и нструменты

Параметр -сl - 8 команды cut указывает на то, что из каждой строки входных
дан ных следует извлеч ь от 1 до 8 символов и направить их в стандартный вывод.
В следующем примере демонстрируется порядок присоединения команды
s o r t в конце конвейера из предыдущего примера с целью получ ить отсортиро­
ван ный список зарегистрированных пользователей:
$ who 1 cut -cl - 8 1
dawn
george
root
s t e ve

sort

$

Следует заметить, что это первый трехкомандный конвейер в рассмотренных
до сих пор примерах. Ясно понимая принцип подкл ючен ия выхода предыдущей
команды на вход последующей, нетрудно образовать логи ческий конвейер из
трех, четырех и большего ч исла команд.
Если же требуется просмотреть применяемые в настоящий момент физиче­
ские, псевдотерминалы или виртуальные терми налы, из результата, выводи мого
командой who, можно извлечь только поле t ty, как показано ниже.
$ who 1 cut -cl0 - 1 6
c on s o l e
t ty02
t ty08
ttylO
$

А откуда известно, что команда who отображает сведения о терминалах на по­
зи циях символов 1 0- 1 6? Выяснить это совсем не трудно! Достаточно выполнить
команду who на своем терминале и подсчитать позиции соответствующих сим­
волов.
Используя команду cut, можно извлечь столько различных символов, сколь­
ко потребуется. В следующем примере команда cut используется для отображе­
н и я тол ько и мен всех зарегистрирован н ых пол ьзователей и времен и их входа в
систему:

$ who 1 c u t -cl - 8 , 1 8 r o o t Feb 2 4 0 8 : 5 4
s t e ve Feb 2 4 1 2 : 5 5
g e o r g e Feb 2 4 0 9 : 1 5
dawn Feb 2 4 1 5 : 5 5

$

Параметр -cl - 8 , 1 8 - определяет точ ное количество символов от l до 8
(т.е. имя пользователя), а также си мволы 1 8 и до кон ца строки (т.е. время входа в
систему).

Ком а нда cut

Параметры

-

91

d и -f

Команда cut с параметром -с удобна для извлечения дан ных из файла или
результатов выполнения другой команды, но при условии, что формат файла или
вывода из другой команды фиксирован.
В частности, командой cu t можно пользоваться вместе с командой who по­
том у, что заранее известно, что и мена зарегистрированных пользователей ото­
бражаютсяна пози циях 1 -8, терминалы - на позициях 1 0- 1 6, а время входа в
систему - на позициях 1 8-29. Но, к сожалению, не все данные настолько хорошо
организован ы!
Рассмотрим в качестве примера содержи мое следующего файла / e t c /pas swd:
$ cat /etc/pas swd
root : * : O : O : The Supe r U s e r : / : / u s r / b i n / k s h
c r on : * : l : l : C ron Da emon f o r pe r i od i c t a s k s : / :
b i n : * : J : З : T he own e r o f s y s t e m f i l e s : / :
uucp : * : 5 : 5 : : / u s r / s poo l / u u cp : / u s r / l i Ь / u ucp / u u c i c o
a s g : * : б : б : T he Own e r o f A s s i g n a Ы e De v i c e s : / :
s t e ve : * . : 2 0 3 : 1 0 0 : : / u s e r s / s t e ve : / u s r / b i n / k s h
o t h e r : * : 4 : 4 : Needed Ь у s e c u r e p r o g r am : / :

$

Файл / e t c /pas swd является главным местом, где содержатся имена всех
пользователей в системе. Он содержит и другие сведения, в том ч исле идентифи­
каторы пользователей, пути к их начальным каталогам, а также имена программ,
запускаемых на выполнение при входе конкретных пользователей в систему.
Очевидно, что дан н ые в этом файле организованы не так хорошо, как в резуль­
тате выполнения команды who. Следовательно, извлечь список всех пользовате­
лей системы из этого файла не удастся по команде cut с параметром -с.
Но если проанализировать содержимое этого файла более внимательно, то
можно заметить, что поля в нем разделя ются двоеточ ием. И хотя эти поля от­
личаются по дл ине от одной строки к другой, тем не менее, можно определить
положение знаков двоеточия, чтобы извлеч ь одно и то же поле из каждой строки.
Если данн ые разделяются кон кретным символом, то для их извлечен ия по
команде cut можно воспользоваться параметрами -d и - f. В частности, пара­
метр :... d определяет разделитель полей, а параметр -f - одно или несколько из­
влекаемых полей. И в таком случае для вызова команды cut служит следующая
форма:
cut -ddch a r - f поля файл

где dch a r - символ, разделяющий поля дан ных, а поля - извлекаемые поля,
которые содержит указанный файл. Номера полей нач и наются с 1 , и для обо­
значения номеров полей может быть использован такой же тип формата, как и
прежде для позиций символов ( например, - f l , 2 , 8 , - f l - 3 , f 4 )
-

-

.

92

Гл ii в а з . Ра бочие инст рументы

Чтобы извлеч ь имена всех пользователей из файла / e t c /pas swd, достаточно
ввести следующую команду:
$ cut -d : -fl /etc/pas swd
root
c ro n
Ьin
uucp
asg
s te ve
other
$

Извлечь поле 1

Если начальный каталог каждого пользователя находится в поле 6, то имена
пользователей системы можно вывести вместе с их н ачальными каталогами сле­
дующим образом:
$ cut -d : -fl , б /etc/pas swd
root : /
c r on : /
Ьin : /
uucp : / u s r / spoo l / u u c p
a sg : /
s t e ve : / u s e r s / s t e ve
other : /
$

Извл е чь поля 1 - 6

Если команда cut предназначается для извлечения полей и з файла, а параметр
-d не указан, то по умолчанию в качестве разделителя полей в ней использует­

ся символ табуляции. В следующем примере демонстрируется типичное препят­
ствие, скрывающееся на пути применения команды cut. Допустим, имеется файл
phoneboo k со следующим содержимым:
$ cat phoneЬook
A l i ce Chebba
Barbara Swingl e
Je f f Go l dbe r g
L i z Stachiw
S u s a n Gol dbe rg
T o n y I a n n i no
$

9 7 3 - 5 5 5 -2 0 1 5
201-555-9257
2 0 1 -555-3378
2 1 2 -555-2 2 98
2 0 1 -555-7 776
973-555- 1 2 95

Если требуется получить только и мена абонентов из телефонного справочни­
ка, то первым побужден ием станет воспользоваться командой cut следующим
образом :
$ cut -cl - 1 5 phoneЬook
97
A l i ce Chebba
Ba rbara Swingle
Je f f Go l db e r g
2

Кома нда cut

Li z S tachiw
S u s a n Go l dbe rg
Tony I a n n i no

$

93

212
97

Но ведь это совсем не то, что нужно! А произошло это потому, что имена або­
нентов отделяются от номеров телефонов символом табуляции, а не рядом про­
белов. Что же касается команды cut, то символы табуляции считаются в ней как
один символ, если она применяется с параметром с Именно поэтому команда
cut извлекает в рассматриваемом здесь примере первые 15 символов из каждой
строки, выводя представлен ный выше результат.
В тех случаях, когда поля дан н ых разделяются символами табуляции, коман­
ду cut следует применять с параметром - f, как показано н и же. Напомним, что
указывать разделитель полей вместе с параметром -d необязательно, поскольку
по умолчанию в команде cut для разделения полей употребляется символ табу­
ляции.
-

.

$ cu t fl phoneЬook
Al i ce Chebba
Ba rba ra S w i n g l e
Je f f G o l dbe rg
L i z S t ac h i w
S u s a n Go l dbe rg
Tony I an n i no
-

$

А как узнать заранее, что поля дан ных разделяются пробельными символами
или символами табуляци и ? С одной сторон ы, это можно сделать методом проб и
ошибок, как было показано ранее. А с другой стороны, можно ввести с терми нала
следующую команду:
sed -n 1 файл

Если поля данных разделяются символами табуляции, то вместо табуляции
отобразится комбинация символов \ t:
$ sed, - n 1 phoneЬook
Al i ce Chebba \ t 9 7 3 - 5 5 5 - 2 0 1 5
Barbara Swing le \ t 2 0 1 - 5 5 5 - 9 2 5 7
Je f f G o l dЬer g \ t 2 0 1 - 5 5 5 - 3 3 7 8
Li z Stachiw\ t 2 1 2 - 5 5 5 - 2 2 9 8
S u s a n Go l dbe r \ t 2 0 1 - 5 5 5 - 7 7 7 6
Tony I a n n i no \ t 9 7 3 - 5 5 5 - 1 2 9 5
$

Как следует из при веденного выше результата, имя каждого абонента отделя­
ется от каждого номера телефона символом табуляции. Более подробно потоко­
вый редактор sed рассматривается далее в этой главе.

94

Гл а ва З. Ра бочие инструменты

К о м а нда pas te

Команда pa s te является полной противоположностью команды cut. Вместо
разделения строк на части она собирает их вместе. Общая форма команды paste
выглядит следующи м образом:
pa s t e фа йлы

где соответствующие строки из указанных файлов "склеиваются" или объединя­
ются вместе, образуя еди ные строки, которые затем направляются в стандартный
вывод. Для обозначения исходных дан н ых из стандартного ввода в задан ной по­
следовательности файлов может быть указан знак дефиса ( - ).
Допустим, в файле name s содержится список и мен абонентов:
$ cat names
Tony
Ema n u e l
Lucy
Ra lph
Fred
$

Допустим также, что в другом файле nшnЬe r s содержатся соответствующие
номера телефонов для каждого абонента из файла name s :
$ cat numЬers
( 307 )
(212)
( 2 12 )
( 2 12 )
( 2 12 )

$

555-5356
555- 3 4 5 6
555-9959
555-7 7 4 1
555-004 0

Чтобы вывести и мена абонентов вместе с номерами их телефонов, можно вос­
пол ьзоваться командой pa s te. Каждая строка из файла name s отображается
вместе со строкой из файла nшnЬe r s , как показано ниже.
$ pas te names numЬers
Tony
( 307 )
555-5356
Ema n u e l
( 2 12 )
555-3 4 5 6
( 2 12 )
555-9959
Lucy
( 2 12 )
555-774 1
Ra l p h
( 2 12 )
555-004 0
Fred

Объеди нить фа йлы вме с те

$

В следующем примере демонстрируется объединение строк из трех файлов по
команде p a s t e :

Кома нда paste

95

$ cat addresses

5 5 - 2 3 V i ne S t re e t , M i am i
3 9 Un i ve r s i t y P l a c e , New Yo r k
1 7 Е . 2 5 t h S t re e t , N e w Y o r k
3 8 Chauncey S t . , B e n s o n h u r s t
1 7 Е . 2 5 t h S t re e t , New Yo r k
$ paste names addresses numЬers
Tony
5 5 - 2 3 V i n e S t re e t , M i am i
Emanue l
3 9 Un i ve r s i t y P l a ce , New Yo r k
Lucy
17 Е . 2 5 t h S t re e t , New Y o r k
Ra lph
3 8 Chauncey S t . , Bensonhu r s t
17 Е . 2 5 t h S t r ee t , New Yo r k
Fred
$

( 307 )
( 2 12 )
( 2 12 )
(212)
( 2 12 )

555-5356
555-3456
555-9959
555-774 1
555-004 0

Параметр -d

Если поля в выводимом результате не требуется разделять символами табуля­
ции, то с помощью параметра d можно указать другой разделитель в следующем
формате:
-

- d ch a rs

где cha rs - один или нескол ько символов, употребляемых для разделения объ­
единяемых строк. Это означает, что первый из переч исленных в списке cha rs
символов будет использоваться для отделения строк из первого файла, которые
объединяются вместе со строками из второго файла; второй символ - для отде­
лен ия строк из второго файла от строк из третьего файла и т.д.
Если задано больше файлов, чем символов, переч исленных в списке cha rs,
команда pa s t e автоматически переходит в начало этого списка, выбирая оттуда
символы для разделения объединяемых вместе строк. В простейшей форме па­
раметр -d указывает еди нственный символ для разделения всех объединяемых
полей в выводимом результате, как показано в следующем примере:
$ paste -d ' + ' names addresses numЬers
Tony+ 5 5 - 2 3 V i n e S t r ee t , M i a mi + ( 3 0 7 ) 5 5 5 - 5 3 5 6
Emanue l + 3 9 U n i ve r s i t y P l a ce , New Y o r k + ( 2 1 2 ) 5 5 5 - 3 4 5 6
Lucy+ 1 7 Е . 2 5 t h S t re e t , New Y o r k + ( 2 1 2 ) 5 5 5 - 9 9 5 9
Ra lph+ 3 8 C h a u n c e y S t . , B e n s o n h u r s t + ( 2 1 2 ) 5 5 5 - 7 7 4 1
Fred+ l 7 Е . 2 5 t h S t ree t , New Y o r k + ( 2 1 2 ) 5 5 5 - 0 0 4 0

Следует, однако, иметь в виду, что символы разделения надежнее заключать в
оди ночные кавычки, как показано выше. Вескость основания для этого поясня ­
ется далее.
Параметр - s

Параметр - s предписывает команде pas t e объедин ить вместе строки и з од­
ного и того же файла, а не из разных файлов. Есл и же указан лишь оди н файл,
в результате будут объеди нены все строки из заданного файла, разделен ные

96

Гп а в а 3. Р а бо ч и е и нструменты

символами табуляции или же символом разделен ия, указанным в параметре d
В следующих примерах наглядно демонстрируется употребление параметров - s
и -d в команде pas te:
-

.

$ paste -s naшes
Ema n u e l
Lucy
Tony
$ ls 1 pas te d ' ' -s -

Объеди нить в се строки нз фа йла naшes
Fred
Ra lph
Объединить с троки и з резуль та та ,
выводимого кома ндой ls , ис поль зуя '
про б ел в ка че стве ра зделителя
addre s s e s i n t ro l o t s a sp a c e s n ame s n llll'\Ь e r s phoneboo k
$
-

В первом примере результат, выводимый командой l s, передается по кана­
лу команде pa s te, объединяющей вместе строки (параметр -s) из стандартного
ввода (знак -), разделяя каждое поле пробелом (параметр -d ' ' ). Как упомина­
лось в главе 1, по команде
echo *

перечисляются также все файлы в текущем каталоге. Возможно, это несколько
более простой вариант, чем l s 1 pas te.
К о м а нд а s ed

Команда sed представляет собой программу, применяемую для редактиро­
вания данных в канале или последовательности команд. Название команды sed
сокращенно обозначает потоковый редактор (stream editor). В отличие от стро­
кового редактора ed, потоковый редактор sed нельзя употреблять в диалоговом
режиме, хотя их команды оди наковы. Общая форма команды sed выглядит сле­
дующим образом:
s e d кома нда фа йла

где кома нда - это команда в стиле редактора ed, применяемая к каждой строке,
указанной в задан ном файле. Есл и же файл не указан, то предполагается стан­
дартный ввод.
Применяя одну или несколько указанных команд к каждой строке исходных
дан ных, редактор sed направляет результаты в стандартный вывод. Рассмотрим
применение этого редактора на конкретном примере. Обрати мся снова к тестово­
му файлу int ro:
$ c a t intro
The Un i x ope r a t i n g s y s t em wa s p i o n e e r e d Ьу Ken
Thomp s o n and De n n i s R i t c h i e at Be l l Labo ra t o r i e s
i n t h e l a t e 1 9 6 0 s . One o f t h e p r ima r y goa l s i n
t h e de s i gn o f t h e Un i x s y s t em w a s t o c r e a t e a n
e n v i r o nme n t t h a t p r omo t e d e f f i c i e n t prog ram

Команда sed

97

deve l opme n t .

$

Допустим, в этом файле требуется заменить все вхождения слова " Un i x " сло­
вом " UN I X " . Это нетрудно сделать в редакторе sed следующим образом :
Заменить слов о l7nix на UNIX
$ sed ' s /Unix/UNIX/ ' intro
The UN I X ope ra t i n g s y s t em wa s p i o n e e r e d Ьу Ken
Thomp s o n and De n n i s Ri t c h i e at Be l l Labo r a t o r i e s
i n t he l a t e 1 9 6 0 s . One o f t l1e p r ima r y g o a l s i n
the de s i gn o f the UN I X s y s t em was t o c r e a t e a n
e n v i ronme n t t h a t p romo t e d e f f i c i e n t p ro g r am
deve l opme n t .
$

Выработайте в себе привычку заключать команду редактора s ed в оди ноч ные
кавычки. В дальнейшем будет разъяснено, когда лучше употребить кавычки, а
когда вместо них - двой ные кавычки.
Команда s / Un i x / UN I X / редактора sed применяется к каждой строке из фай ­
л а intro. Независимо о т того, видоизменяется ли строка или нет, она направля­
ется в стандартный вывод. А поскольку они выводятся в потоке дан ных, то редак­
тор sed не вносит никаких изменений в первоначальный входной файл.
Чтобы сделать изменения постоянными, результат, выводимый из редактора
sed, следует перенаправить во временный файл, а затем заменить первоначаль­
ный файл на вновь созданный следующим образом:
$ sed ' s /Unix/UNIX/ ' intro > tешр
$ шv teJDp intro
$

Вне сти изменения
И сдела ть их п о стоянными

Прежде чем перезаписы вать первоначальный файл, следует убедиться в пра­
вильности внесенных изменен ий. С этой целью полезно просмотреть временный
файл temp по команде с а t и только после этого выполнять команду mv для пере­
записи первоначального файла.
Есл и слово " Un i x " встречается в строке текста неоднократно, то в приведен ­
ном выше примере команда редактора sed заменит только первое вхождение это­
го слова в строке. Есл и же требуется заменить все вхождения слова " Un i x " , то в
конце команды подстановки s следует дополнительно указать глобальный пара­
метр g. В данном случае команда редактора s e d примет следующий вид:
$ sed ' s /Unix/UNIX/g ' intro > teJDp

А теперь допустим, что из резул ьтата выполнения команды who требуется из­
влечь только имена файлов. Как вам должно быть уже известно, это можно, с од­
ной стороны, сделать по команде cut следующим образом:

98

Гл а в а 3. Ра бочие и нструменты

$ who 1 cut

-

cl 8
-

root
ruth
s t e ve
pat

$

А с другой стороны, для удаления всех символов после первого пробела , обо­
значающего конец имени пользователя, и до конца строки можно применить ре­
гулярное выражение в редакторе s ed:
$ who

1 sed ' s / . * $ / / '

root
ruth
s t e ve
pat

$

Приведенная выше команда редактора sed заменяет пробел и следующие за
н и м любые символы до конца строки ( * $ ) ничем ( / / ) , т.е. удаляет их до кон ца
каждой строки исходн ых дан н ых.
.

П а ра метр -n

По умолчанию редактор sed направляет каждую строку в стандартный вывод,
изменяется ли она или нет. Но иногда редактором sed требуется воспользовать­
ся для извлечения лишь конкретных строк из файла. Именно для этой цели слу­
жит параметр -n, который сообщает редактору s ed, что по умолчанию не нужно
выводить любые строки. А в сочетании с командой р можно вывести те строки,
которые совпадают с указанным диапазоном или шаблоном. Например, вывести
только первые две строки из файла:
Выв ес ти толь ко п ервые 2 строки
$ sed -n ' 1 , 2 р ' intro
The U N I X ope r a t i n g s y s tem wa s p i on e e r e d Ьу Ke n
Thomp s o n a n d De nn i s R i t c h i e a t Be l l L a bo r a t o r i e s
$

Если вместо номеров строк команде р предшествует последовательность сим­
волов, заключаемых в знаки косой черты, то редактор sed выведет лишь те строки
из стандартного ввода, которые совпадают с указанным шаблоном. В следующем
примере демонстрируется применение редактора sed для отображения только
тех строк, которые содержат конкретную символьную строку:
$ sed - n ' /UNIX/p ' intro

Выв ести толь ко с троки ,
содержащие слов о UNIX
The UN I X ope r a t i n g s y s t em wa s p i on e e r e d Ьу Ken
the de s i gn of t h e UN I X s y s t em wa s t o c r e a t e an
$

Кома нда sed

99

Уда ление строк

Чтобы удал ить строки, можно воспользоваться командой d редактора s ed.
Указав в этой команде оди н или ряд номеров строк, можно удалить конкретные
строки из исходных дан ных. В следующем примере редактор sed применяется
для удаления двух первых строк текста из тестового файла i n t ro:
$ sed ' 1 , 2d ' intro
Удали ть строки 1 и 2
i n t he l a t e 1 9 6 0 s . One o f t h e p r ima r y g o a l s i n
t he de s i gn o f t h e UN I X s y s t em w a s t o c r ea t e a n
e n v i rorune n t t h a t p romo t e d e f f i c i e n t p r o g r am
deve lopme n t .
$

Напомним, что по умолчанию редактор sed направляет все строки в стандарт­
ный вы вод. Поэтому в данном примере весь оставши йся текст, начиная с третьей
строки и до кон ца файла, будет направлен в стандартный вывод.
Предварив шаблоном команду d редактора s ed, можно удалить из файла все
строки, содержащие текст, совпадающий с этим шаблоном. В следующем примере
редактор sed применяется для удаления из тестового файла всех строк, содержа­
щих слово UN I X:
$

sed ' /UNIX/d ' intro

Удалить в се строки ,
содержащие слов о UNIX
Thomp s o n and Denn i s R i t c h i e a t Be l l L a b o r a t o r i e s
i n t h e l a t e 1 9 6 0 s . One o f t h e p r ima r y g o a l s i n
env i r onme n t t h a t p r omo t e d e f f i c i e n t p r o g r am
deve l opmen t .
$

Истинный потенциал и удобство редактора s ed выходит далеко за рамки при­
веденных выше примеров. Доступн ые в редакторе sed средства позволяют орга­
низовать цикл, вставить текст в буфер и употребить сочетания многих команд в
одном сценари и редактирования. Некоторые допол нительные примеры примене­
ния редактора sed представлены в табл. 3.2.
Табnица

З.2. Примеры применен ия редактора sed

Кома нда реда ктора sed

О п и са н и е

sed

Удалить пятую строку
Удалить все строки, содержащие слово Tes t
или tes t
В ывести из текста только строки 2 0 - 2 5
Заменить слово unix на UN I X везде, где оно
появляется в первых десяти строках из файла

' Sd '

sed ' / [ T t ] est/d '
sed - n ' 2 0 , 2 5р '

text

sed ' 1 , 1 0 s / unix/UNIX/g '

intro

intro

100

Гт� в а 3. Ра б очие и нструмен ты

Окончание табл. 3.2
Ко ма нда ред а кто ра sed

Опи са н и е

sed ' / j an/ s / - 1 / - 5 / '

Замен ить первое значение - 1 на - 5 во всех
строках, содержащих слово j an
Удалить первые три символа из каждой строки
в файле data
Удал ить последние три символа из каждой
строки в файле da ta
В ывести все строки из текста, отобразив непе­
чатаемые знаки как \nn, где nn - восьмерич­
ное значение символа, а символы табуляции как \ t

sed ' s / . . . / / ' data
sed ' s / . . . $ / / ' data
sed -n

'1'

text

К о м а нда tr

Команда t r служит в качестве ф ильтра для преобразования символов и з стан­
дартного ввода. Общая ф орма команды t r выглядит следующим образом:
t r и сходные символы целевые_ симв олы
_

где исходные_ символы и целевые_ символы
оди н символ, несколько или
целый набор соответствующих символов. Л юбой символ, который содержат ис ­
ходные_ символы во входных дан ных, будет преобразован в соответствующий
символ, включаемый в целевые_ символы. А результат этого преобразования
направляется в стандартный вывод.
В своей простейшей ф орме команда tr может быть использована для преоб­
разования одного символа в другой. Напомним еще раз содержимое тестового
ф айла i n t ro, применяемого в при мерах из этой главы:
-

$ cat intro
The U N I X ope r a t i ng s y s t em wa s p i onee red Ь у Ke n
Thomp s on and De nn i s Ri t ch i e a t Be l l L a bo r a t o r i e s
i n t h e l a t e 1 9 6 0 s . One o f t h e p r i ma r y goa l s i n
t h e de s i gn o f t he UN I X s y s t em wa s t o c r e a t e a n
e n v i r onme n t t h a t p r omo t e d e f f i c i e n t p rog ram
deve l opme n t .
$

В следующем примере демонстрируется применение команды t r для преоб­
разования всех букв е в буквы х :
$ tr е х < intro
Thx U N I X opx r a t i n g s y s t xm wa s p i onx xrxd Ьу Kxn
Thomp s o n and Dx nn i s R i t c h i x a t B x l l L a bo r a t o r i x s
i n t h x l a t x 1 9 6 0 s . On x o f t h x p r ima r y goa l s i n
t h x d x s i g n o f t h x UN I X s y s t xm wa s t o c r x a t x a n

Команда tr

101

x n v i ronmxn t t h a t p r omo t xd x f f i c i x n t p ro g r am
dx v x l opmxn t .

$
Входные данные команды tr должны быть переадресованы из ф айла i n t ro,
поскол ьку команда tr всегда предполагает получ ить свои входные данные из
стандартного ввода. Результаты преобразова н и я направляются в стандарт­
ный вывод, не затрагивая первоначальн ый ф айл. Приводя следующий, более
практи ческий при мер, напом н и м о кон вейере, применявшемся для извлечения
имен ф айлов и начальных каталогов всех зарегистри рован н ых в системе поль­
зователей.
cut -d : -fl , б /etc/pas swd
root : /
cron : /
Ьin : /
uucp : / u s r / s poo l / u u cp
asg : /
s t e ve : / u s e r s / s t e v e
other : /
$

$

Знаки двоеточ ия из приведен ного выше результата можно преобразовать
в символы табуляции, чтобы получить более удобочитаемый результат, просто
присоединив команду t r в кон це конвейера следующим образом :
$ cut -d : - fl , б /etc/pas swd 1
/
root
/
cron
/
Ьin
/ u s r / spoo l / u u c p
uucp
/
asg
/ u s e r s / s t eve
s t e ve
/
o t he r
$

tr :

'

В приведен ном выше при мере символ табуляции заключен в одиночные ка­
вычки. И хотя он не отображается, можете нам поверить, что он присутствует.
Этот символ следует закл ючить в одиночные кавычки, чтобы исключ ить его син ­
таксиче ский анализ и удаление как лишнего пробела в оболочке.
Для обращения с непечатаемыми символами можно указать их восьмери чное
представление в команде tr, испол ьзуя следующую ф орму:
\ ппп

где ппп - восьмерич ное представление символа. Такой способ применяется не­
часто, но его все же следует взять на вооружен ие, поскольку он удобен для пред­
ставления непечатаемых символов.

Гл а в а 3. Ра бочие и нст рументы

102

Например, восьмеричное значение символа табуляции равно 1 1 . Следователь­
но, преобразовать знаки двоеточия в символы табуляции с помощью команды t r
можно и таким способом :
tr

:

' \1 1 '

В табл. 3.3 перечислены символы. которые нередко требуется предста,вить в
восьмеричной форме.
Табли ца

З.З. Восьмеричные значения некоторы х символов в коде ASCll

С и м вол

Восьмери ч ное зна ч ение

Звон ковая сигнализация
Возврат на одну позицию
Табуляция
Новая строка
Перевод строки
Перевод страницы
Возврат каретки
Переход

7

10
11
12
12
14
15
33

В приведенном н и же примере команда t r принимает результат, выводимый
командой date, и преобразует все пробелы в знаки новой строки. Таким обра­
зом, каждое поле из конечного результата появляется в отдельной строке.
$

date 1 tr '

'

' \ 12 '

Преобр а з о в а т ь про белы
в зна ки новой с троки

Sun
Ju l
28
19 : 13 : 46
E DT
2 0 02
$

С помощью команды t r можно также преобразовывать диапазоны символов.
Так. в следующем примере демонстрируется преобразование всех строчн ых букв
в прописные буквы текста из файла i n t ro:
$ tr ' [ a- z ] ' ' [A-Z ] ' < intro
ТНЕ UN I X OPERAT I NG S Y STEM WAS P I ONEERED ВУ KEN
THOMPSON AND DENN I S R I TCH I E АТ BELL LABORATOR I E S
I N Т Н Е LAT E 1 9 6 0 S .
ONE OF Т Н Е P R I МARY GOALS I N
Т Н Е DE S I GN O F Т Н Е UN I X S Y STEM WAS Т О CREATE AN
ENV I RONMENT Т НАТ PROMOT E D E F F I C I ENT PROGRAМ
DEVELOPMENT .

$

Ком анда tr

103

В дан ном примере диапазоны символов [ a- z ] и [ A- Z ] заключаются в кавыч­
ки, чтобы оболочка не интерпретировала их как шаблон. Попробуйте выполнить
приведенную выше команду t r без кавычек, и вы сразу же получите совсем не тот
результат, какой ожидали.
Поменяв местами оба аргумента в приведенной выше команде t r, можно пре­
образовать все прописные буквы в строчные:
$ t r ' [A- Z ] ' ' [ a- z ] ' < intro
t h e un i x ope ra t i n g s y s t em wa s p i onee red Ьу k e n
thomp s o n and denn i s r i t c h i e a t be l l l a b o r a t o r i e s
in t h e l a te 1 9 6 0 s .
o n e o f t h e p r ima r y g o a l s i n
t h e de s i g n o f t h e u n i x s y s t em wa s t o c r e a t e a n
e n v i ronme n t t h a t p r omo t e d e f f i c i e n t p r o g ram
deve l opme n t .
$

В качестве более занимательного примера догадайтесь, к какому результату
приведет выполнение следующей команды:
tr ' [ a- zA-Z ] '

' [A-Za- z ] '

Догадал ись? В данном случае проп исные буквы преобразуются в строчн ые, а
строчные - в проп исн ые.
Параметр - s

Указав параметр - s, можно "уплотнить" многие вхождения символов в целе ­
вые_ симв олы. Иными словам и, если заданные исходные_ символы содержат
нескол ько экземпляров отдел ьного символа, то после преобразования они заме­
няются единственным экземпляром дан ного символа.
Так, в следующем при мере команда tr преобразует все знаки двоеточия в сим­
волы табуляции, заменяя нескол ько символов табуляции одн им:
tr - s

' : '

'

\11

'

Таким образом, оди н или несколько знаков двоеточия, следующих подряд во
входных данных, заменяются единственнь1м символом табуляции в выводимом
результ ате. Следует заметить, что вместо восьмеричного значения ' \ 1 1 ' символ
табуляции можно обозначить как ' \ t ' . Можете опробовать такой способ, чтобы
добиться большей удобочитаемости приведенной выше команды t r !
Допустим, имеется ф айл l o t s a spaces с о следующи м содержимым:
$ ca t lotsaspaces
is
a n e x amp l e
of
Th i s
f i le
t h a t con t a i n s
а
lot
Ыank
spaces .
of
$

а

104

! л а в а з. Р а б очие и нструменты

Используя команду t r с параметром -s и указав одиночный пробел в качестве
первого и второго аргументов, можно уплотнить многоч исленные пробелы в при­
веденном выше файле следующим образом:
$ tr -s ' ' ' ' < lotsaspaces
Th i s i s an e xamp l e o f а
f i l e t h a t con t a i n s а l o t
o f Ы a n k s p a ce s .
$
Данная команда t r, по существу, означает следующее: преобразовать последо­
вательности одн их пробелов в другой пробел, заменив многие пробелы в выво­
димом результате еди нственным пробелом.
Параметр -d

С помощью команды tr можно также удалить отдел ьные символы из потока
ввода. Для этой цели служит следующая форма команды t r :
t r -d и сходные симв олы

где л юбой символ, вкл ючаемый в исходные_ симв олы, будет удален из стан ­
дартного ввода. В следующем примере по команде t r с параметром -d из файла
i nt ro удаляются все пробелы:
$ tr - d ' ' < in tro
TheUN I Xope ra t i n g S y s t emwa s p i on e e r e dbyKen
Thomp s o n andDe n n i s R i t c h i e a t Be l l La b o r a t o r i e s
i n t h e l a t e l 9 6 0 s . O n e o f t he p r ima r ygoa l s in
t h e de s i gn o f t h e UN I X S y s t emwa s t o c r e a t e a n
e n v i ronmen t t ha t p romo t ede f f i c i e n tp r o g r am
deve l opmen t .
$
Вы, вероятно, уже сообразили, что той же самой цел и можно добиться и с по­
мощью редактора sed, как показано ниже.
$ sed ' s / / / 9 1 intro
TheUN I Xope ra t i ng s y s t emwa s p i on e e re dЬyKen
Thomp s on andDenn i sR i t ch i e a t Be l l Labo r a t o r i e s
i n t h e l a t e l 9 6 0 s . O n e o f t he p r ima r ygoa l s i n
t h e de s i gno f t he U N I X s y s t emwa s t o c r e a t e a n
e n v i ronme n t t h a tp romo t ede f f i c i e n t p r o g r am
deve l opme n t .
$
Для системы Unix характерно наличие нескольких подходов к решению одной
и той же задач и. В рассмотренном здесь примере любой из приведенных выше
подходов (т.е. применение команды tr или s ed) вполне при годен. Тем не менее
в данном случае лучше выбрать команду t r , поскол ьку она выглядит более лако­
нично и выполняется быстрее.

Кома нда tr

105

В табл. 3.4 приведены характерные при меры применения команды tr для пре­
образования и удаления символов. Но следует и меть в виду, что ком анда tr ма­
нипулирует только одиночными символами. Так, если требуется преобразовать
что-нибудь длин нее одного символа (например, все экземпляры слова uni x в
слово UN I X), для этой цели придется воспользоваться другой командой, напри ­
мер sed.
Табл ица

3.4. Характерные примеры применен и я команды tr

Команда tr

Описание

tr

Преобразовать все прописные буквы Х в строчные бук­
вы х
Преобразовать все открывающие и закрывающие кру­
глые скобки в фигурные
Преобразовать все строчные буквы в прописные
Прео бразовать прописные буквы А-М в N- Z , а буквы
N-Z - в буквы А-М соответственно
Преобразовать в пробелы все знаки табуляции, указан­
ные в первой паре кавычек
Преобразовать многие пробелы в оди н пробел
Удалить все знаки перевода страницы, обозначенные
значением 1 4 , в восьмеричном представлении
Удалить все цифры

' х '

'Х'

tr ' () '

' {} '

tr

' [ a- z ] '

' [ A- Z ] '

tr

' [ A- Z ] '

' [ N - ZA-M ] '

tr

'

tr - s

'

tr -d

' \14 '

tr -d

'

( 0-9)

'

Команда grep

Команда g rep дает возможность находить в одном или нескольких файлах
содержимое, совпадающее с указанным шаблоном. Общая форма команды g rep
выглядит следующим образом :
g rep

ша блон фа йлы

Всякая строка, содержащая указанный ша блон, выводится на терми нал. Если
в команде указано несколько фа йлов, каждая найденная в них строка предва­
ряете!' именем соответствующего файла, чтобы выясн ить файл, в котором было
обнаружено совпадение с указанным шаблоном.
Допусти м, в файле ed . crnd требуется найти все вхождения слова s h e l 1 . Как
следует из результата выполнения приведен ной н и же команды g rep, в файле
ed . crnd обнаружены две строки, содержащие слово s he l l .
$ grep shel l ed . cmd
f i l e s , and i s i n depende n t o f t h e s h e l l .
t o the sh e l l , j u s t t ype i n а q .

$

106

Гл а в а 3 . Ра бочие и нст румен ты

Если шаблон не существует в указанном файле или нескольких файлах, коман­
да grep н ичего и выведет на терминал:
$ grep cracker ed . cшd
$

Как было показано ранее при рассмотрении редактора sed, для вывода из
файла i n t ro всех строк, содержащих слово UN I X, достаточ но было выполн ить
следующую команду:
sed -n ' /UNIX/p ' intro

Но того же самого результата можно добиться и с помощью приведенной ниже
команды g rep.
grep UNIX intro

Вернемся снова к упоми навшемуся ранее файлу phoneboo k, который содер­
жит следующее:
$ oat phoneЬoo k
A l i ce Chebba
Barbara Swing l e
Je f f Go l dbe r g
L i z Stachiw
S u s a n Go l dbe rg
Tony I a nn i no
$

973-555-2015
201-555-9257
201-555-3378
2 1 2-555-22 98
201-555-7776
973-555- 1 2 95

Если в данном файле требуется найти конкретный номер телефона, для этой
цели как нельзя лучше подойдет следующая команда grep:
$ grep Susan phoneЬook
S u s a n G o l db e r g
2 0 1-555-7 7 7 6
$

Команда g rep особенно удобна в том случае, если имеется много файлов и
требуется выяснить, в каком из них содержатся определенные слова или фразы. В
приведенном н и же примере демонстрируется применение команды grep для по­
иска слова s he l l во всех файлах текущего каталога. Как отмечалось выше, если в
команде grep указано несколько файлов, каждая выводимая строка предваряет­
ся и менем файла, в котором содержится эта строка.
$ grep shell *
cmd f i l e s : s he l l t h a t e n a Ь l e s soph i s t i c a t e d
ed . cmd : f i l e s , a n d i s i ndepende n t o f t h e s h e l l .
ed . cmd : t o t h e s he l l , j u s t t ype i n а q .
g rep . cmd : o c c u r rence o f t he word s h e l l :
g re p . cmd : $ g re p s he l l *
g rep . cmd : e ve r y u s e o f t h e word s he l l .
$

Кома нда tr

107

Подобно выражениям, применяемым в редакторе s ed, а также шаблонам, ука­
зываемым в команде t r, шаблоны, задаваемые в команде g rep, рекомендуется
заключать в одиночные кавычки, чтобы "защитить" их от и нтерпретации в обо­
лочке. Рассмотрим в качестве примера, что произойдет, если этого не сделать. До­
пустим, требуется найти все строки, содержащие знак звездочки в файле s t a r s .
Если ввести команду
grep * stars

то достичь желаемого результата не удастся, поскольку, обнаружив знак звездоч ­
ки, оболоч ка автоматически подставит вместо него и мена всех файлов в текущем
каталоге:
$ ls
c i rc l es
po l ka . do t s

s qu a r e s
stars
s t r ipe s
$ grep * stars

$

В данном случае оболочка сначала подставила вместо знака звездочки список
файлов из текущего каталога. А затем запустила на выпол нение команду g rep,
которая приняла в качестве первого аргумента файл c i rc l e s и безуспешно по­
пыталась найти его имя в файлах, указанн ых в качестве оставшихся аргументов
(рис. 3. 1 ).
circles
polka.dots
squares
stars
stripes
stars
Р ис. 3 . 1 . Процесс в ы полнения команды grep * stars

Но если закл юч ить знак звездоч ки в кавычки, он тем самым будет защищен от
си нтаксического анализа и интерпретации в оболочке. Н иже показано, как это
сделать в рассматри ваемом здесь примере.
$ grep ' * ' s tars
The a s t e r i s k ( * ) i s
***********
5 * 4
20
=

s

а

spec i a l c h a r a c t e r t ha t

108

Гл а в а З. Ра б оч ие и нструменты

Кавыч ки сообщают оболоч ке оставить без внимания заключен ные в них сим­
волы. В таком случае оболочка запустит команду g rep на выпол нение, передав
ей два аргумента: знак * (без кавычек, которые попутно удаляются оболоч кой ), а
также имя файла s t a r s (рис. 3.2).

Р ис. 3 . 2 . Процесс вы полнения ком а нды grep ' * ' stars

Помимо знака *, существуют и другие символы, и меющие специальное назна­
чение в оболочке, а следовательно, он и должны быть заключены в кавычки, когда
они употребля ются в шаблоне. Следует, однако, признать, что вопросы обработки
кавычек в оболоч ке непросты, и поэтому им посвя щена отдельная глава 5.
Команда g rep принимает свои исходные дан н ые из стандартного ввода, если
в ней не указано имя файла. Это означает, что команду g rep можно применять в
кон вейере для просмотра строк, совпадающих с указанным шаблоном в результа­
те, выводимом предыдущей командой . Допусти м, требуется выяснить, вошел ли
пользователь j im в систему. С этой целью можно просмотреть по команде grep
результат выполнения команды who, организовав конвейер следующим образом:
$ who 1 grep j im
j im t t y l б Feb 2 0 1 0 : 2 5
$

Однако, есл и файл для поиска не указан, команда g rep автомати чески про­
смотрит стандартный ввод. Естествен но, что есл и пользователь j im не вошел в
систему, то вместо приведенного выш е результата в командной строке будет про­
сто выдано при глашение:
$ who 1 grep j im
$

Ре rулярные в ыражения и кома нда grep

Вернем снова к тестовому файлу i n t ro, отобразив его содержимое:
$ cat intro
The UN I X ope ra t i n g s y s tem wa s p i on e e red Ьу Ken
Thomp s o n and De n n i s R i t c h i e at Be l l Labo r a t o r i e s
in t h e late 1 9 60s .
One o f t he p r ima r y go a l s i n
t h e de s i gn o f t h e UN I X s y s tem wa s t o c r e a t e a n
e n v i ronme n t t h a t p romo ted e f f i c i e n t p r o g ram
deve l opme n t .
$

Кома нда tr

109

Команда g rep дает возможность указать шаблон, используя регулярные вы­
ражения таким же образом, как и в строковом редакторе ed. Это означает, что в
команде g rep можно указать следующий шаблон :
[ tT ] he

чтобы найти строч ную или проп исную букву t или Т, а вслед за ней - буквы he.
Чтобы переч ислить все строки из файла i nt ro, содержащие комби нацию
сим волов the или The, можно ввести следующую команду g rep:
$ qrep ' [ tT ] he ' intro
The UN I X ope r a t i n g s y s t em wa s p i o n e e r e d Ьу Ken
in t he l a t e 1 9 6 0 s .
One of the pr ima r y goa l s i n
the de s i gn o f t h e UN I X s y s t em w a s t o c re a t e a n

$

Более изящный способ состоит в том, чтобы употребить в команде grep пара­
метр i позволяющий составлять шаблоны без учета регистра. Так, по команде
-

,

qrep -i ' the ' intro

поиск строк в файле i n t r o на совпадение с указанным шаблоном осуществля­
ется по команде g rep без учета регистра. Следовател ьно, на терминал будут вы­
ведены строки, содержащие комбинацию символов the или The, а также строки ,
содержащие комби нации символов ТНЕ, ТНе, t H E и т.д.
В табл. 3.5 при ведены другие примеры регулярных выражений, которые могут
быть указаны в команде g rep, а также типы шаблонов, с которыми он и совпадают.
Таблица

3.5. Некоторые п ри меры п ри менен ия команды grep

Кома нда qrep

Оп иса н ие

grep

' [ A- Z ] '

grep

' [ 0 - 9 ] ' da ta

grep

' [ A- Z ] . . . [ 0 - 9 ] '

grep • \ . pic$ '

list

list

filel i s t

Строки из файла l i s t, содержащие прописную
букву английского алфавита
Строки из файла da ta, содержащие цифру
Строки из файла l i s t, содержащие шаблоны из
п яти символов, начинающиеся с прописной буквы и
оканч ивающиеся цифрой
Строки из файла filel i s t, оканч ивающиеся ком­
бинацией символов . pic

Параметр - v

Иногда требуется найти строки, которые не содержат указанный шаблон.
Именно для этой цели и служит параметр -v команды g rep. В частности, он ме­
няет на обратную логи ку совпадения с шаблоном. В следующем примере команда

110

Гл а в а 3 . Ра бочие и нструменты

grep применяется с параметром
рые н е содержат слово UN I X:
$

grep -v ' UNIX ' intro

-v

для поиска в файле i ntro всех строк, кото­
Вывести все строк11 ,

не содержащие слово UNIX
Thomp s o n and Denn i s R i t c h i e a t Be l l Labora t o r i e s
i n t h e l a t e 1 9 60 5 .
One o f t h e p r i ma r y goa l s i n
e n v i ronme n t t h a t p romo t e d e f f i c i e n t prog ram
de ve l opmen t .

$

П а раметр - 1

Порой требуется выявить н е строки , совпадающие с шаблоном, а только и мена
файлов, содержащих этот шаблон. Допустим, в текущем каталоге находится ряд
программ на языке С ( имена и сходных файлов программ на С принято допол нять
расширением . с) и требуется выяснить, в каком из них применяется переменная
Move h i s tory. Решить эту задачу можно следующим образом:
_

$ grep ' Мove_history ' * . с

Иска т ь переменную

Моvе his tory
С

в о всех исх одных файл а; на

exec . c : MOVE Move_h i s t o r y [ 2 0 0 ]
{0};
cpymove ( & Mo ve_h i s t o r y [ NumЬe r h a l f_mo ve s - 1 ) ,
ехес . с :
_
е х е с . с : undo mo ve ( & Move h i s t o r y [ NumЬ e r ha l f mo ve s - 1 ) , ;
o
o
r
е х е с . с : cpym ve ( & l a s t_m ve , & Move_h i s t o y [ N uffiь e r_ha l f move s - 1 ] ) ;
_
c onve r t_move ( & Move_h i s t o r y [ NumЬe r ha l f_move s - 1 ) ) ,
ехес . с :
_
е х е с . с : conve r t _move ( &Move_h i s t o r y [ i - 1 ] ) ,
е х е с . с : c o nve r t_move ( & Move_h i s t o r y [ N umЬe r_h a l f move s - 1 ) ) ,
_
ma kemove . c : I MPORT MOVE Move_h i s t o ry [ ] ;
i f ( Move_h i s t o r y [ j ] . f rom ! = ВООК ( i , j , f r om ) OR
ma kemove . c :
ma kemove . c :
Move h i s t o r y [ j ] . t o ! = ВООК ( i , j , t o ) )
_
t e s t ch . c : GLOBAL MOVE Move_h i s t o r y [ l O O ]
{О} ;
t e s t ch . c :
Move_h i s t o r y [ NumЬe r_ha l f_move s - 1 ) . f rom = move . f rom ;
te s t ch . c :
Move_h i s t o r y [ NumЬe r_ha l f move s - 1 ] . t o = move . t o ;
_
=

$

Просеяв приведенн ы й выше результат, можно обнаружить три исходных фай ­
ла, е х е с . с, rna kernove . с и t e s t ch . с, где применяется искомая перемен ная.
Если же допол нить команду grep параметром -1, то будет получен список фай­
лов, содержащих указанн ы й шаблон, а не те строки , которые с ним совпадают:

$

grep -1 ' Мove_history ' * . с

Перечислить
переменную

фа йлы ,

содерж ащие

Мove_history

ехес . с
ma kemove . c
t e s t ch . c

$

Найденные файлы удобно перечисляются по команде grep в отдельных стро­
ках, и поэтому резул ьтат выполнения команды grep - 1 можно передать по каналу

Кома нда sort

111

следующей далее команде wc, чтобы подсч итать количество файлов, содержащих
указанный шаблон, как демонстрируется в следующем примере:
$

grep -1 ' Мove_history ' * . с 1 wc -1

3

$

Как следует из приведен ного выше результата, ссылки на переменную Move
h i s tory содержатся в трех исходных файлах. А теперь проверьте себя: что вам
удастся подсчитать, есл и вы введете команду g rep без параметра -1 и передадите
результат ее выполнения по каналу следующей далее команде wc - 1 ?

_

Параметр

-n

Если в команде указан параметр - n , каждая строка из заданного файла, со­
впадающая с заданным шаблоном, предваряется соответствующим номером. Как
следует из предыдущих примеров, исходный файл te s t ch . с оказался одн и м из
тех файлов, где присутствовали ссыл ки на перемен ную Move h i s to ry. А в сле­
дующем примере демонстрируется, как выявить в этом исходном файле конкрет­
ные строки кода, содержащие ссылку на переменную Move h i s tory:
_

_

$

grep -n ' Мove_h i s tory ' tes tch . c

13 :
1 97 :
198 :

$

Пр едвари ть стр оки код а
их н омера ми

GLOBAL MOVE Move h i s t o r y [ l O O ]
{Of;
_
Move h i s t o r y [ NumЬ e r h a l f mo ve s - 1 ] . f rom
move . f rom ;
_
_
Mc ve h i s t o r y [ NumЬ e r ha l f mo ve s - 1 ) . t o
move . t o ;
_
=

__

=

Как видите, перемен ная Move h i s t o ry применяется в строках кода 1 3 , 1 97
и 198 из исходного файла te s t ch . с. Команда g rep является одной из наиболее
употребительных опытн ыми пользователями системы Unix благодаря своей гиб­
кой и развитой логи ке сопоставления с шаблоном. Поэтому она вполне заслужи­
вает более углублен ного изучения.
_

К ом а нда sort

В простей шем виде команду sort очень легко понять. Достаточ но предоста­
вить ей строки исходн ых дан н ых, и она отсортирует их в алфавитном порядке,
выведя результат на терминал, как показано н и же. По умолчани ю команда s o r t
прин имает каждую строку из указан ного входного файла и сортирует е е по воз­
растан и ю.
$ sort names
Ch a r l i e
Emanue l
Fred
Lucy

112

Гл а в а 3. Ра бочие и н струменты

Ra l p h
Tony
Tony
$

Специальные символы сортируются в соответстви и с внутренней кодировкой
символов. Например, символ пробела внутрен не представлен числовым значен и­
ем 32, а знак двойной кавычки - числовым значением 34. Это означает,, что в
результате сортировки пробел будет расположен прежде двойной кавычки. По­
рядок сортировки для других языковых стандартов может быть иным, и поэтому
порядок следования букв, знаков препинания и других специальных символов на
иностранных языках не всегда оказы вается таким, как можно было бы ожидать.
Но, как правило, можно быть уверенным, что команда sort обработает буквен­
но-цифровые исходн ые данные должным образом.
У команды s o r t имеется немало параметров, предоставляющих допол нитель­
ные удобства для сортировки. Н и же будут описаны некоторые из н их.
П а раметр -u

Параметр u предписывает команде s o r t исключ ить дубликаты строк из вы­
водимого результата, как показано в следующем примере:
-

$ sort -u names
Cha r l i e
Emanue l
Fred
Lucy
Ra l p h
Tony
$

В данном примере дубли кат строки с именем Tony искл ючен из резул ьтата,
выводимого командой s o r t . По тради ции многие пользователи системы Unix
выполняли ту же самую операцию, используя отдельную программу un i q, и если
просмотреть системные сценарии оболочки, то в них нередко можно обнаружить
команды вроде sort 1 u n i q. Теперь их можно заменить командой sort - u!
Параметр - r

Изменить порядок сортировки на обратный можно, указав параметр
дующим образом:
$ sort - r names
Tony
Tony
Ra l ph
Lucy
Fred

Изменить порядок сорт11ров кн

-r

сле­

Кома нда s o rt

113

Ema n ue l
C h ar l i e

$

Параметр



По умолчан ию команда s o r t направляет отсортированные данн ые в стан­
дартный вывод. Чтобы направить их в файл, можно, с одной стороны, указать
переадресацию вы вода следующи м образом:
$ sort names > sorted names
$
А с другой сторон ы, можно воспользоваться параметром о указав сразу же
после него выходн ый файл, как показано ниже. В итоге отсортирован ное содер­
жимое файла name s будет вы ведено в файл s o r ted name s .
-

$ sort names
$



,

sorted names

В чем же цен ность параметра -о? Зачастую требуется отсортировать строки в
файле, заменив в нем первоначальные дан н ые отсортированными. Но есл и вве­
сти следующую команду:
$ sort names > names
$

то в конечном итоге содержи мое файла name s будет очищено! А с помощью па­
раметра -о вполне допустимо указывать одно и то же имя как входного, как и
выходного файла в команде sort, как демонстрируется в следующем примере:
$ sort names
$ cat names



naшes

Cha r l i e
Ema n ue l
Fred
Lucy
Ra lph
Tony
Tony

$
Со вет

Будьте в н и мател ьн ы , за меняя первоначал ь н ы й входной файл при фил ьтра ции , сорти ров ке
или иной о б ра ботке его содержимого. Не пременно убедитесь в правил ьности в ы пол нен и я
С
кон кретной опера ци и . п режде чем переза писывать исходные да н н ые.
леUнп ix п редо­
тме нистема
ы уда
ия, чтобы
ставляет немало удобн ых средств . но в ней отсутствует кома нда о
восста н овить потеря н н ые да н н ые ил и файлы.

114

Гл а в а З . Рабочие и нструменты

П а ра метр -n

Допустим, имеется файл, содержащий пары координат точек данных ( х, у) :
$ cat data
5 27
2 12
3 33
23 2
-5 1 1
15 6
1 4 -9
$

Допусти м также, что эти дан ные требуется предоставить программе построе­
ния графиков под названием p l otdata. Но этой программе требуется, чтобы ис­
ходные пары дан ных были отсортированы по возрастан ию значения координаты
х (т.е. первого значения в каждой строке).
Параметр -n команды s o r t обозначает, что первое поле в строке следует счи­
тать числом, а дан н ые - отсортировать в алфавитном порядке. Сравн ите резул ь­
тат выпол нения команды s o r t без параметра -n и вместе с ним в следующем
примере:
$ sort data
-5
11
14
-9
15
6
2
12
23
2
33
3
5
27
$ sort -n da ta
-5
11
2
12
33
3
5
27
14
-9
15
6
23
2
$

О т сор тирова т ь в ари фме ти че ском п орядке

П роп уск полей

Если попытаться отсортировать файл da ta по значению координаты у, т.е. по
второму числу в каждой строке, то команде s o r t можно было бы предписать,
чтобы она нач инала сортировку со второго поля, указав следующий параметр:
-k2n

вместо параметра -n. Параметр - k 2 предписывает пропустить первое поле и на­
чать анализ сортировки со второго поля в каждом поле. Аналогично параметр

Кома нда sort

115

k Sn означает следующее: начать сортировку с пятого поля в каждой строке, а
затем отсортировать дан н ые в числовом порядке, как показано н и же.
-

$ sort -k2n data

14
23
15
-5
2
5
3

На ча ть сортир овку со в торого поля

-9
2
6
11
12
27
33

$

По умолчанию поля разделяются символами пробела или табуляции. Если
жетребуется указать другой раздел итель, это можно сделать с помощью параме­
тра - t.
Параметр - t

Как упоминалось выше, если пропустить некоторые поля, команда s o r t пред­
положит, что сортируемые поля разделяются символами пробела или табуляции.
Параметр - t позволяет указать и ное. В этом случае символ , указываемый после
параметра - t, принимается в качестве разделителя.
Рассмотрим снова в качестве примера файл пароля со следующим содержимым:
$ cat /etc/pas swd
roo t : * : O : O : The s upe r U s e r : / : / u s r / b i n / k s h
s t e ve : * : 2 0 3 : 1 0 0 : : / u s e r s / s t e ve : / u s r / b i n / k s h
b i n : * : 3 : 3 : The own e r o f s ys t em f i l e s : / :
cro n : * : l : l : C ron Daemon f o r pe r i od i c t a s ks : / :
g e o r ge : * : 7 5 : 7 5 : : / u s e r s / g e o r g e : / u s r / l i Ь / r s h
pa t : * : 3 0 0 : 3 0 0 : : / u s e r s / pa t : / u s r / b i n / ks h
uucp : nc 8 2 3 c i S i L i ZM : 5 : 5 : : / u s r / s poo l / uucppuЫ i c : / u s r / l i Ь / u u c p / u u c i co
a s g : * : б : б : The Owne r o f A s s i g n a Ы e De v i c e s : / :
s ys i n fo : * : l O : l O : Ac ce s s t o S y s t em I n f o rma t i o n : / : / u s r / b i n / s h
ma i l : * : 3 0 1 : 3 0 1 : : / u s r /ma i l :

$
Если этот файл требуется отсортировать по имени пользователя (т.е. первому
полю в 'каждой строке), с этой целью можно выдать следующую команду:
sort /etc/passwd

Чтобы отсортировать этот файл по третьему пол ю, разделяемому двоеточием
и содержащему так называемый идент ификатор пользователя, следует указать
арифметический порядок сортировки (параметр -kЗ) и знак двоеточия в каче­
стве разделителя полей ( параметр - t : ) . В следующем примере третье поле специ­
ально выделено полужирным в каждой строке, чтобы легко проверить, что файл
правильно отсортирован по идентификатору пользователя:

116

Гп а в New York , N . У . 1 0 0 0 3 "
$ echo $address
39 E a s t 1 2 t h S t r e e t New Yo r k , N . У .
$ echo "$addres s "
3 9 Ea s t 1 2 t h S t r e e t
New Y o r k , N . У . 1 0 0 0 3

1 0003

$

В данном конкретном примере не имеет осо бого значения, присваи вается ли
значение переменной addre s s в одиноч ных или двой ных кавыч ках. Оболочка в
л юбом случае отображает вспомогательное при глашение на ввод команд, чтобы
указать на то, что она ожидает ввода соответствующей закрывающей кавычки.
После присваи вания двухстрочного адреса перемен ной addr e s s ее значение
ото б ражается по команде e cho. В отсутствие кавычек вокруг имени этой пере­
мен ной адрес отображается в одной строке по той же самой причи не, что и сле­
дующий результат:
o n e t wo t h r e e f o u r

выполнения команды:
echo one

two

three

four

Двой н ые ка в ы ч ки

141

Оболочка удаляет символы пробела, табуляции и новой строки (т.е. все про­
бельные символы) из командной строки , а затем разделяет ее на аргументы, пре­
жде чем передать их запрашиваемой команде. Поэтому в резул ьтате вызова сле­
дующей команды:
echo $address

оболочка удал ит встроен ный в значение переменной addre s s символ новой
строки, интерпретируя его как символ пробела или табуляции, служащий в ка­
честве раздел ителя аргументов. А затем оболочка передаст девять аргументов
команде e cho для последующего отображения. Таким образом, сим вол новой
строки не дойдет до самой команды e cho, поскольку он предварительно обраба­
ты вается оболочкой (рис. 5.5).
39
East
1 2th
Street
New
York
N.
У.

1 0003
Рис. 5.5. П роцесс вы полнени я команды echo $addres s

Когда же выполняется следующая команда:
echo " $addres s "

оболочка подставляет значение перемен ной addre s s, как и прежде, н о в дан ном
случае двойные кавычки предписы вают ей оставить без внимания любые заклю­
ченные в них пробелы. Таким образом, оболочка передаст команде echo един ­
ственный аргумент, содержащи й си мвол новой строки. И команда e cho отобра­
зит св0й единственный аргумент. На рис. 5.6 этот факт отображает комбинация
символов \ n, обозначающая новую строку.

в displays the value of х , which is $х "
> > > d i s p l a y s t h e va l u e o f х , wh i c h i s 1
echo $х >>> di splays the value of х , whi ch i s ' $х
> > > d i s p l a y s t h e va l u e o f х , wh i c h i s 1

В первом случае вся строка заключается в двой ные кавычки, а знак обратной
косой черты служит для того, чтобы предотвратить подстановку значения пере­
менной х вместо первого экземпляра $ х. А во втором случае строка заключается
в одиночные кавы чки вплоть до второго экземпляра $ х, добавляемого как пере­
менная без кавычек, вместо имени которой следует подставить ее значение.
Но последн ий способ заключения в кавычки таит в себе следующую едва за­
метную опасность: если переменная х содержит подстановку имени ф айла или
символы пробела, он и будут интерпретированы. Поэтому рассматриваемую здесь
команду e cho надежнее написать следующим образом:
echo ' > displays the value of х , which i s ' " $ х "

П одста н ов ка ко ма нд

Подстановка команд означает для оболоч ки возможность заменить указанную
команду резул ьтатом ее выполнения в любом месте командной строки. Выпол ­
нить подстановку команд в оболоч ке можно двумя способами: заключив команду
в обратн ые кавычки или введя ее в конструкцию $ ( . . . ) .
Обратн ые кав ы ч ки

В отличие от всех упоминавшихся ранее типов кавычек, назначение обратных
кавыче� состоит не в том, чтобы защитить символы от и нтерпретации в оболочке,
но предписать ей заменить заключенную в них команду результатом ее выполне­
ния. Общая форма применен ия обратных кавычек выглядит следующим образом:
кома нда

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

146

Гл а в а 5. За кл ючение в кав ы ч ки

П р и меча н ие

Употребл ять обратн ые ка вычки дnя подстановки команд бол ьше не рекомендуется . Тем не
менее м ы рассматриваем такой спосо б подста новки ком а нд потому, что он применяется в
бол ь шом кол ичестве п режн и х сценариев о болочки . Кроме того , о возмож ностях обратных
ка вычек следует знать на тот случ а й , есл и п ридется п исать п рогра м м ы о б олочки , перено­
симые в прежние версии систем U п ix с о болочка м и , где не поддержи вается новая и более
п редпочтител ьная конструкция $ ( . . . ) .

Рассмотри м следующий пример подстановки команды, закл ючаемой в обрат­
ные кавычки:
$ echo Тhе date and time i s : ' date '
The d a t e a n d t ime i s : Wed Aug 2 8 1 4 : 2 8 : 4 3 E DT 2 0 0 2
$

Когда оболочка выпол няет первоначальн ый просмотр командной строки, она
распознает обратную кавычку, ожидая вслед за ней команду. В данном случае
оболочка обнаруживает команду da te и поэтому выпол няет ее, заменяя после­
довательность символов ' da te ' в командной строке результатом выпол нения
команды date. После этого оболочка разделяет получен ную в итоге командную
строку на аргументы, как обычно, передавая их команде e cho.
В приведен ном н и же примере оболочка выпол няет команду pwd, подставляет
результат ее выполнения в командную строку, а затем выполняет команду e cho.
В примерах из следующего раздела обратные кавычки могут быть использованы
везде, где применяется рассматриваемая далее конструкция $ ( . . . ) , а послед­
няя - разумеется, в примерах из этого раздела.
$ echo Your current working di rectory is ' pwd '
Y o u r c u r r e n t wo r k i n g d i r e c t o r y i s / u s e r s / s t e ve / s h e l l / c h б
$

Конструкция $ (

)
В современ ных оболочках Unix, Linux и прочих, совместимых со стандартом
POSIX, для подстановки команд поддерживается новая и более предпочтительная
конструкция $ ( . . . ) . Общая форма этой конструкци и выглядит следующим об­
разом:
.

.



$ ( кома нда )

где кома нда - это, как и в обратных кавычках, имя команды, стандартный вывод
из которой подставляется в командной строке. Рассмотрим следующий пример:
$ echo Тhе date and time i s : $ (date)
T h e da t e and t i me i s : Wed Aug 2 8 1 4 : 2 8 : 4 3 E DT 2 0 0 2

$

Подста новка команд

147

Такая конструкция луч ше обратных кавычек по двум при ч инам. Во-первых, в
сложных командах прямые и обратные кавычки могут употребляться в различ­
ных сочетан иях, что затрудняет их пониман ие, особенно если выбранное для на­
писания команд начертание шрифта не позволяет визуально отличить оди ноч­
ные кавычки от обратных. И, во-вторых, конструкция $ ( . . . ) допускает простое
вложение, а следовательно, подстановку одной команды в другую. И хотя обрат­
ные кавычки также допускают вложение, сделать это труднее. Пример вложенной
подстановки команд будет представлен далее в этом разделе.
Следует особо подчеркнуть, что в круглых скобках дан ной конструкции мож­
но вызывать не одну, а несколько команд, разделяемых точками с запятой. И за­
частую для этой цели могут также использоваться каналы.
Ниже приведен вариант программы nu для отображения количества пользо­
вателей, зарегистрированных в системе. Он был видоизменен с тем, чтобы про­
демонстрировать применение новой конструкции $ ( . . . ) .
$ cat nu
e cho The re a re $ ( who 1 wc - 1 )
$ nu
The re a r e 1 3 u s e r s l ogged i n
$

u s e r s l og g e d i n
Вып олнить про гр амму

Одиноч ные кавычки защищают все, что в н их заключено, и поэтому результат
выполнения следующей команды вполне очевиден:
$ echo ' $ (who 1 w c - 1 ) tel l s how many users are loqged in '
$ ( who 1 wc - 1 ) t e l l s how man y u s e r s a re l og g e d i n
$

Но подстановка команд все же интерпрет ируется в двой ных кавычках, как
показано ниже
$ echo "You have $ ( l s 1 wc - 1 ) fi les in your di rectory"
You h a ve
7 f i l e s in you r d i r e c t o r y
$

Напомним, что оболочка отвечает за выполнение команды, заключаемой в
круглые скобки рассматриваемой здесь конструкции. А команда e cho замечает
только подставляемый оболоч кой результат выполнения команды, указанной в
круглых скобках.
П р имеч а ние

Начальн ые п робел ы , получ а ющиеся в резул ьтате вы полнения команды wc в приведенном
вы ше при мере , неизменно вызыва ют досаду у п рогра м м истов . П оп ро б уйте на йти спосо б
изба виться от них с помощью кома нды sed.

148

Гл н в а 5. Заключение в кав ы ч ки

Допустим, в создаваемой программе оболочки требуется присвоить текущие
дату и время перемен ной now. Для этого можно воспользоваться подстановкой
команд следующим образом:
$ now=$ (date)

Выполнить к ома нду da te н с о хра нить
резуль т а т в п ер еменной ПОW'
$ echo $now
Посмо треть , ч то присво ен о переме нн о й now
Wed Aug 2 8 1 4 : 4 7 : 2 6 E DT 2 0 0 2
$

Если ввести следующую строку:
now=$ (da te)

интерпретировав ее, оболочка присвоит переменной now весь результат выпол ­
нения команды da te. Следовательно, заключать конструкци ю $ ( date ) в двой­
ные кавычки не нужно, хотя это обычно делается на практи ке.
В перемен ной могут быть сохранены даже те команды, которые выдают ре­
зультат в нескольких строках:
$ filel i s t=$ ( l s )
$ echo $filel i s t
addre s s e s i n t ro l o t s a s p a c e s name s nu numЬe r s p h o n e b o o k s t a t
$

Что же здесь произошло? В конеч ном итоге в одной строке был выведен пе­
речень всех файлов из текущего каталога, хотя знаки новой строки из команды
l s были сохранены в перемен ной f i l e l i s t. Эти знаки были поглощены при
отображении значения переменной f i l e l i s t, подставлен ного оболочкой в про­
цессе обработки командной строки e cho. Знаки новой строки можно сохранить,
если заключить перемен ную f i l e l i s t в двойные кавычки, как в следующем
примере:
$ echo " $ fi lel i s t "
addre s s e s
i n t ro
l o t s a sp a c e s
name s
nu
numЬe r s
p h o n e bo o k
stat
$

П родви гаясь далее в область написания сценариев оболочки, выясним, как
п рименять рассматриваемую здесь конструкцию в сочетании с переадресацией
стандартного ввода-вывода в файл. Напри мер, чтобы сохран ить содержимое
файла в переменной, можно воспользоваться следующей удобной командой cat:

Подста новка команд

149

$ namel ist•$ ( cat name s )
$ echo " $namelist"
Ch a r l i e
Ema п u e l
F re d
Lucy
Ra l p h
Топу
Топу
$

Если же требуется разослать почтой содержимое файла memo всем адресатам,
перечисленным в файле name s, это можно сделать следующим образом:
$ mail $ ( ca t names )
$

< memo

В данном случае оболочка заменяет сначала команду cat результатом ее выпол­
нения, и поэтому командная строка принимает приведенный н иже вид. А затем
оболочка выполняет команду ma i l, переадресовывая ее стандартный ввод из фай­
ла memo и передавая ей семь указанных получателей почты в качестве аргументов.
ma i l Ch a r l i e Ema п u e l F r e d L u c y Ra l p h Т о п у Т о п у < memo

Обратите внимание на то, что адресат Tony может получить одно и то же по­
чтовое сообщение дважды, поскольку он два раза перечислен в файле name s .
Чтобы устранить любые дублирующиеся записи из файла, вместо команды c a t
можно воспользоваться командой s o r t с параметром -u, удаляющим дубли каты
строк, как показано ниже. В итоге каждый адресат получит почтовое сообщение
только ОДИ Н раз.
$ mail $ ( sort -u names )
$

< memo

Напомним, что оболочка выпол няет подстановку и мен файлов после подста­
новки команд. Заключив команды в двойные кавычки, можно исключить подста­
новку имен файлов при выводе результатов.
Подстановка команд нередко применяется с целью изменить значение, храня­
щееся � перемен ной оболочки. Так, если перемен ная оболочки name содержит
чье-то имя, где все буквы требуется сделать проп исными, для этого можно вос­
пользоваться командой echo, чтобы передать переменную name на вход команды
t r, выполнить преобразование, а затем присвоить результат обратно переменной
name, как показано ниже.
$ name="Ralph Кramden "
$ name=$ ( echo $name 1 tr
$ echo $name
RA L P H KRAMDEN
s

' [ a- z ] '

' [A- Z ] ' )

Пр ео бра зова ть
в пропи с ные буквы

150

Гл а в а 5. Заключение в ка вычки

Способ употребления команды e cho в конвейере для передач и данных на
вход последующей команды прост, но эффективен и нередко применяется в про­
граммах оболочки. В следующем примере демонстрируется, каким образом с по­
мощью команды cut можно извлечь первый символ из значен ий, хранящихся в
перемен ной f i l ename:
$ fi lename=/users/s teve/шemos
$ firs tchar=$ ( echo $filename 1
$ echo $firstchar
/
$

cut -cl )

Отредактировать значение, хранящееся в перемен ной, зачастую можно и с по­
мощью команды s ed. В следующем при мере эта команда используется для из­
влечения последнего символа из каждой строки в файле, указан ном в переменной
f i l e:
$ file=exec . o
$ las tchar=$ ( echo $file 1
$ echo $lastchar

sed ' s/ . * \ ( . \ ) $ / \ 1 / ' )

о
$

Команда s ed заменяет все символы в строке последним ее символом. ( Напом­
ним, что шаблон в круглых скобках приводит к сохранени ю последнего символа
в указан ном регистре. В данном случае это регистр 1 , на который делается ссылка
\ 1 .) Подставляемы й результат выполнения команды sed сохраняется в перемен­
ной l a s t char. Команда sed заключена в одиноч н ые кавы чки для того, чтобы
оболочка не пыталась интерпретировать знаки обратной косой черты, применя­
емые в этой команде. ( Вопрос: подошли бы для этой цели и двой ные кавычки?)
И наконец, подстановки команд могут быть вложенными. Допустим, требует­
ся изменить каждое вхождение первого си мвола в перемен ной на что- нибудь дру­
гое. В при веденном ранее примере команда f i r s tchar=$ ( e cho $ f i l ename 1
cut - c l ) извлекает первый символ из переменной f i l ename, но как восполь­
зоваться этим символом, чтобы изменить каждое его вхождение в переменной
f i l ename? С одной стороны, эту операцию можно выполн ить в два этапа, как
показано ниже.
$ fi lename=/users/s teve/шemos
$ firs tchar=$ ( echo $filename 1 cut -c l )
$ filename=$ (echo $fi lename 1 tr "$firstchar" " "' " )
$ echo $ fi lenaшe

л u s e r s л s t e ve лmemo s
$

Пре о бр а зов а ть

зна к / в зна к "'

Подста новка команд

151

А с другой стороны, ту же самую операцию можно выполнить в течение одной
вложенной подстановки команд следующим образом:
$ filename=/users /s teve/memos
$ filename=$ ( echo $filename 1 tr " $ ( echo $filename

$ echo $ filename

1 cut -cl ) " " " " )

$

Если вам трудно понять при веденный выше пример, сравн ите его с предыду­
щим при мером, обратив внимание на то, что перемен ная f i r s tcha r заменена
в нем вложенной подстановкой команд. А в остальном оба примера оди наковы.
Команда expr

Несмотря на то что в стандартной оболочке поддержи ваются встроенные це­
лочислен н ые арифметические операции, в прежних оболочках такая поддержка
отсутствует. В таком случае может пригодиться команда expr для решен ия мате­
матических уравнен ий:
$ expr 1 + 2
3
$

Команда expr проста в обращен ии, но она не вполне пригодна для си нтакси­
ческого анализа уравнен ий. Поэтому каждую операцию и операнд, указываемые
в команде expr, необходимо отделять пробелами для правильной их интерпрета­
ции. Это обстоятел ьство поясняется в следующем примере:
$ expr 1+2
1+2

$

Команда expr распознает обычные арифметические операции: сложения ( +),
вычитания (-), деления (/), умножения (*) и взятия по модулю (%; получения
остатка от деления). Ниже приведен характерный тому при мер.
$ expr' 1 0 + 2 0 / 2
20
$

Операции умножен ия, деления и взятия по модулю обладают более высоким
приоритетом, чем операции сложения и вычитания, как и в обычной арифметике.
Следовательно, в предыдущем примере деление выполняется прежде сложения.
А что же неверно в приведен ном н иже примере?
$ expr 1 7 * б
expr :

$

s yn t a x e r r o r

152

Г11 а в >

p h o n e bo o k

$

И хотя этого не видно, на самом деле аргументы $ 1 и $ 2 разделяются в при ­
веденной выше команде e cho знаком табуляци и . Этот знак должен быть указан
в кавычках, чтобы воспроизводиться по команде echo, а не "поглощаться" обо­
лочкой. Опробуем новую программу следующим образом:
$ add ' StromЬol i Pizza ' 9 7 3 - 5 55 - 9 4 7 8
Пров ерит ь , уда стся л и на й ти новую за пис ь
$ l u Pizza
Пока что в се нормаль н о
S t romЬo l i P i z za 9 7 3 - 5 5 5 - 9 4 7 8
$ cat phoneЬook
Выв е с ти содержимое телефонного с пра в о ч ни ка
Al i c e Chebba
973-555-2 0 1 5
Ba rba r a Sw i n g l e
2 0 1-555-9257
Li z Stachiw
2 1 2 -555-2 2 9 8
S u s a n Go l dbe rg
2 0 1 - 555-7 7 7 6
2 12-555-4 932
S u s a n Topp l e
97 3-555- 1 2 95
Топ у I an n i no
973-555-9478
S t romЬo l i P i z z a
$

Имя и фамилия S t rornЬo l i P i z za были заключены в одиночные кавычки,
чтобы оболочка передала их программе add как единый аргумент. (А что бы про­
изошло, если бы имя и фамилия не были заключены в оди ноч ные кавычки?) По­
сле программы add в приведен ном выше примере была выполнена программа
l u, чтобы выяснить, удастся ли найти новую запись в телефонном справочника,
что и было благополучно сделано. А затем была выполнена команда са t, чтобы
посмотреть, каким образом теперь выглядит видоизмененный телефонный спра­
вочник. Как и предполагалось, в самом его кон це появилась новая запись.
К сожалению, новый файл стал неотсортированным. И хотя сортировка содер­
жимого этого файла не оказывает н икакого влияния на выполнение программы
l u, тем не менее, она является полезным свойством. С этой целью в программу
add можно ввести команду сортировки sort, как показано ниже.

П рограмма дл я удале ния а бо нентов из теле фо н ного спра воч н и ка

161

$ cat add
#
# В вести н о во г о а б о н е н та в телеф о н ньm с п р а в оч ни к - верси я 2
#

$ 2 " > > phonebo o k
echo " $ 1
s o r t - о phoneboo k phoneboo k
$

Напомним, что параметр -о команды s o r t определяет место для вывода от­
сортированного результата. В данном случае это тот же самый входной файл, как
показано ниже. Всякий раз, когда в файл phoneboo k вводится новая запись, его
содержимое сортируется снова, чтобы многостроч ные совпадения с критерием
поиска всегда располагались в алфавитном порядке.
$ add ' Bi l ly васh '
$ cat phoneЬoo k
A l i ce Chebba
B a r b a r a Sw i n g l e
B i l l y Bach
Liz Stachiw
S t r omЬo l i P i z z a
S u s a n Go l dbe rg
Susan Topp l e
Топу I an n i n o
$

2 0 1 -555 - 7 6 1 8
973-555-2 0 1 5
201-555-9257
2 0 1 -555-7 618
2 12 -555-2298
973-555- 94 7 8
201-555-7776
2 12-555-4 932
973-555- 1295

П рогра м м а дл я уда л ен и я або ненто в
из тел ефо н н ого сп р а в о ч н и ка

Ни оди н ком плект программ, позволяющих искать или вводить абонентов в
телефонный справочник, не будет полным без программы удален ия абонентов
из телефон ного справочника. Поэтому напишем программу rem, позволя ющую
удалить из телефон ного справочн и ка абонента по и мени, указан ному в качестве
аргумента в командной строке.
Какой должна быть стратегия разработки такой программы? По существу, из
файла требуется удалить строку, содержащую указанное имя абонента, что про­
тивопо� ожно совпадению с шаблоном. В данном случае можно воспользоваться
параметром -v команды grep, поскольку он позволяет сделать и менно то, что
требуется: вывести из файла все строки , которые не совпадают с шаблоном:
$ cat rem
#
# Удалит ь а б о н е н та и з теле фонн о г о с п р а во ч ни к а
#

g rep -v " $ 1 " phonebo o k > / t mp / phonebo o k
m v / tmp / phoneboo k phoneboo k
$

162

Гла в а 6.

Передача а ргументов

По команде g rep с параметром -v все строки из файла phonebook, не совпада­
ющие с заданным шаблоном, выводятся в файл / tmp /phonebook. (Примечание:
каталог / tmp служит в системах Unix для хранения временных файлов и обычно
удаляется при перезапуске системы.) А после выполнения команды g rep преж­
ний файл phoneboo k заменяется новым файлом из каталога / tmp. Ниже приве­
дены некоторые примеры применения вновь создан ной программы rm.
$ rem ' StromЬol i Pi z za '
Уда лить э ту за пись
$ cat phoneЬook
973-555-2015
A l i ce C h e bba
201-555-9257
Barbara Swingle
2 0 1 -555-7 6 1 8
B i l l y Bach
2 1 2 -5 5 5 -2 2 9 8
Li z Stachiw
S u s a n Go l db e r g
2 0 1 -555-7 7 7 6
2 12-555-4 932
S u s a n Topp l e
973-555-1295
Tony I a nn i no
$ rem Susan
$ cat phoneЬook
973-555-2015
A l i ce C h e bba
201-555-9257
B a r b a r a Sw i n g l e
2 0 1 -555-7 6 1 8
B i l l y Bach
2 12 - 555-2 2 9 8
L i z Stachiw
973-555-1295
Tony I a n n i n o
$

В первом случае из файла phoneboo k была благополуч но удалена зап ись
S t romЬo l i P i z za. Но во втором случае из него были удалены обе записи с име­
нем Sus an, поскольку обе они совпали с заданным шаблоном, а это не совсем
верно! Чтобы ввести эти записи обратно в файл phoneboo k, можно воспользо­
ваться программой add следующим образом:
$ add • susan GoldЬerg ' 2 0 1 -555-7 7 7 6
$ add ' Susan Topple ' 2 12 -555-4 932
$

В главе 7 будет показано, как проверять действие прежде, чем выполнять его,
чтобы в рассматриваемом здесь примере программы можно было определить
факт обнаружения не одной, а нескольких совпадающих записей. Но в програм­
ме может, например, возникнуть потребность известить пользователя об обна­
ружении нескольких совпавших записей вместо слепого их удаления. (Это было
бы очень удобно, поскольку в большинстве реализаций команды g rep произой­
дет совпадение со всем, что угодно, если в качестве шаблона передать ей пустую
символьную строку. По существу, это привело бы к удалению всего содержи мого
файла phoneboo k, что было бы неверно!)
Между прочим, совпавшую запись можно было бы удалить и по команде sed.
В таком случае команду g rep можно было бы заменить следующей командой :
s e d " / $ 1 / d " phoneboo k > / tmp / p honeboo k

Ком анда shift

163

чтобы добиться аналогичного результата. Аргумент команды sed необходимо за­
ключить в двой ные кавычки, чтобы обеспечить подстановку значения аргумента
$ 1 и в то же время гарантировать, что оболочка не отреагирует на команду, ана­
логичную приведен ной ниже, где команде s ed передаются три, а не два аргумента.
sed / S t romЬo l i

P i z z a / d phoneboo k

>

/ tmp /phoneboo k

Конструкци я $ { п }

Если предоставить программе больше девяти аргументов, то десятый и после­
дующие аргументы ( $ 1 0, $ 1 1 и т.д.) окажутся недоступными. И если поп ытаться
получить доступ к десятому аргументу по ссылке $ 1 0, то оболочка фактически
подставит значение аргумента $ 1 , а затем значение О. Вместо этого следует вос­
пользоваться конструкцией $ { п } . Так, чтобы получить непосредствен ный до­
ступ к десятому аргументу, следует указать ссылку $ { 1 О } в своей программе и
так далее для оди н надцатого, двенадцатого и остальных аргументов.
К оманда shi f t

Эта команда позволяет, п о существу, смещать влево позиционные параметры.
Есл и выполнить команду s h i ft, предыдущее значение позиционного параметра
$2 будет присвоено позиционному параметру $ 1 , а предыдущее значение пози­
ционного параметра $ 3 позиционному параметру $2 и т.д. В то же время преж­
нее значение позиционного параметра $ 1 будет безвозвратно утрачено.
При выполнении этой команды значение перемен ной $ # , содержащей количе­
ство аргументов, также автоматически уменьшается на един ицу, как показано ниже.
-

$ cat tshift
echo $ # $ *
shi f t
e cho $ # $ *
shi ft
e cho $ # $ *
sh i f t
echo $ � $ *
shi ft
echo $ # $ *
shi ft
echo $ # $ *
$ tshift а ь с d
5 а ь с d е
4 ь с d е
з с d е
2 d е
1 е

о
$

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

е

164

Гл а в а 6

Передача аргументов

Если попытаться выполн ить команду s h i ft в отсутствие переменных для
смещения (т.е. когда значение перемен ной $ # уже равно н улю), то оболочка вы ­
даст следующее сообщение об ошибке, хотя его содержимое зависит от конкрет­
ной версии оболочки:
p ro g :

s h i f t : b a d n umЬe r

где prog
имя программы, в которой была выполнена команда s h i ft, а bad
nшnЬe r неверное количество аргументов.
Смещение может быть произведено сразу на несколько позици й , если указать
их количество при вызове команды s h i ft. Так, выполнение следующей команды:
-

-

shi ft З

дает такой же результат, как и выполнение подряд трех команд s h i ft без аргу­
ментов:
shi ft
shi ft
shi ft

Команда s h i f t удобна для обработки переменного кол ичества аргументов.
Ее практическое применен ие будет продемонстрировано в главе 8, когда речь
пойдет о ци клах. А до тех пор достаточно запомнить, что позиционные параме­
тры можно продви гать по цепочке, используя команду s h i ft.

В ы бор п о усл овию
В этой главе рассматривается условный оператор i f
конструкция, присут­
ствующая практически в каждом языке программирования. Этот оператор по­
зволяет сначала проверить заданное условие, а затем изменить ход выполнения
программы в зависи мости от результата проверки. Ниже приведена общая форма
команды, реализующей условный оператор i f.
-

i f кома нда ,
then
кома нда

кома нда
fi

выполняемая команда и проверяемый код е е завершен ия. Так,
где кома нда ,
если код завершения равен нулю, выполня ются команды, указан ные в промежут­
ке между операторам и then и f i , а иначе эти команды пропускаются.
-

К од за вершен и я

Чтобы понять принцип действия условного оператора, важно знать, каким об­
разом в системе Unix обрабатывается так называемый код завершения. Всякий
раз, когда программа завершает свое выполнение, она возвращает оболочке со­
ответствующий код завершения. Условно нулевой код завершения обозначает
удачный исход выпопнения программы, а ненулевой код завершения - неудач ­
ный исход, причем разные значения кода завершен ия обозначают разные виды
неудачного исхода.
Неудачный исход может быть обусловлен тем, что программе переданы недо­
стоверные аргументы или в ней обнаружено ошибочное условие. Напри мер, ко­
манда ер возвращает ненулевой (сбой ный) код завершения, есл и копия оказыва­
ется неудачной ( например, если нельзя найти исходн ый файл или создать целевой
файл) или же если аргументы указаны неверно ( напри мер, неверное кол ичество
аргументов или больше двух аргументов, последн и й из которых не является ка­
талогом).
Что же означает ненулевой код завершен ия? Он означает любое целоч ислен ­
ное значен ие, не равное нулю. На больши нстве операти вных страниц руковод­
ства по командам системы U11 ix перечисля ются и возможные коды завершения.
Так, возможными ошибочными условиями завершения команды копирования

Г м ш а 7 . В ы б ор по условию

166

файлов могли бы быть следующие: 1 (файл не найден), 2 (файл недоступен для
чтения), З ( целевая папка не найдена), 4 ( целевая папка недоступна для записи),
5 (общая ошибка копирования файла) и , конечно, О (успешное завершение).
Что же касается команды g rep, то она возвращает нулевой код завершения,
если обнаружит заданный шаблон, по крайней мере, в одном из указанных фай­
лов, или ненулевой код завершен ия, если найти шаблон не удалось или есл и воз­
н и кло другое ошибочное условие вроде сбоя при открытии указанного исходного
файла. А в конвейере код завершения отражает состояние последней команды в
канале. Таким образом, в следующем конвейере:
who

1

grep f red

код завершения команды g rep используется оболочкой в качестве кода заверше­
ния всего конвейера. В этом случае нулевой код (успешного) завершения означа­
ет, что пользовател ь f red был обнаружен в результате выполнения команды who
(т.е. пользователь fred был зарегистрирован в тот момент, когда выполнялась
эта команда).
Переме н ная $ ?

В перемен ной $ ? оболочка автоматически устанавли вает код завершения ко­
манды, выпол нявшейся последней. Естественно, что для вывода значения этого
кода на терминал можно воспользоваться командой e cho, как показано ниже.
Следует, однако, заметить, что числовой результат "сбоя" в некоторой команде
может изменяться при переходе от одной верси и Unix к следующей, но удачный
исход всегда обозначается нулевым кодом завершения.
$ ер phoneЬook phone2
$ echo $ ?

о

"Уда чный " исх од ко пиро ва ния

$ ер nosuch Ьackup
ер : c a n n o t a c ce s s n o s uch
$ echo $ ?

2
$ who

"Неуда чньл1 " исход копиров а н ия
Выяснить , кто заре ги стрирова н в си стеме
Ju l 8
1 0 : 06
Ju l 8
12 : 36
Ju l 8
1 4 : 57
Ju l 8
1 5 : 03

root
con s o l e
w i lma
t ty03
barney
t ty04
be t t y
ttyl5
$ who 1 grep barney
barney
t ty04
Ju l 8
1 4 : 57
$ echo $ ?
Вывес ти код за в ершения п оследней
кома нды

о
$ who 1 grep fred
$ echo $ ?

1

$ echo $ ?

о
$

(grep)

"Уда ч ный " 1 1 сх од выполнения кома нды grep

"Неуда чНЫJ1 " исх од выполнения кома нды grep
Код за в ершения послед не й кома нды echo

Код за вершения

167

В качестве примера напишем программу оболочки on, которая сообщает, заре­
гистрирован ли указанный пользователь в системе. Имя проверяемого пользова­
теля будет передано этой программе из командной строки. Если указанный поль­
зователь зарегистрирован в системе, данная программа выведет соответствующее
сообщение, а иначе - н ичего не сообщит. Ниже показано, каким образом выгля­
дит программа on.
$ cat on
#
# В ыя сн и т ь ,
#

з ар е г и с три ро в а н л и у к а за н ный п ол ь з о в а т е л ь в с и с теме

user= " $ 1 "
i f who
then

1 g r ep " $ u s e r "
echo " $ us e r is logged o n "

fi
$

Сначала первый аргумент, набранный в командной строке, сохраняется в пере­
менной оболочки user. Затем в команде i f вы полняется следующий конвейер
команд:
who

1

g re p " $ u s e r "

проверяется код завершения, возвращаемый командой g rep. Если код завер­
шения оказывается нулевым (т.е. обозначает удачный исход), это означает, что
команда grep обнаружила пользователя, имя которого хранится в переменной
use r, в передан ном ей по конвейеру результате выполнения команды who. А если
код завершения оказывается ненулевым (т.е. обозначает неудачный исход), то это
означает, что указанный пользователь не зарегистрирован в системе, и поэтому
команда echo пропускается.
Команда e cho указана в рассматриваемой здесь программе с отступом от ле­
вого края исключительно из эстетических соображений. В данном случае в про­
межутке между операторами then и fi заключена лишь одна команда. Есл и же
таких команд оказывается больше, а их вложенность углубляется, то наличие от­
ступов значительно повышает удобочитаемость программы. Это обстоятельство
будет наглядно продемонстрировано в последующих примерах. Н и же приведены
некоторые примеры применения программы on.
и

$ who
root
barney
f red
j oa n n e
tony
lulu

con s o l e
t ty03
t ty04
t ty07
ttyl9
t t y2 3

Ju l
Ju l
Jul
Ju l
Ju l
Jul

8
8
8
8
8
8

10 :
12 :
13 :
09 :
08 :
09 :

37
38
40
35
30
55

r л а в а 7 . В ы бо р по условию

168

$ on tony

Изв е стно ,

что этот пользова тель

зарегистриро ва н в системе
tony
tty1 9
T o n y i s l ogged on
$ on s teve

Ju l 8

Где о н был з аре гистрирова н ?

Из в е стно ,

$ on ann
t t y0 7
j oanne
a n n i s l og g e d on
$

08 : 30

Jul 8

что э тот пользова тель не
зарегистрирова н в системе
По пр о б о ва ть в ыя сю1 т ь присут с твие
эт о го поль з ов а теля в сн с т еме
09 : 35

Рассматриваемой здесь программе все же присущи определенные недостатки.
Есл и указанный пользовать зарегистрирован в системе, соответствующая стро­
ка из результата, выводимого командой who, любезно отображается при вызове
команды grep. И хотя в этом нет ничего предосудительного, тем не менее, от
данной програм мы требуется выводить только сообщение о том, что указанный
пользователь зарегистрирован в системе, и ничего больше.
Упомянутая выше строка отображается вследствие проверки по условию.
Ведь команда g rep не только возвращает код своего завершения в следующи й
конвейер:
who

1

grep " $ u s e r "

н о и выполняет свою обычную функцию, направляя любые совпавшие строки в
стандартный вывод, даже если они нас не и нтересуют.
Но поскольку нас интересует не результат выполнения команды g rep, а толь­
ко код ее завершения, то мы можем избавиться от этого результата, переадресо­
вав его в системный "мусорный бачок" по пути / dev /nul 1, где находится специ­
альн ый системный файл, куда любой пользователь может записывать или откуда
читать, получая сразу же признак конца файла. При записи в этот файл информа­
ция исчезает как в огромной черной дыре! Поэтому недостаток вывода избыточ­
ной и нформации разрешается следующим образом:
who

1

g r e p " $ u s e r " > / d e v / nu l l

Другой недостаток программы on проявляется, когда она выполняется с аргу­
ментом ann. Несмотря на то что пользователь ann не зарегистрирован в системе,
команда g rep обнаруживает совпадение с символами a nn в имени пользователя
j oanne. Поэтому в данном случае требуется более строги й шаблон, о составле­
нии которого шла речь при рассмотрен ии регулярных выражений в главе 3. По
команде who в первом столбце выводи мого резул ьтата перечисляется имя каждо­
го пользователя, работающего в системе, и поэтому составляемый шаблон можно
ограничить сопоставлением с началом строки, предварив этот шаблон знаком " ,
как показано н и же.
who

1

g r ep n л $ u s e r " > / de v / n u l l

Код заве р шен и я

169

Но и этого оказывается недостаточно. Ведь, осуществляя поиск по шаблону
вроде ЬоЬ, команда все равно обнаружит строку, аналогичную следующей :
ЬоЬЬ у

tty07

Ju l 8

0 9 : 35

Поэтому шаблон необходимо огранич ить и справа. Если учесть, что и м я каж­
дого пользователя выводится по команде who с одн и м или двумя пробелами, то
приведенный ниже видоизмененный шаблон обеспечит совпадение только с теми
строками, где и меется указанное имя пользователя.
" л $user "

Таким образом, оба недостатка рассматриваемой здесь программы устранены !
А теперь опробуем новую, видоизмененную версию этой программы:
$ cat on

#
# В ы я с ни т ь , з а ре ги с триро ва н ли ука за н ный п о л ь з о ва т ел ь
# в с и с теме - ве р с и я 2
#
user= " $ l "
i f who 1 g r e p " л $ u s e r " > /de v / n u l l
t he n
e c h o " $ u s e r i s l ogged on "
fi
Кто теперь зареги стрирова н в системе ?
$ who
10 : 37
Jul 8
con s o l e
Roo t
Ju l 8
t t y03
12 : 38
barney
Ju l 8
13 : 40
f red
tty04
j oanne
09 : 35
Jul 8
tty07
Ju l 8
tony
08 : 30
ttyl 9
Ju l 8
09 : 55
t t y2 3
lulu
$ on lulu
l u l u i s l ogged o n
Попро бовать выяснить присутствие
$ o n ann
эт ого пользов а теля в системе
$ on
Выяснить , что про изо йдет , если
в оо бще не ука за ть ника ких ар гумент о в ?
$

Если аргументы вообще не указаны, переменная u s e r окажется пустой и ко­
манда grep будет искать в результате, выводимом командой who, строки, нач и на­
ющиеся с пробела ( подумайте, почему?). Не обнаружив н и одной из таких строк,
команда grep просто возвратит приглашение на ввод в командной строке. В сле­
дующем разделе будет показано, как проверить, было ли указано правильное ко­
личество аргументов программы, и если оно оказалось неверным, то предпринять
соответствующее действие.

170

Гл а в а 7 . В ы бор по усло вию

К о м а н да te s t

Несмотря на то что для проверки условия в операторе i f из предыдущего при­
мера программ ы применялся кон вейер, для проверки одного или нескольких ус­
ловий намного чаще употребляется встроенная в оболочку команда t e s t. Ниже
приведена общая форма этой команды.
t e s t выражение

где выражение обозначает проверяемое условие. Команда t e s t вычисляет вы­
ражение, если оно дает истинный результат (TRUE), то возвращается нулевой код
завершен ия, а если результат оказывается ложньtм ( FALSE), то возвращается не­
нулевой код завершения.
Строковые операции

В качестве примера ниже приведена команда, возвращающая нулевой код
завершения, если переменная оболоч ки name содержит си мвольную строку
" j ul i o " .
t e s t " $ name " = j u l i o

Операция = служит для проверки равенства двух значени й . В дан ном случае
проверяется, равно ли содержимое переменной оболоч ки name символьной стро­
ке " j u l i o " . Если такое равенство подтверждается, команда te s t возвращает
нулевой код завершения, а и наче - ненулевой код завершения.
Следует, однако, иметь в виду, что все операнды (name и j ul i o) и операции
(=) должны быть доступны команде t e s t в качестве отдельных аргументов. Это
означает, что они должны быть разделены одни м или несколькими символами
пробела.
Вернемся снова к команде, реализующей условный оператор i f. Чтобы выве­
сти по команде echo сообщение "Woul d you 1 i ke to p l a y а game ? " ( Не хотите
ли пои грать?), при условии, что в переменной name содержится символьная стро­
ка " j ul i o " , достаточно написать следующую команду i f:
i f t e s t " $ n ame "
j ulio
then
e c h o " Wo u l d you l i ke t o p l a y
fi
=

а

game ? "

В условном операторе i f выполняется следующая за ним команда и вычисля­
ется код ее завершения. В частности, команде t e s t передаются три аргумента:
переменная name, вместо ссыл ки на которую подставляется ее значение, опера­
ция = и символьная строка " j u l i o " . И тогда в команде t e s t проверяется, равны
ли первый и трети й ее аргументы. Если они равны, возвращает нулевой код за­
вершения, а и наче - ненулевой код завершения.

Кома нда test

171

Затем в условном операторе i f проверяется код завершения, возвращаемый
командой test. Если этот код нулевой, выпол няются команды, находящиеся в
промежутке между операторами then и f i . В дан ном случае выполняется еди н ­
ственная команда e cho. А если код завершения оказывается ненулевым, то ко­
манда e cho пропускается.
Как было показано выше, переменные оболочки, принимающие аргументы ко­
манды t e s t , целесообразно заключать в двойные кавычки, чтобы разрешить по­
становку значен ий этих переменных. Эти м гарантируется, что команда te s t вы­
явит аргумент, даже есл и он при н имает пустое значение. Для иллюстраци и этого
положения рассмотрим следующий пример:
З ада т ь пус то е з на чение пер еменной
$ name=
$ tes t $name
j ul io
s h : t e s t : a rg ume n t e x pe c t e d
$

$namв

=

В данном примере задано пустое значен ие переменной name, и поэтому ко­
манде tes t передано только два аргумента: = и julio. Ведь оболочка подста­
вила значение перемен ной name прежде си нтаксического анализа аргументов в
командной строке. На самом деле после постановки значения переменной name
получается так, как будто набрана следующая команда:
test

=

j ulio

Когда эта команда выполняется, она обнаруживает л и ш ь два аргумента, как
показано на рис. 7. 1 . И поэтому выдается сообщение об ошибке, где извещается,
что ожидаемый аргумент отсутствует.

c:J

аргументы
"_---------


julio

Р ис. 7 . 1 . П роцесс вы полнения команды tes t $nаше
при пустом значен и и переменной $nаше

=

julio

Заключив переменную в двойные кавычки, можно гарантировать, что команда
test о бнаружит аргумент, поскольку двойные кавычки служат "заполнителем"
пустого значения аргумента. Несмотря на то что переменной name присвоено пу­
стое значен ие, команде t e s t передаются три аргумента, причем первый из них
принимает пустое значение, как показано ниже и н а рис. 7.2.
$ tes t " $name " = j ul io
$ echo $ ?
1
$

Выв ести к од з а вершения

172

Гл а в а 7 .

В ы б ор по условию

r::::J·

!�"!."."!'"'null

--

-

- -

=

julio
Р ис. 7 . 2. П роцесс вы пол нен и я кома нды test " $name "
при пустом значен и и переменной $name

julio

Для проверки символьных строк можно применять и другие операции. Все
они перечислены в табл. 7. 1 .
Табл ица

7.1. Стро к о вые о перации в к оманде

tes t

Воз в ра щает нстннный резул ьтат ( н улевой код за вершен и я ) ,

О п ера ци я

есл и
С'1!р0Жа1
С'1!р0Жа1

=

!=

CIJ!POЖa1

CIJ!POжa
-

n

С '1!р0Жа 1

и C!tpoxa1 одинаковы
и CIJ!POXa! не одинаковы
CIJ!POЖa не нулева я
CIJ!POжa не нулевая (и должна быть обнаружена командой te s t)
CIJ!POXa нулева я (и должна быть обнаружена командой tes t)

CIJ!POЖa! CIJ!POЖa1

CIJ!POжa

- z CIJ!POXa

Выше было показано, каким образом применяется операция =. Аналогичным
образом применяется и операция ! =, за исключен ием того, что в ней проверяется
неравенство символьных строк. Это означает, что команда te s t возвращает ну­
левой код завершения, есл и две символьные строки неравны, а есл и они равны ненулевой код завершения. Рассмотрим три сходных примера:
$ day="monday"
$ tes t 11$day11 = monday
$ echo $ ?
О
Истинн о
$

В данном примере команда t e s t возвращает нулевой код завершения, по­
скольку значение перемен ной day равно символьной строке "monda y " . А теперь
при ведем следующий пример:
$ day= "monday"
$ tes t 11$day11
$ echo $ ?
1
$

monday
Ложно

В дан ном примере переменной day присвоены символы monda y и последую­
щий пробельньtй символ. А проверка равенства двух строк в данном случае дает
ложный результат, поскольку символ ьная строка "monda y " не равна символ ьной
строке "monda y " .

Кома нда test

173

Если требуется обеспечить равенство этих строк, следует опустить двойные
кавычки, в которые заключается ссыл ка на переменную. В этом случае оболочка
"поглотит" конечный пробельный символ, и команда t e s t вообще не обнаружит
его, как показано н и же.
$ daya"monday"
$ test $day = monday
$ echo $ ?

О

Истинно

$

И хотя это, по- видимому, нарушает упомянутое выше правило всегда заклю­
чать в двойные кавычки переменные, принимающие аргументы команды t e s t,
тем не менее, опускать двойные кавычки вполне допустимо, если точно известно,
что значение переменной не является пустым (и не состоит только из пробельных
символов).
Чтобы проверить, не является ли значение переменной оболочки пустым,
можно воспользоваться операцией, перечисленной третьей в табл. 7. 1 :
t e s t " $ da y "

Эта команда возвратит истинньt й результат (логическое значение TRUE), если
значение переменной day не является пустым, а иначе ложньtй результат (логи ­
ческое значение FALSE). Двойные кавычки в данном случае не н ужн ы, поскольку
команде все равно, обнаружит ли она вообще аргумент. Тем не менее их лучше
указать. Ведь есл и значение переменной состоит только из пробельных символов,
оболочка исключит аргумент, если он не заключен в двойныекавычки.
-

11
$ Ыanks="
$ test $Ыanks
$ echo $ ?
1
$ test " $Ьlanks "
$ echo $ ?

о

Не пустое ли э то зна чение ?
Ложно - это пустое зна чение
А теперь ?
Истинно - это непустое зна чение

$

В первом случае команде t e s t не было передано никаких аргументов, по­
скольку оболоч ка "поглотила" четыре пробела в переменной Ы an k s . А во вто­
ром случае команде t e s t был передан оди н аргумент, значен ие которого состоит
из четырех пробелов и не является пустым.
Если вам покажется, что мы уделяем здесь сли ш ком много внимания пробе­
лам и кавычкам, и мейте в виду, что именно он и нередко оказываются источн и ­
ком едва уловимых программных ошибок. Рассмотрен ные здесь принципы стоит
твердо усвоить теперь, чтобы застраховаться от многих неприятностей при про­
граммировании в дальнейшем.

17 4

Г11 а в а

7 . В ы б ор по усло вию

Чтобы проверить, является ли символьная строка нулевой, можно также вос­
пользоваться двумя операциями , перечисленными последними в табл. 7. 1 . В част­
ности, операция -n возвращает нулевой код завершения, если указанный после
нее аргумент оказывается непустым. Эту операцию можно рассматривать как
проверку на ненулевую длину аргумента.
А в операции -z проверяется, не является ли пустым следующий после нее
аргумент, и в этом случае возвращается нулевой код завершения. Эту операцию
можно рассматривать как проверку на н улевую длину аргумента.
Таким образом, следующая команда:
test -n " $day "

возвратит нулевой код завершения, если переменная $ day содержит хотя бы
оди н символ. А команда
test

-z

" $ da t a f l a g "

возвратит нулевой код завершения, есл и переменная da t a f l ag н е содержит ни
одного символа. Это означает, что операци и -n и - z противоположны по своему
действию. Обе они существуют лишь для того, чтобы упростить написание услов­
ных операторов и сделать их удобочитаемыми.
Следует, однако, иметь в виду, что в обеих упомянутых выше операциях пред­
полагается обязательное нал и ч ие аргумента. Поэтому возьмите себе за правило
заключать их аргументы в двойные кавычки.
$
$
$
$

nul lva=
nonnul lvar-aЬc
tes t -n "$nul lvar "
echo $ ?

Имее т л и аргумен т nu.l.lvar ненулевую длину ?

1
$ test -n "$nonnul lvar"

Не т , не имеет
А что же а р гуме нт nonnul..l var ?

о

Да , имее т
Имее т ли аргуме нт nul..lvar нул евую длину ?

$ echo $ ?

$ tes t - z " $nul lvar "

$ echo $ ?

о

$ tes t - z " $ nonnul lvar "
$ echo $ ?
1
$

Да , имее т
А что же ар гумент nonnu.l.l var ?
Не т , не имее т

Следует также и меть в виду, что команда t e s t может быть весьма требова­
тельной к своим аргументам. Так, если переменная оболочки s ymЬo l содержит
знак равенства, то любопытно выяснить, что же произойдет, если попытаться
проверить ее на нулевую длину:

Команда test

175

$ echo $ symЬol
$ test - z 11 $ symЬol 11
s h : t e s t : a r g ume n t e x pe c t e d
$

Операция = обладает более высоким приоритетом, чем операция - z , и поэтому
в команде te s t предпри нимается попытка выполн ить проверку на равенство, а
следовательно, в ней предполагается наличие аргумента после операции =. Во из­
бежание подобного рода недоразумен ий многие программирующие на языке обо­
лочки предпочитают писать свои команды t e s t следующим образом:
t e s t X " $ s ymЬo l "

=

Х

Эта команда даст истинный результат, если значение перемен ной s yrnЬ o l ока­
жется пустым, а иначе - ложный результат. Наличие символа Х перед перемен ­
ной syrnЬol не позволяет команде t e s t интерпретировать символы, хранящиеся
в перемен ной s yrnЬo l , как операцию.
Ал ьтернативная форма кома нды tes t

Команда t e s t нередко применяется программирующими н а языке оболочки
в альтернативной, более лаконичной форме [ . Эта форма повышает удобоч итае­
мость условных операторов i f и прочих проверок по условию в сценариях обо­
лочки.
Напомним, что общая форма команды test выглядит следующим образом :
t e s t выражение

Эту же команду можно выразить и в следующей альтернативной форме:
выражение J

Знак открывающей квадратной скобки ( [ ) фактически обозначает наимено­
вание команды. (Как видите, наименования команд могут состоять не только из
букв и цифр!) И в этой форме начинается выполнение той же самой команды
test, � о в такой форме предполагается также наличие знака закрывающей ква­
дратной скобки ( ] ) в конце выражения. После знака [ и перед знаком ] должны
быть указаны пробелы.
Команду te s t из предыдущего примера можно переписать в альтернативной
форме следующим образом :
$ [ -z " $nonnul lvar "
$ echo $ ?

1
$

Г11 а в а 7 . В ы б ор по условию

176

В условном операторе i f альтернативна форма команды t e s t выглядит сле­
дующим образом:
i f [ " $ n ame "
j ulio
then
e c h o "Wou l d y o u l i ke t o p l a y а game ? "
fi
=

Выбор конкретной формы команды t e s t отдается н а ваше усмотрен ие. Мы
же предпочитаем форму [ . . . ] , которая делает программирование на языке обо­
лочки в большей степени подобным программированию на других распростра­
ненных языках, и поэтому именно она будет использоваться в примерах, приве­
ден н ых в остальной части данной книги.
Целоч ислен н ые опе р ации с р ав нен ия

Команда t e s t и меет большой арсенал операци й для выпол нения целоч ислен­
ного сравнен ия. Эти операции сведены в табл. 7.2.
Таблица

7.2. Цеnочисnенные операции сравнен ия в команде

tes t

Воз вращает нстннный резул ьтат ( нулевой код заверш ени я),

О пе рация

есл и

int,
int,
int,
int1
int,
int,

- eq

- ge
-

gt

-le
-lt
-ne

int2
int!
int2
int!
int2
int2

int, равно int!
int, больше или равно int!
int, больше int2
in t, меньше или равно int!
int, меньше int2
int1 не равно int2

Например, в операции -eq проверяется, равны ли два целочислен ных значе­
ния. Так, если имеется переменная оболочки count и требуется выяснить, равно
ли ее значение нулю, достаточно написать следующую команду:
" $ co un t "

-

eq О

]

Аналогичным образом ведут себя остальные целочислен ные операции. Так,
в следующей операции проверяется, является ли значение переменной cho ice
меньши м 5:
" $ ch o i ce " - l t 5

]

А в приведенной ниже команде проверяется неравенство значений перемен­
ных i ndex и max.
[

" $ i nd e x " - n e " $ma x "

Кома нда test

177

И наконец, в следующей команде проверяется, не равно ли нулю количество
передаваемых ей аргументов:
"$#"

О ]

- пе

Следует, однако, иметь в виду, что именно команда t e s t, а не сама оболоч ­
ка интерпретирует значение перемен ной как целочисленное, когда применяется
целочислен ная операция. Таким образом, рассматриваемые здесь целочисленные
операции сравнения действуют независимо от типа перемен ной оболоч ки.
Рассмотрим более подробно отличия строковых и целочисленных операций в
команде te s t на ряде следующих при меров:
$
$
$
$
1
$
$
о
$
$
1
$
$
о
$

х1="00 5 "
х2=" 1 0 "
[ "$xl "
echo $ ?
[ "$xl "
echo $ ?

=

-

5 ]

eq 5 ]

[ "$х2 " ... 1 0 ]
echo $ ?
[ "$х2 " -eq 1 0 ]
echo $ ?

Сра в нение строк
Ложный резуль та т
Сра внею rе целых чи сел
Ис тин ный резуль та т
Сра в нение строк
Ложный резуль та т
Сра в нение целых чисел
Истинньп/ резуль та т

При первой поверке:
"$xl " = 5 ]

применяется строковая операция сравнения = двух символьн ых строк на ра­
венство. Они не равн ы, поскол ьку первая строка состоит из трех символов 0 0 5 ,
а вторая - и з еди нствен ного символа 5 .
При второй проверке применяется целочисленная операция сравнения -eq.
Если ин терпретировать оба сравни ваемых значения как целочисленные, то 0 0 5
,
равно 5, что и подтверждает код завершения команды t e s t .
Третья и четвертая проверки сходны, н о п р и этом можно заметить, к а к на­
личие даже начального пробела в переменной х 2 способно оказать влияние на
результат проверки с помощью строковой операции, в отличие от целочисленной
операци и.
Ф айловые опера ции

Буквально в каждой программе оболочки приходится оперировать одни м
или несколькими файлами. Именно поэтому команда te s t снабжена обшир­
ным рядом операций, позволяющих решать различные задач и манипулирования

178

Гл а в а 7 .

В ы б ор по услови ю

файлами . Каждая из этих операций носит унарный характер, а это означает, что
в н их предполагается еди нственный аргумент. Но в л юбом случае в качестве вто­
рого аргумента служит имя файла, вкл ючая и имя каталога там, где это уместно.
В табл. 7.3 перечислены наиболее употребительные файловые операции.
Таблица

7 . 3 . Наиболее употребител ьные файловые

операции в кома нде te s t
Опера ци я

Воз вра щает нстнннын резул ьтат ( н ул е вой код завершени я ) ,
есл и

-d файл
е

файл

-f

файл

-

- r файл
файл

-s

-w ф айл


файл

-L файл

файл -

эт о катал о г
файл - эт о сущес твующи й файл
файл - это о быкн овенный файл
файл - это доступный для чтения файл
файл - э т о файл ненул е в о й длины
файл - эт о до ступный для запи си файл
файл - э т о исп олняемый файл
файл - э то символическая ссылка

В команде
- f / u s e r s / s t e ve / p h o n eboo k

проверяется, существует ли файл / u s e r s / s teve /phoneboo k и является ли он
обыкновенным, т.е. не специальным файлом или каталогом.
А в приведен ной выше команде проверяется, существует ли указанный файл и
является ли он доступ ным для чтен ия.
- r / u s e r s / s t e ve / p h oneboo k ]

И наконец, по следующей команде:
-s / u s e r s / s t e ve / phoneboo k ]

проверяется, имеет л и указанный файл ненулевое содержимое (т.е. не является
пустым). Это удобно, если сначала создается файл регистрации ошибок, а затем
требуется выяснить, было ли что- нибудь в него записано.
i f [ -s $ ERR F I LE ]
t he n
echo " E r r o r s found : "
c a t $ ERR F 1 LE
fi

В сочетании с описан ными ранее операциями ряд других операций, доступ ­
ных в команде t e s t , позволяет составлять более сложные условные выражения.

Кома нда test

179

Операция логического отри ца н ия !

Унарная логическая операция ! может быть указана перед любым другим вы­
ражением в команде t e s t для отрицания результата вычисления данного выра­
жения. Например, следующая команда:
[

!

-r / u s e r s / s t e v e / ph o n e b o o k ]

возвращает нулевой код завершения (т.е. исти н н ы й результат), если файл
/users / s teve /phoneboo k оказывается недоступным для чтения, а команда
[

!

-f " $ma i l f i l e "

]

возвращает исти нный резул ьтат, если файл, указанный в переменной $ma i 1 f i le,
не существует или не является обыкновенным файлом. И наконец, следующая ко­
манда:
[

!

"$xl "

=

" $ х2 "

]

возвращает истинный резул ьтат, есл и значен ия операндов $ x l и $ х 2 неодинако­
вы, что, очевидно, равнозначно приведенному ниже, более понятному условному
выражению.
[ "$xl "

! = " $х2 "

Операция



]

логическое И

Операция -а выполняет логическую операцию И над двумя выражениями и
возвращает истинный результат (логическое значение TRUE), если оба соеди няе­
мые выражения оказы ваются исти нными. Так, следующая команда:
[

-f " $ma i l f i l e "



-r " $ma i l f i l e "

]

возвращает истинный результат, если файл, указанный в перемен ной $ma i 1 f i le,
является обыкновенным и доступ ным для чтения файлом. ( В дан ном примере
операция - а специально отделена пробелами для повышения удобочитаемости
условного выражен ия, что, очевидно, не оказывает никакого влияния на выпол ­
нение этой операци и.)
А команда
[ " $ c ou n t " -ge О



" $ co un t " - l t 1 0

]

возвратит истинный результат, есл и переменная count содержит целочислен ное
значение, большее или равное нулю, но меньшее 1 0 . Операция -а и меет более
низкий приор итет, чем целоч исленные операции сравнения ( как, впрочем, стро­
ковые и файловые операции). Это означает, что приведенное выше выражение,
очевидно, вычисляется как следующее выражение:
( " $ cou n t " - g e 0 )



( " $ co un t " - l t 1 0 )

180

Гщша 7

В ы б ор по условию

В некоторых случаях важно знать, что команда t e s t сразу же прекращает вы­
ч исление логического выражения И, как только что-нибудь в нем окажется лож­
ным. Так, оператор, подобный следующему:
[

-f

!

" $ f i l e " - а $ ( wh o

>

$ f i le )

]

не будет выполнен в подоболочке с вызовом команды who, есл и проверка ! f
(на несуществование) не пройдет, поскольку команде t e s t уже известно, Что ло­
гическое выражение И (в операции - а) ложно. Это может поставить программи­
рующих на языке оболочки в затруднительное положение, если они попытаются
втиснуть сл ишком много операций в условные выражения, предполагая, что все
они будут выполнены до проверок по услови ю.
-

К ругл ые скобки

В условном выражении команды te s t можно воспользоваться круглыми скоб­
ками, чтобы изменить порядок вычисления требуемым образом. Нужно лишь
экранировать сами круглые скобки, поскольку у них имеется особое назначение в
оболочке. Таким образом, предыдущи й пример применен ия команды te s t мож­
но переписать следующим образом:
\ (

" $ c oun t "

-ge О

\)

-а \ (

" $count " - l t

10 \)

]

Как правило, круглые скобки должны быть отделены пробелами, поскольку в
команде t e s t предполагается обнаружить каждый элемент условного выраже­
ния в качестве отдельного аргумента.
О п ерация



логическое И Л И

Операция -о подобна операции -а, но только она образует логи ческое ИЛИ
из двух выражений. Это означает, что выч ислен ие всего выражения даст истин­
ный результат, если исти нно первое или второе или же оба исходн ых выражения.
- n " $ma i l op t " - о - r $ HOME / ma i l f i l e

Данная команда возвратит истинный результат, есл и значение перемен ной
$ma i l opt не равно нулю или же есл и файл $ HOME /ma i l f i l e доступен для чте­
ния. Операция -о имеет более низкий приоритет, чем операция -а, а это означа­
ет, что следующее выражен ие:
" $а " -eq

О -о " $ Ь " - e q 2 - а " $ с " - e q

10

будет вычислено в команде t e s t как приведен ное ниже выражение.
" $ а " -eq

О -о ( " $ Ь " - e q 2 - а " $ с " - e q 1 0 )

Естествен но, что такой порядок вычислени я можно при необходимости изме­
н ить с помощью круглых скобок следующим образом :
\ (

"$а"

-eq О

-о " $Ь "

-eq

2 \)

-а " $ с " -eq

10

Конструкция else

181

Приоритет выполнения операци й в сложных условных операторах имеет реша­
ющее значение, и поэтому многие программирующие на языке оболочки пользу­
ются вложенными уловными операторами i f, чтобы обойти любые затруднения,
а другие - круглыми скобками, чтобы прояснить порядок интерпретации. Оче­
видно, что допускать порядок интерпретации слева направо весьма опрометчиво!
В примерах, приведенных в данной книге, можно обнаружить немало приме­
ров применения команды t e s t , поскольку практически невозможно написать
даже самую простую программу оболочки без определенного рода условных вы­
ражений. Все операци и, доступные в команде t e s t, сведены в табл. А. 1 1 прило­
жения А к дан ной книге.
К онструкци я e l s e

Конструкция, назы ваемая условным оператором e l se, может быть добавле­
на к условному оператору i f в одноименной команде. Н и же приведена ее общая
форма.
i f кома нд а ,
then
команда
кома нда
e l se
кома нда
команда
fi

В при веденном выше при мере выполняется указан ная кома нда , и выч исля­
ется код ее завершения. Если этот код оказы вается нулевым, выполняется блок
кода, следующий после оператора then, т.е. все команды, находящиеся в проме­
жутке между операторами then и e l se, а блок кода, следующий после оператора
e l se, т.е. все команды, находящиеся в промежутке между операторами e l s e и
f i , игнорируется. Но в л юбом случае может быть выпол нена лишь одна из этих
послед?вательностей команд: первая из н их, если код завершения равен нулю, а
вторая - есл и этот код не равен нулю.
Более лаконично это можно пояснить следующим образом :
i f условие t h e n кома нды е сли 1 1 ст11нныi1_ре зуль та т
_
_
e l s e кома нды если ложный_резул ь та т f i
_
_

А теперь рассмотрим видоизменен ный вариант программы on. Вместо того
чтобы вообще не выводить н ичего, есл и запрошен н ы й пользователь не зареги­
стрирован в системе, программа on должна сообщать пользователю об этом фак­
те. Ниже при ведена третья версия дан ной программы.

182

Гл а в а 7 . В ы бо р по услови ю

$ cat on
#
# Выясни т ь , заре гистриро ван ли указанный пол ь з о ватель
# в системе - версия 3
#
user= " $ 1 "
i f who
theп

1

g rep " л $ u s e r "

>

/ de v / пu l l

echo " $ u s e r i s l ogged о п "
e l se
e c h o " $ u s e r i s п о t l ogged оп "
fi
$

Если пользователь указан в качестве первого аргумента программы on и ко­
манда g rep завершится успешно, на терминал будет выведено сообщение " u s e r
i s l ogged on" (пользоват ель зарегистрирован), а и н аче - сообщение " u s e r i s
n o t l ogged o n " (пользоват ель н е зарегистрирован ):
$ who
Root
c oп s o l e
tty03
Ьаrпеу
fred
t ty04
t ty07
j оаппе
ttyl9
tопу
lulu
t ty2 3
$ on pat
pa t i s п о t l ogged оп
$ on tony
t о п у i s logged оп
$

Кто ра б о та е т в си стеме '!
Ju l
Ju l
Jul
Ju l
Ju l
Ju l

8
в
в

в

8
8

10
12
13
09
08
09

:
:
:
:
:
:

37
38
40
35
30
55

Чтобы превратить созданный на скорую руку прототип в программу, которая
станет полезной на долгое время, целесообразно проверить, передано ли этой
программе правильное кол ичество аргументов. Если же пользователь укажет
неверное количество аргументов, должно быть выведено соответствующее со­
общение об ошибке наряду с сообщением о правильном при менении данной
программы:
$
#
#
#
#
#
#
#

cat on
Выясни т ь , заре гистриро в а н ли указанный пол ь з о в а т е л ь
в системе - версия 4

Выясни т ь ,

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

Конструкция else

183

i f [ " $ # " -ne 1 ]
then
e c h o " I n c o r r e c t n umЬe r o f a r gume n t s "
e c h o " U s a g e : on u s e r "
e l se
user= " $ 1 "

i f who
then

1 g re p " л $ u s e r

"

>

/ de v / n u l l

e c h o " $ u s e r i s l og g e d o n "
else
e c h o " $ u s e r i s n o t l og g e d on "
fi
fi
$

На первый взгляд, в данную программу внесено немало изменений, но самое
главное, что для проверки правильности количества предоставленных аргумен­
тов в нее введен допол нительный условный оператор i f вместо того, чтобы втис­
нуть эту проверку в пару условных операторов e l s e - f i . Если значение пере­
мен ной $ # не равно 1, что соответствует требующемуся кол ичеству аргументов,
то данная программа выводит два сообщения об ошибках. В противном случае
выполняются команды, следующие после условного оператора e l se. Обратите
внимание на то, что в данном случае требуются два условных оператора f i , по­
скольку применяются два условных оператора i f.
Как видите, отступы заметно повышают удобочитаемость данной программы.
Поэтому возьм ите себе за правило употреблять отступы в своих программах, и
вы еще не раз с благодарностью вспомн ите эту нашу рекомендацию, когда ваши
программы станут нам ного сложнее.
Как показано ниже, взаимодействие с конечным пользователем в рассматри­
ваемой здесь версии программы on заметно улуч шилось по сравнени ю с преды­
дущими ее версиями.
$ on
I nco r r e c t n шnЬ e r o f a rg ume n t s
Usage : on u s e r
$ on prisci lla
p r i s c 1 l l a is n o t logged on
$ on j o anne
I n c o r r e c t n шnЬ e r o f a rg ume n t s
Usage : o n u s e r
$

Б ез а ргуме н тов

ОдJi н ар гуме н т
Дв а аргуме н т а

184

l л а в / tmp / p h o n e bo o k
/ tmp / ph o n e b o o k p h o n e boo k
$
"

"

mv

Допустим, что введена следующая команда:
rem S u s a n Topp l e

В этом случае оболочка передаст оба аргумента команде rem из-за отсутствия
кавычек. И тогда программа rem удалит все записи с именем Sus an, указанным в
переменной $ 1 , даже не обращая внимания на то, что пользователь указал слиш­
ком много аргументов.
Таким образом, в любой потенциально деструктивной программе целесоо­
бразно принять меры предосторожности, убедившись в том, что предполагаемое
пользователем действие должно быть согласовано с действием, которое готова
выполн ить дан ная программа.
Одной из первых в программе rem может быть организована проверка пра­
вильности количества аргументов, как это уже быно сделано ранее в программе
оп. Но на этот раз будет использована команда e x i t, чтобы прервать выполне­
ние программы, есл и ей предоставлено неверное количество аргументов:

Конструкц ия elif

185

$ cat rеш
#
# Уд алить абонента и з телефо н н о г о спра воч ни ка - в е р с и я 2
#
if
" $ # " -пе 1 ]
t he n
e c h o " I n co r re c t numЬe r o f a rg ume n t s . "
e c h o " U s a g e : rem n ame "
exi t 1
fi
g rep -v " $ 1 " p h o n e bo o k > / tmp / ph o n e bo o k
m v / tmp /phoneboo k ph o n e bo o k
$ r еш Susan GoldЬerg
Опробова ть программу
I n co r re c t n umЬ e r o f a r gume n t s .
U s a g e : rem n ame
$

Команда exi t возвращает код завершения 1 , чтобы известить о сбое на тот
случай, есл и в какой- н ибудь другой программе потребуется проверить его в ус­
ловном выражении. Можно ли было бы написать приведенную выше программу
с условными операторами i f- e l s e вместо применения команды e x i t ?
Вам решать, пользоваться ли командной e x i t или условными операторами
i f- e l se. Иногда команда e x i t предоставляет более удобный и быстрый вы­
ход из программы, особенно если это делается на ранней стадии ее выполнения.
И она обладает дополнительным преимуществом, исключая потребность прибе­
гать к глубоко вложенным условным выражениям.
К онструк ц ия e l i f

П о мере усложнения программ приходится все чаще прибегать к написанию
вложенных условн ых операторов i f аналогично следующему:
i f кома нда 1
t he n
команда
кома нда

else
i f команда
then
кома нда
кома нда
..

e l se
i f кома нда "
then
кома нда

186

Гл а в а 7 . В ы б ор по услов и ю

кома нда
e l se
кома нда
кома нда
fi
fi
fi

Такая последовательность команд может оказаться полезной, когда требуется
сделать не двой ной, а больший выбор. В таком случае организуется многовари­
антный выбор, причем последний условный оператор e l s e выполняется, если не
удовлетворяется ни одно из предыдущих условий.
В качестве относительно простого примера рассмотрим написание программы
gree t i ng s , выводящей дружественное приветствие " Good mo rn i ng " (Доброе
утро), " Good a fternoon " (Дoбpый день) или " Good eve n i ng " (Добрый вечер)
в зависимости от времени суток. Ради простоты дан ного примера будем считать
утром любой период времени от полуночи до полудня, днем - от полудня до 6
часов после полудня, а вечером - от 6 часов после полудня до полуноч и.
Чтобы написать такую программу, придется выясн ить текущее время суток.
И для этой цели вполне подходит команда date. Ниже приведен резул ьтат ее вы­
полнения.
$ date
Wed Aug 2 9 1 0 : 4 2 : 0 1 E DT 2 0 0 2
$

Формат вывода результата выполнения команды da te фиксирован, и этим
обстоятельством можно выгодно воспользоваться, поскольку время всегда ука­
зывается на позициях символов от 1 2 до 1 9. Хотя в данном случае достаточно из­
влечь значение часа, указываемого на пози циях 12 и 1 3, как показано ниже.
$ date 1
10
$

cut

-

с12 1 3
-

Таким образом, задача написания программы gree t i ngs существенно упро­
щается:
$ cat 9reetin9s
#
# Про грамма дл я вывода п ри в е т с т ви я
#
h o u r = $ ( da t e

1 cut - с 1 2 - 1 3 )

Конструкция elif

i f [ " $ hou r " - g e О -а " $ hou r " - l e 1 1 ]
then
e c h o "Good mo r n i ng "
e l se
i f [ " $ ho u r " -ge 1 2 - а " $ h ou r " - l e 1 7
then
e c h o " Go o d a f t e rn o o n "
e lse
e c h o " Good e ve n i n g "
fi
fi
$

187

]

Если значение переменной $ hour больше или равно О ( полночь) и меньше или
равно 1 1 (до 1 1 : 5 9 : 5 9), то выводится приветствие " Good mo rn i ng " . Если же
значение переменной hour больше или равно 12 ( полдень) и меньше или рав­
но 17 (до 1 7 : 5 9 : 5 9), то выводится приветствие " Good a fte rnoon " . А если
ни одно из предыдущих условий не удовлетворяется, то выводится приветствие
" Good eve n i ng " .
$ 9reetin9s
Good mo rn i n g
$

Если внимательно проанализировать программу gree t i ng s , то станет ясно,
насколько неукл юже выглядит употребляемая в ней последовательность вложен­
ных условных операторов i f - then-e l s e. Для упрощения подобного рода по­
следовательностей в оболочке поддержи вается также специальная конструкция
e l i f, действующая аналогич но конструкции e l se i f условие, за исключением
того, что она не повышает уровень вложенности. Н и же приведена общая форма
этой конструкции.
i f кома нда ,
t he n

кома нда
кома нда
е l i f 1, / de v / n u l l
then
e l se
echo " $ s y s tem i s n o t
exi t 1
fi

а

va l i d s y s t em "

Конструкц и и && и 1 1

199

Если проверка условия проходит, то н и чего делается. А если дан ная проверка
не проходит, то выводится сообщение об ошибке и происходит выход из про­
граммы.
Откровенно говоря, данный кон кретны й пример можно было бы переделать,
изменив на обратную структуру команды g rep (напри мер, воспользовавшись
аргументом ! команды tes t). Но и ногда проще организовать проверку положи­
тельного, а не отрицательного условия, н ичего при этом не делая. Но в л юбом
случае очень полезным оказывается своевременный комментарий , который бук­
вально творит чудеса, когда приходится читать исходный текст программ ы мно­
гие недели, а то и месяцы спустя.
К онструкци и & & и 1 1

В оболочке имеются две специал ьные конструкции, позволяющие выпол нять
последующую команду в зависимости от удачного или неудачного исхода выпол ­
нения предыдущей команды. Н а самом деле эти конструкции подобны условному
оператору i f и просто являются более краткой его формой. Так, если написать
следующее выражение:
кома нда :

&&

к ома нда

любом месте, где в оболочке предполагается обнаружить команду, то выполня­
ется кома нда , . Есл и эта команда возвращает (при удачном исходе) нулевой код
завершения, выполняется кома нда г Есл и же кома нда , возвращает ( при неудач­
ном исходе) ненулевой код завершения, то кома нда2 не вы пол няется и просто
игнорируется.
Так, есл и написать следующее условное выражение:
в

s o r t b i gda t a > / tmp / s o r t o u t & & m v / tmp / s o r t o u t b i gd a t a

то команда mv будет выполнена только при удачном исходе выполнения команды
sort. Следует, впрочем, заметить, что данное выражение равнозначно при веден­
ному ниже условному оператору.
i f s o r, t b i gda t a > / t mp / s o r t o u t
then
mv / tmp / s o r t o u t b i gda t a
fi

А в следующей команде:
-z

" $ E D I TOR" ]

& & E D I TOR= / Ь i n / ed

проверяется значение переменной $ E D I TOR. Если в этой переменной содержится
пустое значение, то ей присваивается значение /Ьin/ ed.

Гll i'Ш (I 7 . В ы б ор по условию

200

Аналогичным образом действует конструкция 1 1 . за исключением того, что
команда, указываемая в ней второй, выпол няется лишь в том случае, если первая
команда возвратит ненулевой код завершения. Так, есл и написать следующее ус­
ловное выражение:
g r e p " $ n ame " phonebo o k

1 1

e c h o "Cou ldn ' t f i nd $ n ame "

то команда e cho будет выпол нена лишь при неудач ном исходе выполнения ко­
манды grep, т.е. в том случае, если значен ие перемен ной $narne не удастся найти
в файле phoneboo k. И это выражение равнознач но при веденному н иже условно­
му оператору.
i f g r ep " $ name " phonebo o k
then
e l se
echo " Cou l dn ' t f i nd $ n ame "
fi

В левой или правой части этих конструкций можно указать сложные последо­
вательности команд. В левой части этих конструкций проверяется код заверше­
ния последней команды в кон вейере. Следовательно, в приведен ном ниже услов­
ном выражении команда e cho выполняется лишь при неудачном исходе выпол­
нения команды g rep.
who

1

grep " л $ n ame

"

>

/ de v / n u l l

1 1

echo " $ n ame ' s n o t l ogged on "

Конструкции & & и 1 1 можно также объеди нять в одной командной строке, как
демонстрируется в следующем примере:
who

1

1 1

grep " $ n ame " > / d e v / n u l l & & echo " $ n ame ' s not l ogged o n " \
e c h o " $ n ame i s l og g e d on "
л

( Напомним, что н ал и ч ие знака \ в конце строки сигнализирует оболоч ке о
продолжении строки.) Первая команда e cho выполняется при удачном исходе
выполнения команды grep, а вторая - при неудачном.
Эти конструкции нередко применяются и в условных операторах i f, как де­
монстрируется в следующем фрагменте кода из программы системной оболочки
(в этом фрагменте обратите больше внимания на применение конструкции & &,
чем на вызываемые команды):
i f va l i d s y s " $ s y s " & & t ime o k
then
sendma i l " $ u s e r @ $ s y s " < $me s s a g e
fi

Конструкц и и && и 1 1

201

Есл и команда va l idsys возвращает нулевой код завершения, выполняется
команда t imeo k и далее проверяется код ее завершения в условном операторе
i f. Если этот код завершения оказывается нулевым, то выполняется команда
sendma i l . А если команда va l i ds ys возвращает ненулевой код завершения, то
команда t imeo k не выполняется, далее в условном операторе i f проверяется код
неудач ного завершения и в конеч ном итоге команда se ndma i l также не выпол­
няется.
Конструкция && в предыдущем примере обозначает логическую операцию И.
Обе команды, указанные в условном операторе i f, должны возвратить нулевой
код завершения, чтобы была выполнена и команда s e ndma i l . На самом деле
приведенный выше фрагмент кода можно было бы написать следующим образом:
v a l i d s y s " $ s y s " & & t imeo k & & s endma i l " $ u s e r @ $ s y s "

<

$me s s a g e

С другой стороны, наличие конструкци и 1 1 в условном операторе i f обозна­
чает логическую операцию ИЛИ, как показано н и же.
i f endo fmon t h 1 1 spe c i a l reque s t
then
s end r e p o r t s

fi

Если команда endo fmonth возвращает нулевой код завершения, то выпол­
няется команда spe c i a l reque s t . А если она возвращает ненулевой код за­
вершения, то выполняется команда s e ndrepo r t s . Таким образом, команда
sendrepo rts выполняется, если нулевой код завершения возвращает команда
endo fmonth или spe c i a l reque s t.
Из главы 8 вы узнаете, как организовать сложные циклы, управляющие ходом
выполнения программы. Но прежде поупражняйтесь в применении операторов
i f, case и конструкци й & & и 1 1 , пояснявшихся в этой главе.

П овт о р н ое вып ол нен и е
коман д
В этой главе реч ь пойдет об организаци и программных циклов, позволяющих
выполнять ряд команд указан ное количество раз до тех пор, пока не будет удов­
летворено кон кретное конеч ное условие. Для орган изаци и программных ци клов
в оболоч ке предоставля ются перечисленные ниже команды. Они рассматри вают­
ся по отдельности в соответствующих разделах этой главы.

for

wh i l e

unt i l
К о м а нда fo r

Команда for служит для выполнения одной и л и нескольких команд указан­
ное количество раз. Ниже приведена общая форма этой команды, реализующей
оператор цикла for.
t· a r
do

va r

i n сло в о . сло в о . . .

сло в о "

кома нда
к ома нда

done

Команды , указанные в промежутке между операторами do и done, назы вают­
ся телом цикла и выполняются столько раз, сколько указано после оператора in.
В начале цикла первое слово, присваи вается переменной ци кла var и далее вы­
полня�тся тело ци кла. Затем переменной цикла va r присваивается второе сло ­
в о2 и тело цикла вы полняется снова.
Этот процесс продолжается до тех пор, пока переменной не будет присвоено
последнее сло в о", а тело ци кла - выпол нено в последний раз. После этого слов в
сп иске больше не остается, и на этом цикл for завершается. Вслед за эти м сразу
же выполняется оператор done.
Есл и в операторе i n перечислено п слов, тело цикла будет выполнено в общем
п раз, после чего цикн завершится. Ниже при веден пример цикла, выполняюще­
гося три раза.

204

f i1 o в a Н. Повторное вы пол нение кома нд

for i i n 1 2 3
do
echo $ i
done

Чтобы опробовать этот цикл, наберите его непосредственно на терми нале ана­
логично любой другой команде оболочки, как показано ниже.
$ for i in 1 2 3
>

do

>
>

done

echo $ i

1
2

3
$

В ожидании ввода оператора done для завершения цикла for оболоч ка про­
должает выводить вспомогательное приглашение на ввод команд. Как только
пользователь введет оператор done, оболочка продолжит выполнение ци кла.
В данном примере после оператора in указаны три элемента (значения 1, 2 и З),
и поэтому тело цикла (в данном случае - единственная команда e cho) будет вы­
полнено в общем три раза.
Сначала переменной цикла i присваивается первое значение 1 из списка. Затем
тело цикла выполняется первый раз. При этом значение переменной цикла i вы­
водится на терми нал. Затем переменной цикла i присваивается второе значение 2,
и команда e cho выполняется снова, выводя это значение на терминал. Далее пере­
менной цикла i присваи вается третье значение З, и команда echo выполняется
в третий раз, выводя это значение на терминал. В этот момент в списке больше
не остается слов, поэтому выполнение цикла for завершается. После этого обо­
лочка выводит приглашение на ввод команд, уведомляя о том, что цикл завершен.
А теперь вернемся к примеру программы run, рассматривавшейся в главе 6
и позволявшей обработать файл в последовательности команд tЫ, nro f f и lp:
$ cat run

tЫ $ 1

1 n ro f f

-mm

-Tlp

1 lp

$

Если же требуется обработать несколько файлов ( например, rnerno l -rnemo 4 ),
то на терминале можно набрать следующий цикл:
$ for file in memol memo2 memoЗ memo4
>

do

>

done
requ e s t
reque s t
reque s t
requ e s t

run $file

>

$

id
id
id
id

is
is
is
is

laserl-33
lase r l - 3 4
l aser l - 3 5
lase r l - 3 6

( s t a nd a r d
( s tandard
( s tandard
( s t a пd a r d

i n pu t )
i n pu t )
i n pu t )
i n pu t )

Кома нда for

205

Переменной ци кла f i l e по очереди присваиваются значения memo l , memo2 ,
memoЗ и memo 4 , и программа r u n выполняется со значением этой переменной в
качестве аргумента. Выполнение данного цикла будет осуществлено так, как буд­
то был и введены четыре команды подряд:
$ run memol
reque s t i d i s
$ run memo2
reque з t i d i s
$ run memoЗ
reque s t i d i s
$ run memo4
reque s t id i s
$

laser l-33

( s t anda rd i npu t )

laser l-34

( s t a nda rd i npu t )

l a se r l - 3 5

( s t anda rd i n pu t )

lase r l - 3 6

( s t anda rd i npu t )

В оболочке допускается подставлять и мена файлов из списка слов, указанного
в операторе for. Таким образом, предыдущи й цикл можно переписать следую­
щим образом:
f o r f i l e i n memo [ l - 4 )
do
run $ f i l e
done

Если по команде run требуется вывести все файлы из текущего каталога, для
этого достаточ но набрать следующий цикл:
for f i l e i n *
do
run $ f i l e
done

Чтобы выполнить более сложное действие, допустим, в файле f i l e l i s t со­
держится список файлов, которые требуется обработать по команде run, доста­
точ но ввести следующий цикл:
f i l e s = $ ( ca t f i l e l i s t )
f o r f i l e in $ f i l e s
do
run $ f i l e
done

или более лакон ично:
for f i l e in $ ( c a t f i l e l i s t )
do
run $ f i l e
done

206

Гп а в а 8 . Повторное в ыполнен ие команд

В качестве дальнейшего совершенствования можно внести соответствующие
коррективы в саму программу run, и оператор f o r идеально подходит для дан ­
ной цели, как показано н и же.
$ cat run
#
# Обра бо т а т ь фа йлы по кома нде n r o f f - - в е р с и я 2
#

fo r f i l e i n $ *
do
tЫ $ f i l e
done
$

1 n ro f f - rom - T l p 1 l p

Напомним, что специальная перемен ная оболоч ки $ * обозначает все аргумен­
ты, введенные в командной строке. Если выполн ить новую версию программы
run, введя в командной строке следующее:
run memol memo2 memoЗ memo4

то список, сохраняемый в переменной оболочк и $ * для цикла for, будет заменен
введенными аргументами rnerno l , rnerno2 , rnerno З и rnerno 4 . Разумеется, для полу­
чения тех же самых результатов можно было бы ввести следующее:
run memo [ l - 4 ]

П еременная $ @

Раз у ж мы коснулись переменной $ * , рассмотрим более подробно, каким об­
разом действует она и родственная ей переменная $ @ . С этой целью рассмотрим
следующую программу a r g s , отображающую в отдельных строках все аргумен­
ты, введенные в командной строке:
$ cat args
echo NumЬe r o f a r gume n t s pa s s ed i s $ #
for arg in $*
do
echo $arg
done
$

А теперь опробуем эту программу следующим образом:
$ args а Ь с
NumЬe r o f a rg ume n t s p a s s e d i s 3
а

ь
с

Команда for

207

$ args ' а ь · с
NumЬ e r o f a r g umen t s pa s sed i s 2
а

ь
с

$

Проанализируем более подробно второй из приведенных выше примеров.
Несмотря на то что строка ' а Ь ' была передана программе a r g s как еди н ы й
аргумент, о н а все равно разби вается на два аргумента в ци кле for. Именно по­
этому переменная $ * заменяется в операторе ци кла for списком значен и й а Ь
с, а кавычки при этом отбрасываются. Так и м образом, ци кл fo r выполняется
три раза.
Оболоч ка заменяет значение перемен ной $ * значен иями аргументов $ 1 , $ 2
и т.д" но есл и вместо нее воспол ьзоваться специал ьной переменой оболоч ки
" $ @ " , то программе будут передан ы значен ия " $ 1 " , " $ 2 " и т.д. Главное отл и ­
ч и е состоит в том, что перемен ная $ @ закл ючается в двойн ы е кавычки, в отсут­
ствие которых она действует таким же образом, как и переменная $ *. Вернемся
к программе a r g s и заменим переменную $ * без кавычек перемен ной " $ @ "
в кавыч ках:
$ cat args
echo N wnЬe r o f a r gume n t s pa s s ed i s $ #
for arg i n " $ @ "
do
echo $ a rg
done
$

А теперь опробуем эту программу еще раз:
$ args а Ь с
NumЬ e r o f a rg ume n t s p a s s e d i s З
а

ь
с

$ args ' а ь · с
NwnЬ e г o f a rg ume n t s p a s s e d i s 2
а

Ь

с

Опробова ть про rр амму без ар гументов
$ args
NumЬ e r of a rg ume n t s p a s sed is О
$

В последнем случае программе не было передано н и одного аргумента, и по­
этому переменную " $ @ " нечем было заменить. А в конечном счете тело цикла так
и не было выполнено.

208

Г11 а в а 8. Повторное в ы полнение команд

Ц и кл for без списка

При организации циклов for оболочка распознает особое обозначение. Так,
есл и опустить оператор i n и следующий после его сп исок, как показано ниже,
оболочка воспримет последовательно все аргументы, введенные в командной
строке.
f o r va r
do
кома нда
кома нда
done

Это все равно, что составить следующий цикл:
f o r va r i n " $ @ "
do
кома нда
кома нда
done

Если принять во вн и мание эту особенность орган изации циклов for, то тре­
тью и последнюю версию программы a r g s можно написать и опробовать следу­
ющим образом :
$ cat args
echo NumЬe r o f a rgumen t s pa s s ed i s $ #
for arg
do
echo $arg
done
$ args а Ь с
N umЬe r o f a rg umen t s p a s s e d i s 3
а
ь

с

$ args ' а ь · с
N umЬ e r o f a rg umen t s p a s s e d i s 2
а Ь
с

$

К о м а нда whi le

Второй для организаци и ци клов является команда, реализующая оператор
whi l e. Ниже приведена его общая форма.

Ком а нда while

209

wh i l e кома нда ,
do
кома нда
команда
done

В цикле wh i l e выполняется кома нда, и проверяется код ее завершения. Есл и
этот код нулевой, то выполняются команды, находящиеся в промежутке между
операторами do и done и образующие тело данного цикла. Затем кома нда, вы­
полняется снова и опять проверяется код ее завершения.
Если этот код нулевой, то тело цикла whi l e выполняется снова. Этот процесс
продолжается до тех пор, пока кома нда, не возвратит ненулевой код своего за­
вершения, и тогда данный цикл завершится. А выполнение продолжится с коман ­
ды, следующей после оператора done.
Следует, однако, иметь в виду, что команды, находящиеся в теле цикла wh i le,
т.е. в промежутке между операторами do и done, могут быть так и не выполнены,
есл и кома нда , возвратит ненулевой код своего завершения после первого же вы­
полнения. Ниже приведена программа twhi le, где производится простой под­
счет до 5.
$ cat twhile
i=l
wh i l e [ " $ i " - l e 5 ]
do
echo $ i
i=$ ( ( i + 1 ) )
done
$ twhile

Выпол н1 1ть э ту програ мму

1
2
3

4
5
$

В перемен ной ци кла $ i первоначально устанавливается значение 1 . Затем
начинае'тся цикл wh i l e, где при удачном исходе проверки выполняется блок
кода, образующий тело дан ного цикла. Оболоч ка продолжает выполнение цикла
wh i l e до тех пор, пока значение переменной цикла $ i будет меньше или равно 5.
В самом теле цикла значение его переменной $ i выводится на терминал и увел и ­
чивается на един и цу.
Цикл wh i l e нередко применяется в сочетании с командой s h i ft для обра­
ботки неизвестного количества аргументов, введенных в командной строке. Рас­
смотрим в качестве примера следующую программу, называемую prargs и вы ­
водящую каждый аргумент в отдельной строке:

210

Гл а в а 8 .

Повторное в ыполнение команд

$ cat prargs
#
# В ы в е с т и а р гуме н ты кома ндно й с т ро ки в о тдел ь ных стр о ка х
#
wh i l e
do

[ " $ # " -ne О ]
echo " $ 1 "
shi ft

done
$ prargs а Ь с
а
ь

с

$ prargs ' а ь · с
а Ь
с

$ prargs *
addre s s e s
i n t ro
l o t s a sp a c e s
n ame s
nu
n umЬe r s
phonebo o k
stat
$ prargs
$

Б ез ар гументов

До тех пор, пока количество аргументов не равно нулю, значение переменной
оболочки $ 1 выводится на терми нал, а затем вызывается команда shi ft, сдвига­
ющая значения переменных оболоч ки (т.е. значение перемен ной $2 - в перемен­
ную $ 1 , значение переменной $3 - в переменную $ 2 и т.д.), а также уменьшаю­
щая на еди н и цу значение переменной $ # . Как только будет выведен и сдви нут по­
следний аргумент, значен ие перемен ной $ # станет равным нулю, и в этот момент
цикл whi l e заверш ится. Следует, однако, иметь в виду, что есл и не предоставить
программе prargs н и каких аргументов, то команды e cho и s h i ft так и не будут
выполнены в теле цикла wh i l e, поскольку в самом его начале значение перемен­
ной $ # равно нулю.
К о м а нд а until

Цикл wh i le выполняется до тех пор, пока проверочное выражение продол ­
жает возвращать нулевой код завершения ( TRUE). Совсем иначе действует цикл
unt i l . Он продолжает выпол нять блок кода в своем теле до тех пор, пока прове­
рочное выражение возвращает ненулевой код завершения, и прекратит выполнять
этот блок кода, как только возвратится нулевой код завершения. Ниже приведена

Кома нда u ntil

211

общая форма команды, реал изующей цикл unt i l . Как и в цикле whi l e, коман­
ды, находящиеся в теле ци кла unt i l , т.е. в промежутке между операторами do
и done, могут быть так и не выполнены, если команда, возвратит нулевой код
своего завершения при первом же выполнении.
u n t i l кома нда ,
do

кома нда
к ома нд а
done

Несмотря на внешнее сходство обоих ци клов, команда, реализующая цикл
unt i l , чаще всего применяется для написан ия программ, ожидающих наступле­
ния определенного события. Допустим, требуется выяснить, зарегистрировался
ли пользователь sandy в системе, поскольку ему необходимо передать нечто важ­
ное. С этой целью данному пользовател ю можно было бы послать сообщение по
электронной почте, ноизвестно, что он привык ч итать свою почту в конце дня.
Чтобы выяснить, зарегистрировался ли пользователь s andy в системе, можно
воспользоваться программой on, упоми навшейся в главе 6:
$ on sandy
s a n d y i s n o t l og g e d o n
$

Это простой, но неэффективный способ, поскольку данная программа вы пол ­
няется только раз. Ее можно было бы, конечно, выполнять периодически в тече­
ние дня, но это не очень удобно. Поэтому лучше написать отдельную программу
для постоян ной проверки регистрации нужного пользователя в системе!
Допустим, такая программа называется wa i t fo r и принимает в качестве един ­
ственного аргумента и м я пользователя, вход которого в систему требуется кон­
тролировать. Но вместо того чтобы непрерывно проверять, зарегистрировался ли
нужный пользователь в системе, это можно делать лишь один раз в минуту. И для
этого достаточно воспользоваться командой s l eep, приостанавливающей выпол­
нение программы на указанное количество секунд. Так, следующая команда:
s l eep

п

приостанавли вает выполнение программы на п секунд. А по истечении заданного
интервала времени программа возобновит свое выпол нение с того места, где она
была приостановлена, т.е. с команды, следующей сразу же после команды s l eep:
$ cat wai tfor
#
# Ожи да т ь до т е х п о р , по к а ука з а н н ый по л ь з о в а т е л ь
# н е з аре ги с т р и ру е т с я в с и с т е ме
jj

212

Гл u в u 8. Повторное в ыполнение команд

i f [ " $ # " пе 1 ]
theп
e cho " U s a ge : wa i t f o r u s e r "
exit l
fi
u s e r= " $ 1 "
#
# Про в е р я т ь каждые 6 0 с е кун д , заре ги с т риро в ал с я ли
# ука з а нн ый п ол ь зо в а тел ь в с и с теме
#
-

u п t i l who 1 g re p " л $ u s e r
do
s l e ep 6 0
dопе

"

>

/ de v / n u l l

#
# Если п р о грамма дойде т до э то г о м е с т а , з н а чи т ,
# у к а з а н н ый пол ь з о в а т е л ь з а р е гис триро в а л с я в си с теме
#
e c h o " $ u s e r h a s l ogged оп "
$

После того, как будет проверено, что программе предоставлен только оди н ар­
гумент, значение переменной $ 1 , хранящей этот аргумент, присваивается пере­
менной u s e r . Затем начинается цикл unt i l , который будет выполняться до тех
пор, пока команда grep не возвратит нулевой код завершения, т.е. до того момен­
та, когда указанный пользователь зарегистрируется в системе. А до тех пор, пока
он не войдет в систему, тело цикла unt i l (т.е. команда s l eep) будет продолжать­
ся, приостанавли вая всякий раз выпол нение программы на 60 секунд. По истече­
н и и заданного промежутка времени в одну м инуту снова вызывается конвейер
команд, указанный после команды unt i l , и весь процесс повторяется снова.
По окончании цикла unt i l , свидетельствующего о том, что нужный пользо­
ватель зарегистрировался в системе, на терминал вы водится соответствующее со­
общение. И на этом дан ная программа завершается, как показано ниже.
$ wai tfor sandy
s aпdy h a s l og g e d оп
$

Про ходит вр емя

Разумеется, вы пол нять программу wa i t f o r так, как показано выше, не
очень практи ч но, поскольку она связывает терми нал до тех пор, пока пользова­
тель s andy не войдет в систему. Поэтому дан ную программу лучше выполнять
в фоновом режиме, чтобы пользоваться терминалом для других видов работ.
С этой целью программу wa i t fo r можно запустить на выполнение следующим
образом:

Кома нда u пtil

$ wai tfor sandy &
[ 1 ] 4 3 92
$ nro f f
s a nd y h a s L og g e d

213

Выполннть программу в фонов ом режиме
Номер зада ння 1 1 ндентифнка тор пр оце с с а
ВЫПОЛНl /ТЬ другую ра боту
оп

Это со бытие происх од и т некоторо е время спустя

Теперь можно выполнить другую работу. А программа wa i t for продолжит
свое выполнение в фоновом режиме до тех пор, пока пользователь sandy не во­
йдет в систему или текущий пользователь не выйдет из нее.
П ри меча н ие

По умолчан и ю все процессы а втоматически заверша ются , когда в ы в ыходите из системы .
Есл и же требуется . что б ы п рогра м м а п родолж ила свое в ы п ол нен ие после того , как вы вы­
йдете из системы . можете за пустить ее с помощью ком а нды nohup ил и за план и ровать ее
вы полнен ие по команде at ил и cron. За дополн ител ьной справкой обра щайтесь к руко­
водству пользователя вашей системы U п ix.

Программа wa i t for проверяет факт регистрации нужного пользователя в
системе лишь оди н раз в ми нуту, и поэтому она не потребляет много системных
ресурсов на свое выполнение. Это соображен ие очень важно принимать во вни­
мание, выполняя программы в фоновом режи ме.
К сожалению, после того, как указанный пользователь войдет в систему, впол­
не возможно, что соответствующее уведомление об этом в одной строке будет
пропущено. Так, есл и вы редактируете файл в экранном редакторе вроде v i , со­
общение, извещающее о регистрации нужного пользователя в системе, может
превратить изображение на экране в полный беспорядок, и прочитать это сооб­
щение так и не удастся !
Поэтому сообщение, извещающее о регистраци и нужного пользователя в си­
стеме, лучше отправить самому себе по электронной почте. А еще лучше предо­
ставить пользователю программы wa i t for возможность выбрать вариант от­
правки извещающего сообщения по электронной почте. Если выбран и менно
такой вариант, программа должна указывать, что сообщение будет отправлено по
электрон ной почте, а иначе - выведено на терми нал. С этой целью в следующей
версии программы wa i t for добавлен параметр -m:
$ cat wai tfor

#
# Ожи да т ь до т е х по р , п о ка у ка з а нн ьм пол ь з о в а тел ь
# не з аре ги с т ри ру е т с я в с и с т еме - в ерси я 2
#
if

"$ 1 "

=

-m ]

t h en
ma i l op t =TRUE
shi ft
e l se
ma i l o p t = FA L S E
fi

214

Гл а в а 8 . П о вторное выполнен ие команд

i f [ " $ # " -eq О -о " $ # " -gt 1 J
then
e c h o " U s a g e : wa i t fo r [ -m ] u s e r "
e c h o " - m mea n s t o Ье i n f o rme d Ь у ma i l "
ex i t 1
fi
user= " $ 1 "
#
# Про в е р я т ь каждую ми н уту , заре ги стриро ва л с я ли
# ука з а н н ый п ол ь з о ва т ел ь в с и с т еме
#
un t i l who 1 g r e p n л $ u s e r " > / d e v / n u l l
do
s leep 60
done
#
# Если пр о грамма дойдет до эт о го ме с т а , з на чи т ,
# у к а з ан н ый п о л ь з о ва т ел ь заре ги стриро в а л с я в с и с теме
#
if
" $ma i l op t " = FALS E ]
then
e c h o " $ u s e r h a s l ogged o n "
e l se
e c h o " $ u s e r h a s l ogged o n "
fi
$

1

ma i l s t eve

При первой проверке в данной программе выясняется, был ли указан пара­
метр -m. Если он был указан, переменной ma i l opt присваивается логическое
значение TRUE, а затем выполняется команда s h i ft, выполняющая сдвиг перво­
го аргумента с именем контролируемого пол ьзователя в переменную $ 1 и умень­
шающая на единицу значение переменной $ #. Если же параметр -m не был ука­
зан, переменной ma i l opt присваивается логическое значение FALSE.
Выполнение программы продолжается далее таким же образом, как и в преды­
дущей ее версии, за исключением того, что на этот раз по завершении основного
блока кода проверяется значение перемен ной ma i lopt, чтобы выяснить, куда
именно направлять извещающее сообщение: по электронной почте или на терми­
нал по команде e cho. Н и же демонстрируется при менение программы wa i t for
в новой версии.
$ wai tfor sandy m
U s age : wa i t fo r [ -m ] u s e r
- m me a n s t o Ье i n f o rmed Ь у ma i l
$ wai tfor -m sandy &
( 1 ) 54 35
-

Кома нда u ntil

$ vi newmemo

215

Продолжить ра б о ту

you have ma i l
$ ma i l
rrom s t e ve Wed Aug 2 8 1 7 : 4 4 : 4 6 E DT 2 0 0 2
sandy h a s l ogged о п
?d
$

Разумеется, программу wa i t fo r можно было бы написать таким образом,
чтобы она принимала параметр -m в качестве первого или второго аргумента.
Но в тради цион ном си нтаксисе Unix все параметры должны непременно предше­
ствовать любым другим типам аргументов в командной строке.
Следует также иметь в виду, что в прежней версии программу wa i t for мож­
но было бы выполнить следующим образом :
$ wai tfor sandy 1 ma i l s teve &
[ 1 ] 5522
$

чтобы добиться такого же результата, как и с помощью дополнительного параме­
тра -m, хотя это и менее изящный вариант.
В текущей версии дан ная программа всегда посылает извещающее сообщение
по электрон ной почте адресату s t eve, что не особен но практично для какого­
нибудь другого ее пользователя. Поэтому лучше определить сначала пользова­
теля, выполняющего данную программу, а затем отправить ему извещающее со­
общение по электрон ной почте, если он укажет параметр -m. Но как это сделать?
С этой целью можно, например, выполн ить сначала команду who с параметрами
am i и получить в ответ имя текущего пользователя, а затем извлечь его по ко­
манде cut из результата, вы води мого командой who, чтобы воспользоваться им в
качестве имени получателя электронной почты.
Все это можно сделать в последнем условном операторе i f, внеся приведенные
ниже изменения. Теперь программу wa i t fo r сможет выполн ить любой пользо­
ватель, и он получ ит извещающее сообщение по своему правильно определенно­
му имен и адресата электронной почты.
i f [ " $ # " -eq 1 ]
then
echo " $ u s e r has l og g e d о п "
e l se
r e c i p i e n t = $ ( wh o am i 1 c u t - c l - 8 )
echo " $ u s e r h a s l og g e d о п " 1 ma i l $ re c i p i e n t
fi

216

Гл а в а �. П овторное вы пол нение команд

Доп ол н ител ьн ые сведен и я о ц и кл ах

В последующих разделах рассматри ваются дополнительные возможности ор­
ганизации ци клов.
П реры вание ц и кла

Иногда логи ка выполнения программы ди ктует немедленный выход иЗ цикла.
Чтобы выйти из ци кла, но не из самой программы, достаточ но указать в теле цик­
ла следующую команду:
b rea k

Когда выполняется команда bre a k, управление немедленно передается за пре­
делы цикла, где выполнение программы продолжается обычным образом. Таким
способом можно, в частности, воспользоваться для прерывания бесконечного
цикла, т.е. такого блока кода, который п редназliачен для бескоliеч ноrо выпол­
нения одli их и тех же команд до тех пор, пока оно не будет прервано командой
brea k.
В подобн ых случаях можно воспользоваться командой t rue, чтобы возвра­
тить нулевой код завершения, и командой fa l s e - в противоположной ситуа­
ции, чтобы возвратить ненулевой код завершения. Так, есл и написать следующий
цикл wh i l e:
wh i l e t r ue
do

done

он будет выполняться бесконечно, поскольку команда true всегда возвращает
нулевой код завершения.
А команда f a l s e всегда возвращает ненулевой код завершения, и поэтому
следующий цикл unt i l :
u n t i l fa l s e
do
done

будет также выполняться бесконеч но.
Таким образом, команда brea k применяется для выхода из подобного рода
бесконеч ных ци клов. Как правило, это делается при обнаружении ошибоч ного
условия или окончан ия обработки, как демонстрируется в следующем примере:
wh i l e t r u e
do

cmd= $ ( ge t cmd )

Дополнительн ы е сведени я о ци клах

if

[ " $ crnd "

217

qu i t ]

brea k
e l se
p r o c e s s crnd " $ crnd "
fi
done

В данном примере цикл wh i l e будет продолжать выполнение команд g e t cmd
и proce s s cmd до тех пор, пока значение перемен ной cmd не станет равным
qui t . Именно в этот момент будет выполнена команда brea k, что приведет к
окончанию дан ного ци кла.
Если команда brea k применяется в следующей форме:
brea k

п

то происходит немедлен ный выход из
зом, в следующем примере:

п

самых внутренн их ци клов. Таким обра­

. for f i le
do
wh i l e
do

[

" $ c ou n t "

-

lt 10 ]

i f [ -n " $ e r ro r "
then
brea k 2
fi
done
done

циклы wh i l e и for будут прерваны, если значение перемен ной e r ror окажется
непустым.
П ро пуск ил и оставление команд в цикле

Ко � анда cont i nue подобна команде brea k, но она не приводит к прерыва­
нию цикла, а только оставляет команды на текущем шаге цикла, пропуская его.
В этом случае выполнение программы сразу же переходит к следующему шагу
ци кла, выполняя его, как обычно. Как и в команде b r e a k, в команде con t i nue
может быть указано дополнительное число n:
con t i nue

п

которое обозначает пропуск команд в самых внутренних циклах, после чего вы­
полнение программы продолжается обычным образом:

218

Гл а в а 8. Повторное в ы пол нен ие ком а нд

for f i le
do
if
then

!

-е " $ fi le "
e c h o " $ f i l e not found ! "
con t i nu e

fi

#
# Обра бота т ь файл
#

done

В дан ном примере каждое значение из списка, хранящегося в переменной
$ f i le, проверяется на предмет существования файла. Есл и файл не существу­
ет, выводится соответствующее сообщение, и дальнейшая обработка файла про­
пускается. Цикл продолжает выполняться со следующего значения в указанном
списке.
Код из приведен ного выше примера равнозначен написанию следующего
фрагмента кода:
for f i l e
do
if
then

!

-е " $ f i l e "
e c h o " $ f i l e n o t found ! "

e l se

#
# Обра бота 1ъ файл
#

fi
done

В ы пол нение ц и кла в фоновом режи ме

Выполнение всего цикла может быть перенесено в фоновы й режим. Для этого
достаточно указать знак & после оператора done, как показано ниже.
$ for file in memo [ l - 4 )
>

do

run $file
done &
( 1 ) 9932

>
>

$
reque s t i d i s l a s e r l - 8 5

Перенести выполнен и е цикла в фонов ый р ежим

( s t a n d a r d i np u t )

Дополн ител ь н ые сведен ия о ци клах

r e que s t id is l a s e r l - 8 7
reque s t i d i s l a s e r l - 8 8
reque s t i d i s l a s e r l - 9 2

219

( s t anda rd i np u t )
( s t anda r d i n p u t )
( s t a nda r d i n p u t )

Этот и последующие примеры вполне работоспособны, поскольку оболочка
интерпретирует циклы как отдельные мини- программы. И все, что следует после
таких операторов, закрывающих блок кода, как, например, done, fi или e s a c,
может быть перенесено на выполнение в фоновый режим с помощью знака & или
даже частичной формы организаци и конвейера команд.
В следующем при мере весь вы вод переадресовы вается из цикла в файл
output, за исключен ием результата, выводимого из команды e cho, который на­
правляется непосредственно на терми нал:
for f i le
do
e c h o " P r o ce s s i ng f i l e $ f i l e " > / d e v / t t y
done > o u t p u t

Стандартный вывод ошибок можно также переадресовывать из цикла. Для
этого достаточно указать форму переадресации 2> имя_ файла после оператора
done, как показано н и же. В данном примере стандартн ы й вывод ошибок из всех
команд будет переадресован в файл e r rors.
wh i l e
do

[ " S e ndo fda t a " - n e T R U E ]

done 2 > e r ro r s

Для вывода сообщени й об ошибках на терминал даже в том случае, если их
предполагается переадресовы вать в файл или канал, служит следующая разно­
видность формы переадресации 2 >:
echo " E r ro r :

no f i l e " 1 > & 2

П о умолчанию команда e cho направляет результат своего выполнения в стан­
дартнь1й вы вод (с дескри птором файла 1), тогда как дескриптор файла 2 остается
для вывода ошибок, который умолчанию не подлежит переадресации в файлы
или каналы. Таким образом, приведенное выше обозначение означает, что со­
общение об ошибке, выводимое командой e cho, должно быть переадресовано из
"файла # 1 " в " файл #2': т.е. в стандартный вывод. В этом можно убедиться, вы­
полнив следующий фрагмент кода:
for i
do

in " o n c e "

e c h o " S t a n d a r d o u t p u t me s s ag e "
e c h o " E r ro r me s s ag e " 1 > & 2
done > /de v / n u l l

220

Гл а в а 8. Повторное вы пол нение команд

Кон вейеризация ввода из вывода дан н ых из цикла

Вывод из команды можно кон вейеризировать в цикл, указав знаки канала
между командам и, выполняемыми в конвейере, и последующим ци клом, а вывод
из цикла - в последующую команду. Ниже при веден при мер кон вейеризации вы­
вода из цикла for в команду wc.
$ for i in 1 2 З 4
>
>
>

do

echo $ i
done 1 w c - 1
4

$

Ввод цикла в одной строке

Если часто приходится набирать циклы непосредственно в командной строке,
то с этой целью можно опробовать приведенное ниже сокращенное обозначение
для ввода всего цикла в одной строке. Для этого достаточно указать точ ку с за­
пятой сначала вслед за последним элементом в сп иске, а затем после каждой ко­
манды в теле ци кла, но только не после оператора do. Используя это сокращенное
обозначение, следующий цикл:
for i i n 1 2 3 4
do
e cho $ i
done

может быть переписан таким образом:
for i i n 1 2 3 4 ;

do e c h o $ i ;

do n e

Этот цикл можно набрать непосредственно в командной строке следующим
образом:
$ for i in 1 2 З 4 ; do echo $ i ; done
1
2
3
4
$

Те же самые правила п рименяются к ци клам whi l e и unt i l . Условные опера­
торы i f также могут быть набраны в одной строке в той же самой форме:
$ if
ye s
$ if
no
$

1

=

1 ] ; then echo yes ; fi

1

=

2 ] ; then echo yes ; else echo no ; fi

Кома нда getopts

221

Следует, однако, иметь в виду, что после операторов then и e l s e точки с за­
пятыми не указываются. Многие программирующие на языке оболочки пользу­
ются гибридной структурой, где условные операторы i f структурированы таким
образом :
if

условие
кома нда

then

fi

Столь простое употребление точки с запятой может способствовать повыше­
нию удобочитаемости программ оболоч ки. И поэтому его стоит включить в арсе­
нал своих средств форматирования исходного текста программ.
К оманда ge topts

Произведем дал ьнейшее расширение программы wa i t for, добавив пара­
метр - t, обозначающи й, как часто (в секундах) осуществляется проверка реги ­
страции нужного пол ьзователя в системе. Теперь программа wa i t for должна
принимать два параметра, -m и - t. Допустим, эти параметры могут указываться
в любом порядке в командной строке, но перед именем контрол ируемого поль­
зователя. Таким образом, достоверные варианты ввода данной программы в ко­
мандной строке выглядят следующим образом:
wa i t fo r
wa i t fo r
wa i t fo r
wa i t fo r
wa i t f o r

ann
m ann
- t 6 0 0 ann
-m - t 6 0 0 a n n
-t 6 0 0 - m ann
-

а недостоверные варианты - таким образом:
wa i t fo r
wa i t fo r - t 6 0 0 a n n
wa i t fo r a n n -m
wa i t fo r -t ann

Отсутст вует имя пол ь зова теля
Тре буется пробел после параметра - t
Сна чала должны быт ь ука з а ны параме тры
Отсутствует аргумент после параметра - t

Как только вы начнете писать код, допускающий подобную гибкость в команд­
ной строке, то сразу же обнаружите, что он становится довольно сложным! Но не
переж И вайте, ведь в оболочке и меется встроенная команда getop t s , упроща­
ющая обработку аргументов командной строки . Н и же приведена общая форма
этой команды.
g e t op t s параметры переме нна я

Строку параметров мы обсуди м несколько позже, а до тех пор достаточно
знать, что параметры, обозначаемые тол ько буквами, указываются как таковые, а
параметры, требующие дополнительных аргументов, дополняются завершающим
двоеточием. Так, строка параметров «аЬ : С » означает, что в команде допускаются

222

Гп а в а 8 . Повторное в ы полнен ие кома нд

параметры - а, -Ь и -с, но вместе с параметром -Ь требуется указать дополни­
тельный аргумент.
Но команда getop t s предназначена для выполнения в цикле, поскольку она
упрощает выполнение таких действий, которые требуются для каждого из ука­
занных параметров. На каждом шаге цикла команда getopts проверяет следу­
ющий аргумент командной строки и определяет его достоверность, выясняя, на­
чинается ли он со знака "минус" и любых последующих букв, обозначаемь1х как
параметры. В таком случае команда getopts сохраняет совпавшую букву пара­
метра, которую содержит указанный список переменная, и возвращает нулевой
код завершения. Ниже поясн яется, что все это означает.
Если буква, указан ная после знака "минус': отсутствует в списке параметры,
команда getop t s сохраняет знак вопроса в указан ной переменной, прежде чем
возвратит нулевой код завершения. Она направляет также в стандартный вывод
ош ибок сообщение о параметре, неверно указан ном пользователем.
Если в командной строке больше не остается аргументов или же есл и текущий
аргумент не нач и нается со знака "минус ': команда getopt s возвращает ненуле­
вой код завершения, позволяя затем обработать любые последующие аргументы
в сценарии или программе. Рассмотрим в этом контексте команду ls - С /Ьin,
где -С - параметр, который может быть синтаксически проанал изирован и об­
работан по команде getop t s , а / Ь i n - аргумент самой команды l s , обрабаты ­
ваемый после всех начальных аргументов.
На первый взгляд, приведен ное выше пояснение кажется несколько запу­
танным. Все это действительно не так просто, поэтому обрати мся к кон кретно­
му примеру, чтобы продемонстрировать принцип действия команды getop t s .
Допусти м, что в создаваемом сценарии требуется воспользоваться командой
getopt s , чтобы распознать параметры -а, -i и - r. В таком случае вызов этой
команды может выглядеть следующим образом:
g e t o p t s " a i r " opt i o n

где первый аргумент air обозначает три допустимых параметра команды ( -а,
-i и - r ) , а второй аргумент option - имя переменной, используемой в команде
getopt s для хранения каждого обнаруженного при совпадении значения.
Команда getopt s позволяет также группировать параметры вместе в команд­
ной строке. Для этого достаточно указать оди н знак "минус" и несколько после­
дующих параметров. Так, команда foo в рассматриваемом здесь примере может
быть выполнена следующим образом:
f o o -а

-r

-i

или же так:
foo - a r i

есл и воспользоваться простым свойством группирования.

Кома нда getopts

223

На самом деле команда getop t s намного более эффективна, чем было про­
демонстрировано до сих пор! Она, напри мер, способна учесть и то обстоятель­
ство, что параметру требуется допол н ительный аргумент. Например, новый пара­
метр - t, которым необходимо дополн ить команду wa i t for, должен быть указан
с дополн ительным аргументом.
Чтобы проанализировать надлежащим образом аргументы указанного поль­
зователем параметра, команде getopts требуется, чтобы анализируемая коман ­
да вызы валась хотя бы с одн и м пробелом, отделяющим параметр от аргумента.
В дан ном примере параметры не могут быть сгруппированы вместе.
Чтобы указать команде getopts на то, что параметру требуется аргумент,
после буквы, обозначающей этот параметр, следует указать двоеточие в строке
команды getop t s . Таким образом, в программе wa i t for, допускающей нали­
чие параметров - m и - t, последнему из которых требуется допол нительный аргу­
мент, команду getopts следует вызвать так:
ge t op t s mt : op t i o n

Если команда getopts не обнаружит аргумент после того параметра, которо­
му он требуется, она сохранит знак вопроса в указанной переменной и направит
сообщение об ош ибке в стандартный вывод ошибок. В противном случае она со­
хранит символ в указанной перемен ной, а введенный пользователем аргумент в специальной перемен ной OPTARG.
И последнее замечание относительно команды getop t s . Значен ие 1, первона­
чально устанавливаемое в еще одной специальной переменной O PT I N D, обновля­
ется всякий раз, когда команда getopts возвращает результат, отражающий по­
рядковы й номер аргумента командной строки, который должен быть обработан
следующим по порядку.
Чтобы разъясн ить эту особен ность команды getop t s , рассмотрим приведен­
ную ниже третью версию программы wa i t for, где команда getop t s применя­
ется для обработки аргументов командной строки. В этой версии реализовано
также упом инавшееся выше изменение для отправки сообщен и я по электронной
почте пользовател ю, выполняющему дан ную программу.
$ cat wai tfor
#
# Ожи д а т ь д о т е х пор , п о ка ука з а н н ый п ол ь з о в а т е л ь
# не з аре г и с три руе тс я в с и с т еме - в ер с и я 3
#
# У с т а н о в и т ь з н а ч е н и я по ум олч а нию

ma i l op t = FALSE
i n t e r va l = б O

224

Гла в а 8. Повторное вы полнение команд

# Обработа т ь параме тры команды
wh i l e g e t o p t s mt : opt i o n
do
case " $ op t i on "
in
m ) ma i l op t =TRUE ; ;
t ) i n t e rva l = $ 0PTARG ; ;
\ ? ) echo " Usage : wa i t fo r [ -m ] [ - t n ] u s e r "
echo " - m means t o Ь е i n f o rmed Ь у ma i l "
e cho " - t means che c k every n s e c s . "
exit 1 ; ;
esac
done
# Убедит ь с я ,

что

ука зано

имя

поль з о в а т ел я

i f [ " $0PT I N D " - g t " $ # " ]
then
echo "Mi s s i n g user n ame ! "
exit 2
fi
s h i f t c ount = $ ( ( 0PT I N D - 1 ) )
s h i f t $ s h i f tcount
user=$ 1
#
# Про верять , заре гистриро валс я ли
# ука з анный пол ь з о ватель в системе
#
un t i l who 1 g rep " л $ u s e r "
do
s l ee p $ i n t e rval
done

>

/de v / nu l l

#
# Если про грамма дойдет до э т о г о мес т а , значит ,
# указанный поль з о в а тель заре гис трировался в системе
#
if
" $ma i lopt " = FALSE ]
then
echo " $ u s e r h a s l ogged on "
e l se
runn e r= $ ( who ат i 1 c u t - c l - 8 )
echo " $ u s e r h a s l ogged on " 1 ma i l $ runne r
fi
$ waitf"or -ш
Mi s s ing u s e r name !

Команда getopts

$ wai tfor

-

х

fred

225

Недо пу стимый параметр

wa i t fo r : i l l e g a l op t i o n - - х
U s a g e : wa i t fo r [ -m ] [ - t n ] u s e r
- m mea n s t o Ь е i n fo rmed Ь у ma i l
- t mea n s c he c k e ve r y n s e c s .

$ wai tfor -m - t 600 ann &

Пров еря ть регистра цию в сис т еме
ann каждые 1 0 м 11 нут

поль зо ва т еля
[1]

5 7 92

$

Проанализируем последнюю строку более подробно. Когда выполняется строка
wa i t fo r -m -t

6 0 0 ann &

в цикле whi l e происходит следующее: вызы вается команда getopts, сохраняю­
щая символ m в перемен ной opt i on, устанавл ивающая значение 2 в переменной
OPT I N D и возвращающая нулевой код завершения.
Затем в операторе case определяется, что и менно было сохранено в перемен ­
ной opt i on. Совпадение с символом m указывает н а то, что выбран параметр,
определяющий отправку сообщения по электронной почте, и поэтому в перемен ­
ной $ma i lopt устанавли вается логическое значение TRUE. (Обратите внимание
на то, что знак ? в операторе ca s e специально экранирован . Благодаря этому
исключается его специальное назначение в оболоч ке как символа совпадения с
шаблоном.)
При выполнении во второй раз команда getop t s сохраняет символ t в пере­
мен ной opt i on, следующий в командной строке аргумент ( 6 0 0 ) - в переменной
OPTARG, а значение З - в перемен ной OPT I N D и возвращает нулевой код завер­
шения. Затем в операторе case проверяется совпадение с символом t, храня­
щимся в переменной opt i on. Далее в коде, указанном в данной ветви оператора
case, значение 600, сохраненное в переменной O PTARG, копируется в перемен ­
ную interva l . А когда команда getopt s выполняется в третий раз, она возвра­
щает ненулевой код завершен ия, указывая на то, что она дости гла конца списка
операторов, указан н ых пользователем в командной строке.
После этого в дан ной программе сравниваются значения в переменных OPT I N D
и $ #, чтобы проверить, было ли и м я пользователя введено в командной строке.
Если значение переменной OPT I N D оказывается больше, чем значение перемен­
ной $ #, это означает, что аргументов в командной строке больше не осталось, а
пользователь программы забыл указать имя нужного ему пользователя в качестве
аргумента. Конкретное количество позиций, на которые требуется произвести
сдвиг, оказывается на единицу меньше, чем значение переменной O PT I N D.
Остальная часть програм мы wa i t for остается такой же, как и прежде. Еди н ­
ственное изменение состоит в применен ии переменной i n t e rva l для хранения
промежутка времени (в секундах), на который прерывается данная программа.

226

Гл а в а 8. Повторное вы пол нен ие команд

Если у вас голова идет кругом от команды getop t s , не отчаивайтесь - ее при­
менение будет еще не раз продемонстрировано в примерах программ оболочки
из последующих глав, что поможет вам лучше раскрыть ее истинный потенциал.
Ее изучение окажется полезным и для совершенствования в программировании
на языке оболочки, поскольку синтаксический анализ вручную не одного, а не­
скольких аргументов в командной строке край не неэффекти вен.

В в од и выв од д анных
В этой главе поясняется, каким образом данные вводятся с терминала и л и
файла п о команде r e a d и направляются в отформатирован ном виде в стандарт­
ный вы вод по команде p r i n t f.
К ом а нда read

Общая форма команды read выглядит следующи м образом:
r e a d переме нные

Когда выполняется эта команда, оболоч ка читает строку из стандартного
ввода и присваивает первое слово перемен ной, перечисленной первой в списке
переменные, второе слово - второй перемен ной и т.д. Если же слов в строке
оказывается больше, чем перечисленных выше переменных, лишние слова при­
сваиваются последней переменной. Например, по следующей команде:
read х у

строка читается из стандартного ввода, сохраняя первое слово в перемен ной х, а
остальные слова - в перемен ной у. Таким образом, по следующей команде:
read text

вся строка читается и сохраняется в перемен ной оболоч ки text.
П ример п рогра м мы коп и рован ия файлов

Попробуем применить команду read на практике, нап исав программу в виде
упрощенной версии команды ер. Эта программа называется mycp и должна при ­
нимать два аргумента, обозначающие исходный и целевой файлы. Есл и целевой
файл уже существует, программа mycp предупредит пользователя и предложит
ему продолжить операци ю копирования. При положительном ответе пользова­
теля операция копирования будет продолжена, а и наче произойдет выход из дан ­
ной программы, как показано н и же.
$ cat mycp
#
# С к о п и р о в а т ь фа йл
#
if

" $ # " -ne 2 ] ; then
e c h o " U s a g e : m y c p f r om t o "

228

Гл а в а 9. В вод и вывод данн ы х

exit 1
fi
f rom= " $ 1 "
t o= " $ 2 "

#
# Выяснит ь ,
#
if

суще с т вует ли целе вой файл

- е " $ t o " ] ; then
ec ho " $ t o a l ready e x i s t s ;
read a n s we r
if

[

ove r w r i t e

( ye s / no ) ? "

" $ a n s we r " ! = ye s ] ; then
ec ho "Сору n o t p e r f o rmed "
exit О

fi
fi

#
# Цел е в ой файл не с уще с т вуе т или в веден положител ь ный о т ве т
#
ер $ f rom $ t o
$

# продолжи ть копиро вание файла

А теперь оперативно проверим данную программу в действии :
$ l s -с

Что за ф а йлы ? Параметр - С о пределяет
вывод резуль та та в несколь ко стол бцов

mycp
Add re s s e s
i n t ro
lot saspaces
name s
nu
nшnЬe r s
phonebo o k
stat
$ mycp
Без аргументов
U s age : mycp f rom t o
$ mycp naшes naшes2
Скопиров а ть фarw names
Произошло ли ко пирова ние у спешно ?
$ ls -1 names *
- rw - r - - r - 1
s t eve
s t eve
4 3 Ju l
20 1 1 : 12
name s
- rw - r - - r - 1
s t eve
s t eve
4 3 Ju l
21 14 : 16
name s 2
$ mycp naшes numЬers
Попыта ть ся пере писа ть существующий фа йл
n umЬ e r s a l ready e x i s t s ; overwr i t e ( ye s / n o ) ?

no
Сору n o t pe r fo rmed
$

Следует заметить, что если целевой файл уже существует, команда echo вы­
водит приглашение дать положительный или отрицательный ответ. А следующая
далее команда read вынуждает оболоч ку ожидать ответа пользователя. В данном
примере программы демонстрируется, что сама оболоч ка не выводит приглаше­
н ие, ожидая от пользователя ввода дан ных. Эта обязанность возлагается на авто­
ра программы.

Кома нда read

229

Данные, вводимые пользователем, сначала сохраняются в перемен ной answe r,
а затем сравниваются с сим вольной строкой " ye s " , чтобы выяснить, следует ли
продолжить процесс копирования файла. Кавычки, в которые заключена пере­
мен ная answer в следующей проверке:
[

" S a n s we r "

! = ye s ]

необходимы на тот случай, если пользователь просто нажмет клавишу < Enter>, не
вводя ни каких данных. В таком случае оболоч ка сохранит в перемен ной answe r
пустое значение. А без кавычек в результате данной проверки было б ы выведено
сообщение об ошибке.
Обратите также внимание на точку с запятой, которая позволяет указывать
операторы then в одной строке с условн ым оператором i f. Это типичный прием,
к которому прибегают программирующие на языке оболочки, как упоми налось в
предыдущей главе.
Употребление специал ьн ых у правля ю щ их
си мволов в команде echo

Некоторое неудобство при использовании программы rnycp возни кает в свя ­
зи с тем, что данные, введенные пользователем после выполнения команды e cho,
отображаются в следующей строке. Это происходит потому, что команда e cho ав­
томатически добавляет знак новой строки вслед за последним аргументом.
Правда, этот знак нетрудно подавить, если указать специальный управляющий
символ \с в конце команды e cho. Тем сам ым команде e cho предписы вается про­
пустить знак новой строки после отображения последнего аргумента. Так, есл и
внести в вызов команды e cho из программы rnycp следующие изменения:
echo " S t o a l ready e x i s t s ;

ove rwr i t e

( ye s / n o ) ? \ с "

введенные пользователем дан ные отобразятся в той же самой строке. Следует,
однако, иметь в виду, что управляющий символ \с интерпретируется командой
echo, а не оболоч кой. Это означает, что он должен быть экранирован знаком об­
ратной косой черты, чтобы его правильно восприняла команда echo.
Примеч а ние

Оболоч ки в некоторых системах Li n u x и М ае OS Х не и нтерпрети руют уп ра вля ющие сим ­
вол ы в кома нде echo . и поэтому при веденная вы ше кома нда echo отобразит следующи й
резул ьтат:
newfile . txt al ready exists ; overwrite (yes/no ) ? \с
Есл и в резул ьтате п роверки выявится , что о болочка действует и менно таким о бразом , в ы­
зовы команды echo в этих кон кретн ых местах п рогра м м ы следует замен ить на о б ра щения
к отдел ьной п рогра мме /Ьin/echo . и тогда он и будут вы полнены п ра вильно. А все остал ь­
н ые вызовы о б ыч ной команды echo следует оста вить без изменен ия.

230

ГЛ pwd
/use r s / s teve
� = > PSl = " I awai t your next cOJDJDand , master :
"
I a wa i t yo u r n e x t c omma n d , ma s t e r : date
Wed Sep 1 8 1 4 : 4 6 : 2 8 E DT 2 0 0 2
I awa i t you r n e x t c omma n d , ma s t e r : PS1="$ "
$

В ерну ть ся к о бычному пригл ашению

По умолчанию в качестве вспомогательного при глашения, когда команду тре­
буется ввести в нескольких строках, употребляется знак >, который хранится в

Переменная НО М Е

261

перемен ной PS2. Содержимое и этой переменной можно изменить по своему ус­
мотрению, например, следующим образом:
$ echo : $ PS2 :
: >

:

> "
$ PS2="
$ for х in 1 2 3
> do
> echo $х
> done

= о� = = = = =

=======
=======

1

2

3

$

Как тол ько вы выйдете из системы , все изменен ия, внесен ные в упомянутых
выше переменн ых, исчезнут, как, впрочем, и все изменен ия в любых других пере­
мен ных оболочки. Если внести изменение в переменную PS 1, ее новое значен ие
будет использоваться далее в сеансе работы в оболоч ке. Но когда вы войдете в
систему в следующи й раз, то увидите прежнее приглашен ие, если только не со­
храните новое значение переменной PS l , введя его в файл . pro f i l e, рассматри­
ваемый далее в этой главе.
Со вет

У п ри гла шения , хра ня щегося в перемен ной

PS l . имеется собственный язы к со специал ь­
н ы м и последовател ьностя м и опера ци й . п роизводя щих подсчет команд, выбор текущего
каталога , оп ределение времени суток и в ы пол няющих м ногое другое. Озн а ко м иться с эти м
языком мож но, п рочита в раздел " Prom pti пg" ( В ыдача п р и глашения) на операти вной стра ­
ни це руководства по оболочке Bash или S h .

Пере м е н ная НОМЕ

Ваш начальный каталог находится там, где вы размещаете его всякий раз, ког­
да входите в систему. Этот каталог автоматически устанавли вается также в спе­
циальной перемен ной оболоч ки НОМЕ, когда вы регистрируетесь в системе, как
демонстрируется в следующем примере:
$ echo $На.Е
/use r s / s teve
$

Этой переменной вы можете воспользоваться в своих программах с целью
определ ить начальный каталог. Именно таким образом она употребляется в дру­
гих программах системы Unix. Переменная НОМЕ употребляется также в команде
cd для перехода в требующийся целевой каталог, когда эта команда вводится без
аргументов, как показано ниже.

Гл а в а 1 0 . Рабочая среда

262

$ pwd

Ото бр а зить текущий к а т а лог

/ u s r / s r c / l i Ь / l i b c / po r t / s t d i o
$ cd
$ pwd
На чальный ка талог п оль зова теля
/ u s e r s / s t e ve
$

Содержимое переменной НОМЕ можно изменить на любое другое, ка�< пока­
зано ниже. Но такое изменение может повлиять на действие программ, опираю­
щихся на дан ную переменную.
$ HOМE=/users / s teve/Ьoo k

$ pwd

Изме нить содержимо е пер еме н ной

/ u s e r s / s t e ve
$ cd

$ pwd
/ u s e r s / s t e v e / bo o k
$

Выя с нить ,

что же пр оизошло

Содержи мое перемен ной НОМЕ можно измен ить. Но делать этого все же не ре­
комендуется, если только вы не готовы к тому, что положение дел может очень
быстро оказаться весьма шатким.
Перемен н ая РАТИ

Вернемся, однако, к программе ro l o из главы 9, выполнив ее следующим об­
разом:
$ rolo Liz
L i z Stachiw

2 12-775-2298

$

Допустим, что для приведения дел в более орган изованный порядок эта про­
грамма была создана в подкаталоге / b i n пользователя s t eve:
$ pwd

/ u se r s / s t e ve / b i n
$

Перейдите в какой-нибудь другой каталог в файловой системе. Например, по
следующей команде:
$ cd

Перейти в на чальный ка талог

$

А

теперь попытайтесь найти абонента L i z в телефон ном справочн и ке:

$ rolo Liz
sh : ro l o : not found
$

Не удалось! Что же произошло?

Переменная РАТН

263

Всякий раз, когда вы вводите имя программы, оболочка производит ее поиск
в списке каталогов до тех пор, пока не найдет запрашиваемую программу. Как
только программа будет найдена, она будет запущена на выполнен ие. Этот список
каталогов для поиска пользовател ьских программ хранится в переменной обо­
лочки РАТ Н и автоматически устанавли вается в ней, когда вы входите в систему.
Чтобы выяснить в любой момент, что установлено в этой перемен ной, достаточно
воспользоваться командой e cho следующим образом :
$ echo $РАТИ
/bin : /usr/bin : .

$

Скорее всего, в перемен ной РАТН установлено совсем другое значение, но в
этом нет ни чего страшного. Ведь это всего лишь отклонение от конфигурации
системы. Важно лишь иметь в виду, что каталоги должны разделяться двоеточием
( : ) и что поиск в них запрашиваемых команд или программ оболочка производит
по порядку слева направо.
В предыдущем примере перечислены три каталога: / Ь i n, / us r / Ь i n и . (точ­
ка, как известно, обозначает текущий каталог). Поэтому всякий раз, когда вводит­
ся имя программы, оболоч ка производит ее поиск в каталогах, перечисленных в
переменной РАТН, до тех пор, пока не найдет совпадающий исполняемый файл.
Так, если ввести имя программы rolo, оболочка попробует найти ее исполняе­
мый файл по пути /Ь i n / ro l o, затем по пути /us r / Ь i n / ro l o и, наконец, по
пути / rolo к текущему каталогу. Как только оболочка найдет искомый файл,
она запустит его на выполнен ие. А если оболочке не удастся найти испол няемый
файл rolo ни в одном из каталогов, перечисленных в перемен ной РАТН, то она
выдаст сообщен ие об ошибке " not found" (не найдено).
Чтобы поиск нач и нался, прежде всего, с текущего каталога, точку следует
указать в переменной РАТН первой, как показано н и же. Следует, однако, иметь в
виду, что из соображений безопасности поиск не должен производиться в теку­
щем каталоге пользователя прежде, чем в системных каталогах .
.

. : /Ь i n : /us r /Ь i n

Это· правило следует собл юдать в о избежание нарушений защиты системы с
помощью так назы ваемых троянских коней. Допустим, кто-нибудь создаст свою
верси ю команды s u, которая позволяет перейти в корневой каталог или устано­
вить привилегии суперпользователя по приглашению ввести пароль адми нистра­
тора системы, а затем разместит ее в текущем каталоге, ожидая до тех пор, пока
другой пользователь перейдет в этот каталог и выполнит дан н ую команду. Если
этот текущий каталог указан в перемен ной РАТ Н первым, то будет выполнена
видоизменен ная версия команды su. Но дело в том, что эта версия выдаст при ­
глашение н а ввод пароля, отправит его п о электрон ной почте злонамеренному

264

Гл а в а 1 0 . Рабочая среда

пользователю, удалит себя и выведет безобидное сообщение об ошибке. В резуль­
тате повторного вызова и ввода пароля учетная запись администратора окажется
нарушенной, а пользователь даже не осознает, что же на самом деле произошло!
Ловко, не так ли?
Точка ( . ), обозначающая текущий каталог, служит необязательным, но удоб­
ным наглядным напоминанием. Например, следующее значение пер�менной
РАТН:
: /Ьin : /usr/Ьin

равнознач но предыдущему. Но здесь и далее текущий каталог будет обозначаться
точкой ради большей ясности.
Есл и вас беспокоят троя нские кони , у вас всегда есть возможность переопреде­
л ить порядок поиска, заданный в переменной РАТН, явно указав путь к исполня­
емому файлу программы. Так, если вы введете следующий путь:
/ Ь i n /da t e

оболочка перейдет непосредственно к каталогу / Ь i n, чтобы выполн ить команду
da te. В этом случае содержимое перемен ной РАТН будет прои гнорировано, как,
впрочем, и в том случае, если вы введете путь
. . /Ьin / l u

или
. / rolo

В последнем случае предписывается выполн ить программу ro lo, исполняе­
мый файл которой находится в текущем каталоге. Такой способ нередко приме­
няется при разработке программ оболочки, поскол ьку он дает возможность опу­
стить точку ( . ) в переменной РАТН.
Теперь должно быть понятно, почему программу r o l o нельзя было выполнить
из начального каталога пользователя s teve. В переменную РАТН не был вклю­
чен путь / u s e r s / s t eve / Ь i n, и поэтому оболочке не удалось найти программу
r o l o. Чтобы устран ить данное препятствие, проще всего включить путь к этому
каталогу в переменную РАТН следующим образом:
$ PAТН=/bin : /usr/bin : /users / s teve/bin : .
$

Теперь любая программа из каталога / u s e r s / s teve / Ь i n будет выполнена
независимо от местоположения текущего каталога в файловой системе.
$ pwd
От о бра зить текущнй ка та л о г
/ u s e r s / s t e ve
$ rolo Liz
g r e p : c a n ' t open phonebo o k
s

Пе р еменна я РАТН

265

Что же теперь не так? Оболочка правильно обнаружила исполняемый файл
программы ro l o, но команде g rep не удалось найти файл данных phoneboo k.
Если внимательно проанализировать исходный текст программы rolo, то мож­
но обнаружить, что источником сообщения об ошибке в команде grep служит
программа 1 u. Ниже приведен исходный текст программы 1 и в ее текущей версии.
$ cat /users / s teve/bin/lu
#
# Найти абоне нта в телефонном спра во ч ни ке - в е р с и я З
#
if

"$#"

-

п

е 1

]

t hen
e cho " I n co r r e c t numЬ e r o f a r gume n t s "
e c h o " U s a g e : l u name "
exi t 1
fi

g r ep " $ name " phonebo o k

$

Команда g rep пытается найти файл phoneboo k в текущем каталоге, которым
в настоящий момент является каталог / u se r s / s teve. Но дело в том, что рассма­
триваемая здесь программа выполняется безотносительно к каталогу, в котором
находится она и ее файл дан н ых.
В перемен ной РАТН указываются только те каталоги, в которых ищутся испол­
няемые файлы программ, вызываемых из командной строки, но не л юбые другие
типы файлов. Поэтому местонахождение файла данных phonebo o k должно быть
точно определено, чтобы им было удобнее пользоваться в программе l u.
Этот недостаток, присущий не только программе lu, но и программам rem и
add, можно исправить несколькими способами . В частности, перед вызовом ко­
манды grep в программе lu можно перейти в каталог / u s e r s / s teve /Ьin, как
показано ниже. И тогда команда g rep обнаружит файл phoneboo k, поскольку
он находится в новом текущем каталоге.
cd / u s e r s / s t e ve/ Ы n
phonebo o k

g rep � $ 1 "

Такой способ при годен в том случае, если приходится немало мани пулировать
различными файлами в отдельном каталоге. Для этого достаточно перейти снача­
ла в нужный каталог по команде cd, а затем непосредственно обратиться ко всем
требующи мся файлам.
Второй , более распространенн ы й способ состоит в том, чтобы указать полный
путь к файлу phonebo o k в команде grep:
g rep " $ 1 " / u s e r s / s t e ve / Ь i n / phonebo o k

Гл а в а 10. Ра бочая среда

266

Допустим, что и другим пользователям требуется предоставить возможность
применять программы ro lo, а также связанные с ней программы l u, add и rem.
С этой целью каждому из них можно было бы предоставить отдельную копию дан­
ной программы, но тогда в системе появилось бы нескол ько ее копий, обновлять
которые было бы неудобно, если бы потребовалось внести даже незначительные
изменения в программу. Поэтому лучше иметь еди нственную копию прогр аммы
ro l o, но предоставить доступ к ней други м пользователям.
В этой связи возникает следующее затруднение: есл и измен ить все ссыл ки
на файл phonebo o k таки м образом, чтобы явно ссылаться на свой телефон ­
н ы й справоч н и к, то и все остал ьные будут пользоваться эт им же телефон ­
н ы м справоч н и ком. Поэтому лучше, чтобы у каждого пол ьзователя был свой
файл phoneboo k, доступ н ы й в его начальном каталоге по ссылке $ НОМЕ /
phoneboo k.
Чтобы воспользоваться столь распространенным соглашен ием по програм­
мировани ю на языке оболочки, следует определить в программе r o l o перемен ­
ную PHONEBOOK, установив в ней удобное для многих пользователей значение
$ HOME /phoneboo k. Если экспортировать переменную PHONEBOOK, ее значение
будет использоваться в программах l u, rem и add, выполняемых как подоболоч ­
ки в программе r o l o, для ссылки на отдельную версию файла phoneboo k соот­
ветствующего пользователя.
Преимущество такого подхода заключается, в частности, в следующем: если
изменить местоположение файла phoneboo k, то достаточ но внести изменение
только в одну переменную в программе r o l o, чтобы остальные три программы и
дальше работали без сучка и задоринки. С учетом этих соображений ниже при­
ведены новые версии программ ro l o, l u, add и rem.
$
$
#
#
#
#

cd /users/ s teve/bin
cat rolo
прогр амма дл я п о и с к а , в вода и удал е ни я с ведений
об абон ен та х и з теле фон н о г о с п ра во чн и ка

rolo

-

# Ус т а но в и т ь в п ереме н н о й РНОNЕВООК с с ыл ку н а файл
# тел ефо н н о г о спра во ч н и к а и э к с п ортиро ва т ь е е , ч тобы
# сдела т ь доступ н ой в дру г и х программ а х
#

PHONE BOOK= $ HOME / phoneboo k
e xpo r t PHON EBOOK
if

fi

[

- f " $ PHONEBOO K " ] ; t h e n
e c h o " N o p h o n e boo k f i l e i n $ НОМЕ ! "
exit l

П еремен ная РАТН

#
# Е сли предо с т а влены аргуме н т ы ,
#
if

" $ # " -ne О
lu " $ @ "
exit

J

прои з в е сти поиск

then

fi
va l i dcho i ce = " "

# установить пус т о е значение

#
# Вьmолни т ь цикл до т е х пор ,
# сделан правиль ный выбор

п о к а не буде т

#
unt i l
do

-n " $ va l idch o i ce " ]
#
# Отобр а зи т ь меню
#
e cho '
Wou l d you l i ke t o :

1 . Loo k s ome one up
2 . Add s ome one t o t h e phone b o o k
3 . Remove s ome one f r om the phone b o o k
P l e a s e s e l e c t one o f t h e above

( 1-3 ) :

\с '

#
# Прочи т а т ь и обра б о т а т ь выбранный вариант
#
read cho i c e
e cho
case
in

" $ ch o i c e "

1)

2)

e c h o " E n t e r name t o l o o k up : \ с "
r e a d n ame
lu " $ name "
va l i dcho i ce =TRUE ; ;
e c h o " E n t e r n ame t o Ье added : \ с "
r e a d name
e cho " E n t e r numЬ e r : \ с "
r e a d numЬ e r
a d d " $ name " " $ numЬe r "
v a l idcho i c e =T RU E ; ;

267

268

Гл а в а 1 0 . Ра бочая среда

3)

*)

e c h o " E п t e r п ате to Ье r emove d :
read паmе
rem " $ паmе "
va l i dcho i c e =T RUE ; ;
e c h o " B ad cho i c e " ; ;

\с"

e sac
dопе
$ cat add
#
# Программа дл я в в ода абонента в файл т елефонно го справочника
#
if

"$#"
e ch o
e ch o
exit

-пе 2 ] ; t h e п
" I п c o r r e c t пшnЬ е r o f a r gumeп t s "
" U s a g e : add п аmе пшnЬ е r "
1

fi
echo " $ 1
$ 2 " > > $ PHONE BOOK
s o r t - о $ PHON E BOOK $ PHONEBOOK
$ cat lu
#
# Найти абонента в телефонном справочнике
#
if

" $ # " -пе 1 ] ; theп
e cho " I п c o r r e c t пшnЬ е r of a r gume п t s "
e ch o " U s a ge : l u паmе "
exit 1

fi
пате = $ 1
g rep " $ паmе " $ P HONEBOOK
i f [ $ ? -пе О ] ; theп
e cho "I c o u l dп ' t f i пd $ п аmе i п t h e рhопе boo k "
fi
$ cat rem
#
# Удали т ь абонента из телефонного спра вочника
#
if

" $ # " -пе 1 ] ; t h e п
e ch o " I п c o r r e c t пшnЬ е r o f a r gume п t s "
e cho " U s a ge : rem п ате "
exit 1

fi
паmе = $ 1
#
# Выя в и т ь коли ч е с т в о совпа вших записей
#

Переме н н а я РАТН

ma tche s = $ ( g r e p " $ name " $ PHONE BOOK

1

269

wc - 1 )

#
# Если с о впа вших з а писей бол ь ше одной ,
# а ина ч е - удалить з апись
#

выв е с ти сообще ние ,

" $ma t che s " - g t 1 ] ; t h e n
echo " Mo r e than one ma t ch ; p l e a s e qua l i f y f u r t he r "
e l i f [ " $ma t che s " - e q 1 ] ; t h e n
g r e p - v " $ n ame " $ PHONEBOOK > / tmp /phoneboo k $ $
mv / tmp /phonebo o k $ $ $ P HONEBOOK
e l se
echo " I cou l dn ' t f i nd $ n ame in the phone b o o k "
fi
$
if

В данном случае был применен еще оди н специальный прием. Ради большего
удобства для пользователей в конце программы 1 u была введена проверка с це­
лью выяснить, успешно ли была выпол нена команда g rep. Если же поиск не дает
никаких результатов, то выводится соответствующее сообщение. А теперь про­
верим программу rolo:
$ cd
$ rolo

Перей ти в на чаль ный ка талог
Пр оизв е сти быстрый поиск
No phone b o o k f i l e in / u s e r s / s t e ve ! Fo r g o t to move i t
$ mv /users/ steve/bin/phoneЬook .
$ rolo Liz
Попр обо в а ть еще р а з
Li z S t ac h i w 2 1 2 - 7 7 5 - 2 2 9 8
Попр обо в а ть с в ыбор ом в ариа нта из ме ню
$ rolo
Wou l d you l i ke t o :
1 . L o o k s ome one up
2 . Add s ome on e to t h e phone b o o k
3 . Remo ve s ome one f rom t h e phone boo k

Liz

P l e a s e s e l e c t one o f t h e above
E n t e r name t o Ье added : Teri
E n t e r numЬe r : 2 0 1 - 3 93 - 6 0 0 0
$ rold Teri
Teri Zak 2 0 1 - 3 9 3 - 6 0 0 0
$

( 1-3 ) :

2

Zak

Как видите, программы rolo, l u и add действуют исправно. Остается лишь
проверить программу rem, чтобы убедиться и в ее исправности. Если же програм­
му 1 u, rem или add требуется выполнить отдельно, это можно сделать, определи в
сначала переменную PHONEBOOK, а затем экспортировав ее, к а к демонстрируется
в следующем примере:

270

Гл а в а 10. Рабочая среда

$ PHONEBOOK=$HOМE /phoneЬook
$ export РНОNЕВООК
$ lu Harmon
I c o u l dn ' t f i nd Ha rmon in t he phone b o o k
$

Если упомянутые выше программы предполагается выполнять отдеJ\ьно, в
каждой из них следует ввести проверку установки правильного значения в пере­
менной РНОNЕВООК.
Те кущ и й каталог п ол ьзо в а теля

Ваш текущий каталог является также частью среды вашей оболоч ки. Рассмо­
трим в качестве примера следующую небольшую программу оболочки под на­
званием cdte s t:
$ cat cdtest
cd / u s e r s / s t e ve / b i n
pwd
$

В этой программе сначала выполняется команда cd для перехода в каталог
/us e r s / s teve / Ь i n, а затем вызывается команда pwd для проверки изменений
в местоположении пользователя. Попробуем выполнить эту программу следую­
щим образом:
Выя с ни ть те кущий к а т ало г
$ pwd
/ u s e r s / s t e ve
$ cdtest
/ u s e r s / s t e ve / b i n
$

А теперь попробуйте ответить на следующий любопытный вопрос: если вы звать команду pwd, то в каком каталоге вы окажетесь: / u s er s / s teve или /
u s e r s / s teve / Ь i n? Oтвe�
$ pwd
/ u s e r s / s t e ve
$

Оказывается, что выполнение команды cd в программе cdt e s t не оказывает
н икакого влияния на ваш текущи й каталог. А поскольку текущий каталог явля­
ется частью текущей среды, то когда команда cd выполняется из оболочки, она
оказывает влияние только на смену каталога в данной оболочке. Перейти же в
текущий каталог родительской оболочки из подоболочки никак нельзя.
Когда команда cd вызывается на выполнение, она сменяет текущий каталог, а
также устанавливает в переменной PWD полный путь к новому текущему катало­
гу. В итоге следующая команда:

Текущи й каталог пол ьзователя

271

echo $ PWD

дает такой же результат, как и команда pwd:
$ pwd
/ u s e r s / s t e ve
$ echo $PWD
/ u s e r s / s t e ve
$ cd Ьin
$ echo $PWD
/ u s e r s / s t e ve / b i n
$

Кроме того, команда cd устанавливает в переменной OLD PWD полный путь к
каталогу, который был прежде текущим. И в некоторых случаях это может быть
удобно.
П е ре м ен на я CDPATH

Переменная CDPATH действует таким же образом, как и переменная РАТН. Она
определяет список каталогов, в которых оболочка производит поиск всякий раз,
когда выполняется команда cd. Такой поиск производится лишь в том случае,
если указанный каталог не задан по полному пути и если значение переменной
CDPATH оказывается непустым. Так, если ввести следующую команду:
cd /users/steve

оболочка сменит текущий каталог на /us e r s / s t eve . Но если ввести команду
cd memos

оболочка воспользуется значением переменной CDPATH, чтобы найти каталог
memo s . И если значение переменной C D PATH окажется следующим:
$ echo $CDPATH
. : / u s e r s / s t e ve : / u s e r s / s t e ve / d o c s
$

оболочка произведет поиск каталога memo s сначала в текущем каталоге данно­
го пользователя, а если не найдет его - в каталоге / u s e r s / s teve. Если же и
эта поqытка окажется неудачной, то поиск будет произведен в каталоге / u s e r s /
s t eve /doc s , как в последнем прибежище искомого каталога. Если указанный
каталог найден не относительно текущего каталога, то команда cd выведет пол­
ный путь к нему, чтобы пользователю стало понятно, куда именно он перешел.
$ cd /users/ s teve
$ cd memos
/ u s e r s / s t e ve / d o c s /rnerno s
$ cd Ьin
/ u s e r s / s t e ve / b i n
$ pwd
/ u s e r s / s t e ve / b i n
$

272

гл а в а 10.

Ра бочая среда

Как и в переменной РАТН, употреблять точку для обозначения текущего ка­
талога в переменной С О РАТН совсем не обязательно. Поэтому следующий путь:
: / u s e r s / s t e ve : / u s e r s / s t e v e / do c s

равнозначен приведенному ниже пути
. : / u s e r s / s t e ve : / u s e r s / s t e ve / do c s

Благоразумное использование переменной С О РАТ Н позволяет немало сэконо­
мить на наборе путей к каталогам, особенно если иерархия каталогов оказывает­
ся довольно глубокой и приходится часто перемещаться не только в этой, но и
в других иерархиях. В отличие от переменной РАТ Н, текущи й каталог, вероятнее,
всего следует указать в переменной С О РАТН первым. Это дает возможность упо­
треблять переменную С О РАТН самым естественным образом. Если же текущий ка­
талог не указан в ней первым, он может в конечном итоге оказаться неожиданным!
И еще оди н момент: переменная CDPATH не устанавливается, когда вы входите
в систему. Вам придется устанавливать в ней явным образом последовательный
ряд каталогов, в которых оболочка будет искать указанное имя файла.
До п ол н ител ьн ы е све д е н и я об п одоболоч ках

Как известно, ни значение переменной, н и текущий каталог из родительской
оболочки не могут быть изменены в подоболочке. Допустим, требуется написать
программу для установки значен и й в ряде переменных, которыми необходимо
воспользоваться после входа в систему. В качестве примера рассмотрим файл
va r s следующей программы:
$

cat vars

BOOK= / u s e r s / s t e v e / b o o k
U U P U B = / u s r / s po o l / uucppuЫ i c
DOC S = / u s e r s / s t e ve / do c s /memo s
DB= / u s r 2 / d a t a

$

Если вызвать программу va r s , значения, присвоенные указанным в ней пере­
менным, по существу, исчезнут по окончании данной программы, поскольку она вы­
полняется в подоболочке, как показано ниже. И в этом нет ничего удивительного.
$

$

vars
echo $ВООК

$

Ко ма нда

Чтобы разрешить упомянутую выше дилемму, в оболочке имеется команда­
точка ( ), общая форма которой приведена ниже.
.

фа йл

Допол н ител ьн ые сведен и я об подоболочках

273

Назначение этой команды - выполнить содержимое указанного фа йла в те­
кущей оболочке. Это означает, что команды из указанного файла выполняются в
текущей оболочке так, как будто они были просто набраны в командной строке,
но не в подоболочке. Переменная РАТН употребляется в оболочке для поиска ука­
занного файла, как и при выполнении любых других программ.
$
vars
$ echo $ВООК
/ u s e r s / s t e v e /boo k
$
.

Выполнить пр ограмму vars в текущей оболо чке
Ур а !

Для выполнения программы подоболочка не порождается, и поэтому любая
переменная, которой присваивается значение, сохраняется даже по завершении
программы. Так, если имеется программа с:1Ь со следующими командами:
$ cat dЬ
DATA= / u s r2 / d a t a
RPTS= $ DATA / rp t s
В I N= $ DAТA / Ь i n
cd $ DATA
$

то в результате выполнения программы db по команде-точке будет получен сле­
дующий любопытный результат:
$ pwd
/ u s e r s / s t e ve
$

$
.

На этот раз в данной программе определяются три переменные, DATA, RPTS
и B I N, в текущей оболочке и происходит переход к каталогу, указанному в пере­
менной DATA:
$ pwd
/ u s r 2 / da t a
$

Работая над несколькими проектами, можно создавать программы вроде с:1Ь
для специальной настройки своей среды нужным образом. В такую программу
можно также включить определения других переменных, изменить приглашения
и сделать многое другое. Например, может возникнуть потребность заменить на
DB приглашение в переменной PS l , чтобы знать, что переменные базы данных
были установлены; ввести в переменную РАТН каталог, где находятся программы,
связанные с базой данных; а в переменной указать соответствующие каталоги,
чтобы сделать их легко доступными по команде cd.
С другой стороны, если внести изменения подобного рода, то может воз­
никнуть потребность выполнить программу с:1Ь в подоболочке, а не в текущей

274

гл а в а 10. Ра боча я среда

оболочке. Ведь в последнем случае все видоизмененные переменные останутся по
завершен и и работы с базой данных.
Самое лучшее - запустить новую оболочку из подоболочки со всеми видо­
измененными переменными и обновленными в среде установками. А по завер­
шен ии работы можно выйти из новой оболочки, нажав комбинацию 1
PWD= / u s e r s / s t e ve /rni s c
SHELL= / u s r /Ь i n / s h
T E RМ= x t e rrn
TMOU T = O
T Z =E S T 5 E DT
crnd=wc
х=*
$

П е р е назна че н ие пози ц и он н ых п а ра м етр ов
с помо щ ь ю к оманд ы set

Напомним, что присвоить новое значение позиционному параметру или пере­
назначить его никак нельзя. Попытку переназначить, например, значение 1 0 0 по­
зиционного параметра $ 1 логически можно обозначить следующим образом:
1=100

Но и з этого ничего не выйдет. Пози ционные параметры устанавливаются по­
сле вызова программы оболочки.
Тем не менее, чтобы изменить значение позиционного параметра, можно вос­
пользоваться следующим ловким приемом: если слова задаются в команде set как
аргументы командной строки, эти слова будут присвоены позиционным параме­
трам $ 1 , $ 2 и т.д. А предыдущие значения, хранившиеся в позиционных параметрах,
будут утрачены. В таком случае по следующей команде из программы оболочки:
set

а

Ь

с

аргумент а будет присвоен позиционному параметру $ 1 , аргумент Ь - позицион ­
ному параметру $ 2 , тогда как аргумент с - позиционному параметру $ 3 . Ниже
приведен более сложный при мер переназначения позиционных параметров.

Ком а н да set

295

$ set one two three f our
$ echo $1 : $2 : $3 : $ 4
one : t wo : t h r e e : f o u r
Эта ссылка должна быть на зна чение 4
$ echo $ #
4
$ echo $ *
А н а что дела е тся эта с сылка ?
one two t h r e e f o u r
$ for arg ; do echo $arg ; done
one
two
three
four

$

После выполнения команды s e t все действует, как и предполагалось. В част­
ности, переменные $ # , $ * и цикл for без списка - все эти элементы отражают
изменения в значениях позиционных параметров.
Команда s e t нередко применяется подобн ым образом для "синтаксического
анализа" данных читаемых из файла или терминала. В качестве примера н иже
приведена программа wo rds, подсчитывающая количество слов, н абранных в
строке (т.е. "слов" в том смысле, в каком они определяются в оболочке).
$ cat words
#
# П одс ч итат ь сло в а в с тро ке

#
read l i ne
s e t $ l ine
echo $ #
$ words

Here ' s
7

а

Выполнить программу

line for you to count .

$

Данная программа читает вводимые пользователем данные, сохраняя сначала
прочитанную строку в переменной оболочки l i ne, а затем выполняя следующую
команду:
set $ l i n e

В итоге каждое слово, сохраняемое в переменной l i ne, присваивается соот­
ветствующему пози ционному параметру. А в переменной $ # устан авливается
значение, обозначающее количество присвоен н ых слов, которое равно количе­
ству слов в прочитан ной строке.
Па р ам етр - -

Описанный выше способ вполне работоспособен. Но что, если пользователь
начнет по какой - н ибудь причине ввод дан ных со знака ? Рассмотрим следующий
пример:
-

296

Гл а в а 1 1 .

Допол н ител ь н ы е сведен ия о параметрах

$ words
-1 + 5
4
wo rds : - 1 : bad opt i o n ( s )
$

В данном случае произошло следующее: после того, как введен ная пользова­
телем строка была прочитана и присвоена переменной l i ne, в оболоч�е была
выполнена приведенная ниже команда.
s e t $ l in e

А после подстановки значения переменной l i ne эта команда приобрела сле­
дующий вид:
set

-1 + 5 = 4

В ходе выполнения данной команды оболочка обнаружила знак - и восприня­
ла его как неверно введенный параметр - 1 . Именно этим и объясняется появле­
ние приведенного выше сообщения об ошибке.
Еще один недостаток программы words проявляется в том случае, если пере­
дать ей строку, полностью состоящую из символов пробела или пустую строку,
как демонстрируется в следующем примере:
$

words

Про сто нажа ть кла вишу
C D PATH= . : / u s e r s / s t e ve : / u s r / s p o o l
E D I TOR= / b i n / v i
HOME = / u s e r s / s t e v e
I FS =

LOGNAМE = s t e ve
МA I L = / u s r / sp o o l /rna i l / s t e ve
МA I LCHECK= 6 0 0
PAT H = / b i n : / u s r / b i n : / u s e r s / s t e ve / b i n : . :
PHONEBOOK= / u s e r s / s t e ve / phonebo o k
PS1=$
PS2=>
PWD= / u s e r s / s t e ve /mi s c
S H E L L= / u s r / b i n / s h
TERМ= x t e rm
TMOU T = O
T Z = E S T 5 E DT
cmd=wc
х=*

о

$

В данном случае оболочка обнаружила команду s e t без аргументов. Следо­
вательно, она вывела список всех переменных, установленных в среде данного
пользователя.

Ком а нда set

297

Чтобы застраховаться от подобн ых осложнений, команду s e t следует приме­
нять с параметром - - , который предписывает ей и нтерпретировать в качестве
параметров любые последующие знаки дефиса или слова, обнаруживаемые в ко­
мандной строке в форме аргументов. Такая мера предохраняет также от вывода
всех переменных, установленных в среде данного пользователя, если в командной
строке отсутствуют аргументы, как это произошло в приведенном выше примере,
где была введена пустая строка.
Таким образом, в строку с командой s e t в программе words необходимо вне­
сти следующее изменение:
set - - $ l ine

Если дополн ить программу words циклом whi l e, где выполняется вполне
определенная целочисленная арифметическая операция, как показано ниже, эта
программа сможет подсчитывать общее количество слов, прочитанных из стан­
дартного ввода. По существу, она станет разновидностью команды wc -w.
$

cat words

#
# П одсчитат ь в се с л о в а , прочитанные из стандартно го в вода
#
count = O
wh i le r e a d l i ne
do
set - - $ l i ne
coun t = $ ( ( count + $ #
done

) )

e cho $ c ount
$

Прочитав каждую строку из стандартного ввода, команда s e t присвоит новые
данные из этой строки позиционным параметрам, а в переменной $ # установится
количество слов в данной строке. Параметр - - указан в команде s e t на тот слу­
чай, если читаемые строки будут начинаться со знака -, окажутся пустыми или не
будут вообще состоять из буквенно-цифровых символов.
Далее значение перемен ной $ # прибавляется к значению переменной count
и читается следующая строка. После выхода из цикла в связи с обнаружением
конца ' файла отображается значение переменной coun t, т.е. общее количество
прочитанных слов. Ниже демонстрируется применение новой версии программы
wo rds в сравнении с командой wc -w.
$ words <
567
$ wc - w <
5 67
$

/etc/passwd
/etc/pas swd

Пров ерить полученный резуль т а т
с помош,ью кома нды wc

Гл а в а 1 1 .

298

Дополн ител ьные сведения о параметрах

Безусловно, в программе words применяется довольно необычный способ
подсчета количества слов в файле. Но в то же время в ней демонстрируется, на­
сколько универсальной может быть команда s e t, о чем известно далеко не всем
пользователям систем Unix. В качестве еще одного при мера применения данной
команды ниже приведен краткий способ подсчета количества файлов в каталоге.
$
$
8
$

set *
echo $#

Такой способ позволяет намного быстрее подсчитать количество файлов в ка­
талоге, чем следующая последовательность команд:
ls

1

wc - 1

поскольку в нем применяются только команды, встроенные в оболочку. В целом
программы оболочки будут выполняться намного быстрее, если постараться ре­
ализовать в них как можно больше операций с помощью команд, встроенных в
оболочку.
Другие п а р а м етр ы к ом анды set
Команда s e t принимает ряд других параметров, каждый из которых активи­

зируется предваряющим знаком - и дезактивируется предваряющим знаком + .
Чаще всего применяется рассмотренный выше параметр -х, а остальные параме­
тры данной команды перечислены в табл. А.9 приложения А.
П е р е м е н н а я I FS

В оболочке имеется специальная переменная I FS, сокращенное имя кото­
рой обозначает внутренний разделитель полей (internal field separator). Значение
этой переменной употребляется в оболочке при синтаксическом анализе ввода
из команды re ad, вывода из команды, подставляемой с помощью механизма об­
ратных кавычек, а также при подставке значений переменных. Короче говоря,
переменная I FS содержит ряд символов, употребляемых в качестве пробельных
разделителей. Если эта перемен ная введена в командной строке, оболочка интер­
претирует ее значение как пробельный символ, обыкновенно применяемый для
разделения слов.
Приведенное выше пояснение назначения переменной I FS может показать­
ся не вполне вразумительным! Следовательно, чтобы выяснить, какие же имен­
но символы хранятся в данной перемен ной , ее значение достаточ но передать по
каналу из команды e cho команде od (т.е. восьмеричный вывод содержимого) с
параметром -Ь (т.е. побайтовое отображение), как показано ниже.

Пе ременная I FS

$

299

echo "$ IFS " 1 od -Ь

0000000 040 0 1 1 012 012
0000004
$

В первом столбце приведенных выше чисел указано смещение относительно
начала ввода. А последующие числа являются восьмеричными эквивалентами
символов, прочитан ных командой od. Первым их них указано восьмеричное чис­
ло 0 4 0 , обозначающее символ пробела в коде ASCII. Далее следует восьмеричное
число 0 1 1 , обозначающее символ табуляции в коде ASCII, а затем восьмеричное
число 0 1 2 , обозначающее символ новой строки в том же самом коде. После этого
следует еще один символ новой строки, добавленный командой e cho. Нет ничего
удивительного в том, что именно этот ряд символов содержится в перемен ной
I FS. Ведь все они относятся к категори и пробельных символов, не раз упоминав­
шихся в данной книге.
Как отмечалось ранее, оболочка удаляет начальные пробельные символы из
любой строки, прочитанной командой r e ad. Но если установить в переменной
I FS только символ новой строки перед выполнением команды read, то началь­
ный си мвол новой строки останется в прочитанной строке, поскольку оболочка
не воспримет его как разделитель полей.
$

read line

Выполнить кома нду read "старым " спосо бом

Here ' s

$

l ine

echo "$1ine "

Here ' s

l i ne

а

>

IFS="
"

$

read line

$

echo "$1ine "

$

а

Уста новить в переменной IFS толь ко
зна к но в ой с троки
Выполнить кома нду read снова

Here ' s
Here ' s

а

l ine

а

l ine

На чаль ные про белы о стались

$

Чтобы установить в переменной I FS только знак новой строки, в данном при ­
мере была введена открывающая кавычка, после которой сразу же была нажата
клавиша , а с новой строки - закрывающая кавычка. Между этими ка­
вычками н икаких дополнительных символов не вводится, поскольку они будут
сначала сохранены в переменной I FS, а затем употреблены в оболочке.
А теперь попробуем установить в переменной I FS нечто более видимое знак двоеточия:
$
$

IFS= :
read х

у

123 : 345 : 678
$

echo $х

123

z

300

$

Гл а в а 1 1 .

Допол н ител ьные сведен ия о пара метрах

echo $z

678
$ list="one : two : three "
$ for х in $list ; do echo
one
two
three
$ var=a : b : c
$ echo "$var "
а:Ь:с
$

$х ; done

В первом из приведенных выше примеров в переменной I FS был установлен
знак двоеточия, и поэтому, прочитав строку, оболочка сначала разделила ее на
три слова ( 1 2 3 , 3 4 5 и 67 8), а затем сохранила их в переменных х, у и z . В сле­
дующем примере переменная I FS была использована при подстановке значения
переменной l i s t в цикле f o r . А в последнем примере демонстрируется тот факт,
что переменная I FS не используется, когда переменной var присваи вается зна­
чение.
Изменение значения в переменной I FS нередко выполняется вместе с коман­
дой s e t, как демонстрируется в следующем примере:
$ line= "Мicro Logic Corp . : Box 1 7 4 : Hackensack , NJ 0 7 60 2 "
$ IFS= :
$ set $line
Сколь ко параме тров было уста новл е но ?
$ echo $#
3
$ for field ; do echo $field ; done
M i c r o Log i c C o rp .

Вох 1 7 4
Hackensac k , N J 0 7 6 0 2
$

Такой способ оказывается эффективным потому, что в нем применяются все
встроенные в оболочку команды, заметно ускоряющие выполнение программ.
Именно этот способ применяется в окончательной версии программы rol o,
представленной в главе 13.
Н иже приведена программа, которая называется numЬe r2 и является окон­
чательной версией программы numЬer, предназначенной для нумерации строк
и представленной в главе 9. В этой программе введенные строки направляются в
стандартный вывод с предшествующим номером строки, а содержимое перемен­
ной I FS видоизменяется с целью сохранить и воспроизвести начальные пробелы
и остальные пробельные символы, в отличие от предыдущей версии данной про­
граммы. Обратите также внимание на применение команды p r i n t f для вырав­
нивания номеров строк по правому краю.

Кома нда readon ly

$

301

cat numЬer2

#
# Пронумерова т ь с тро ки , введенные из файла , заданного
# в каче стве ар гуме нт а , или и з с т андартно г о в в ода , е сли
# файл не ука зан - окон чатель на я верси я
#
# Видоизме нит ь содержимое переме нной IFS , что бы
# со храни т ь началь ные пробелы при в воде с тр о к
I FS = '
# В ка выч ки з а ключа е т с я лишь зн а к но вой с тро ки
l i neno = l
cat $* 1
wh i l e read - r l i ne
do
p r i n t f " 'l, Sd : 'li s \ n " $ l i n e n o " $ l i n e "
l i ne n o = $ ( ( l i n e n o + l ) )
done

Ниже приведен пример выполнения программы numЬe r 2 .
$

numЬer2 words
1:#
2 : # Подсчита т ь все сло в а ,

прочи т анные из с тандартно г о в вода

3:#
4:
S : count=O
б : wh i l e r e a d l i ne
7 : do
8:
set $ l ine
coun t = $ ( ( c o u n t + $ #
9:
l O : done
11 :
l 2 : e ch o $ co u n t
-

) )

$

Значение переменной I FS оказывает влияние на порядок интерпретации вво­
димых данных в оболочке. И если его требуется изменить в программе, то целесо­
образно сохранить прежнее значение данной переменной (например, в перемен­
ной or'FS), а затем восстановить его по окончании соответствующих операций.
К ом а нда readonly

Эта команда применяется для обозначения тех переменных, значения которых
не подлежат последующему изменению. Например, в следующей команде:
r e adon l y РАТН НОМЕ

302

Гл а в а 1 1 .

Допол н ител ьн ы е сведе н и я о п а ра метрах

переменные РАТН и НОМЕ обозначаются как доступные только для чтения.
При последующих попытках присвоить значение любой из этих переменных обо­
лочка выдаст сообщение об ошибке, как демонстрируется в следующем примере:
$ PATH=/bin : /usr/bin : . :
$ readonly РАТН
$ PAТН=$PATH : /users / s teve/bin
s h : РАТН : is r e a d - o n l y
$
В

данном примере демонстрируется следующее: после того, как переменная

РАТН была сделана доступной только для чтения, оболочка вывела сообщение об

ошибке при попытке присвоить ей значение. Чтобы перечислить переменные, до­
ступные только для чтения, достаточно ввести команду readonl у -р без аргу­
ментов:
$ readonly -р
readon l y PATH= / b i n : / u s r / b i n : . :
$

Атрибут "только для чтения" не передается от переменной к подоболочкам.
А после того, как переменная станет доступной в оболочке только для чтения,
"отменить" этот ее атрибут нельзя н и коим образом.
К о м а нда uns e t

Иногда требуется удалить определение переменной и з своей среды. С этой це­
лью достаточно ввести команду uns et, указав далее имена перемен ных:
$ x=lO O
$ echo $ х
100
$ unset х
$ echo $х
$

Уда лить переменную х из текущей среды

Но по команде uns e t из среды нельзя удалить переменную, доступную только
для чтения. Более того, из среды нельзя удалить переменные I FS, МA I LCHECK,
РАТН, P S l и P S 2 .

12

Нев ыясненн ы е в о п росы
В этой главе рассматриваются команды и средства оболоч ки, не охваченные в
предыдущих главах. Они не рассматриваются здесь в каком-то обоснованном по­
рядке, и поэтому вы вольны воспользоваться материалом этой главы, чтобы рас­
ширить свои знания приемов и методов программирования на языке оболочки.
К о м а нда eval

В этом разделе описывается eva l
одна из самых необычных команд обо­
лочки. Ее общая форма выглядит следующим образом:
-

eval кома ндная стро ка
_

где кома ндна я_ стр ока это обычная командная строка, вводимая с термина­
ла. Но если указать такую командную строку после команды eva l , то оболоч ка
просмотрит ее два жды, прежде чем выполнять ее. Это может быть удобно, если в
сценарии составляется команда, которую, помимо всего прочего, требуется вы­
звать.
В простейшем случае применение команды eva l не дает н икакого эффекта,
как демонстрируется в следующем примере:
-

$ eval echo hel lo
he l l o

$

А

теперь рассмотрим следующий пример, где команда eva l не применяется:

$ pipe=" 1 "
$ ls $pipe

WC

-1

1 :

No s u ch f i l e o r d i re c t o r y
wc : No s uch f i l e o r d i r e c t o r y
- 1 : N o , s u ch f i l e o r d i r e c t o r y

$

Сообщения об ошибках выводятся из команды 1 s потому, что значение пере­
менной pipe и результат последующего вызова команды wc - 1 интерпретируют­
ся как аргументы команды 1 s. Оболочка берет на себя заботу о каналах и переа­
дресации ввода-вывода перед подстановкой значения переменной, и поэтому она
вообще не интерпретирует символ канала в переменной p i p e . Но если указать

304

Гn а в а 1 2 .

Н евыясненные воп росы

команду eval перед рассматриваемой здесь последовательностью команд, то
можно добиться желаемого результата:
$ eval
16
$

ls $pipe wc -1

Когда оболочка просматривает командную строку в первый раз, она подстав­
ляет знак 1 в качестве значения переменной pipe. А команда eva l вынуждает
оболочку просмотреть командную строку во второй раз. В этот момент знак 1
распознается оболочкой как символ канала, и все остальное продолжается далее,
как и предполагалось.
Команда eva l нередко применяется в тех программах оболоч ки, где команд­
ные строки составляются в одной или нескольких переменн ых. И команда eva l
оказывается весьма полезной в том случае, если эти переменные содержат любые
символы, которые интерпретируются в оболоч ке. В частности, ограничители ко­
манд ( ; , 1 , &), знаки переадресации ввода-вывода (), а также знаки кавычек
должны быть указаны непосредственно в командной строке, чтобы иметь особое
назначение в оболочке.
В качестве следующего примера рассмотрим программу l a s t, единственное
назначение которой - отобразить аргумент, переданный последним. Напомним,
что в программе mycp, рассматривавшейся в главе 9, дан ная задача выполняется
смещением всех аргументов до тех пор, пока не останется один аргумент. Но того
же самого результата можно добиться и с помощью команды eva l следующим
образом:
$

cat last

eval e ch o \ $ $ #
$

last one two three four

four
$

last *

Получи т ь по следний файл

z o o repo r t
$

-

Когда оболочка просматривает в первый раз командную строку
echo \ $ $ #

знак обратной косой черты предписывает ей прои гнорировать следующий далее
знак $. После этого она обнаруживает специальную переменную $# и поэтому
подставляет ее значение в командной строке. В итоге анализируемая команда
при мет следующий вид:
echo $ 4

Ком а н да wait

305

Знак обратной косой черты удаляется оболочкой после первого просмотра ко­
мандной строки. А при втором ее просмотре оболочка подставляет сначала значе­
ние позиционного параметра $ 4, а затем выполняет команду e cho.
Тем же самым способом можно было бы воспользоваться и в том случае, если
бы в командной строке имелась переменная a rg, содержавшая, например, цифру,
и при этом требовалось отобразить позиционный параметр по ссылке на пере­
менную arg. В таком случае можно было бы написать следующую строку:
e va l e cho \ $ $ a r g

Единственный недостаток такого подхода заключается в том, что подобным
способом оказываются доступными только первые девять позиционных параме­
тров. Ведь для доступа к позиционным параметрам свыше 10 -го потребуется кон­
струкция $ { п } . Поэтому сделаем еще одну попытку:
e va l e cho \ $ { $ a r g )

Команда e va l , по существу, применяется для создания "указателей" на пере­
менные, как демонстрируется в следующем примере:
$
$
$

x=lOO
ptrx=x
eval echo \$$ptrx

100

$

eval $ptrx=50

$

echo $х

50

Ра зымено в а ть ука за тель ptrx
Сохр а нить зна чение 50 в п еременной ,
н а которую ука зыв а е т переменна я ptrx
Выяснить , к чему это прив ело

$

К ом а нда wai t

Если перенести команду на выполнение в фоновый режим, она будет выпол ­
няться в подоболочке независимо о т текущей оболочки (в этом случае говорят,
что задание выполняется асинхронно) . Но иногда требуется подождать завер­
шения фонового процесса, называемого также порожденным, поскольку он по­
рожден родительским процессом в текущей оболочке, прежде чем продолжить
выполнение. Например, круп ное задание по сортировке может быть отправлено
на выпо!1 нение в фоновый режим, а для доступа к отсортированным данным при ­
дется ждать завершения этого задания. Именно для этого и предн азначена коман­
да wa i t, общая форма которой выглядит следующим образом:
wa i t идентифика тор_ проце сса

где идентифика тор_ пр оце сса обозначает тот процесс, завершения которого
требуется подождать. Если идентификатор процесса не указан, оболочка ожида­
ет завершения всех порожденных процессов. В этом случае выполнение текущей

306

Гл а в а 1 2 .

Невыяснен ные воп рос ы

оболочки будет приостановлено до тех пор, пока не завершится ожидаемый про­
цесс или ряд процессов.
Команду wa i t можно попробовать запустить на выполнение с терминала сле­
дующим образом:
$

sort big-data > sorted data &

[1]

3423

$ date
Wed Oct 2 1 5 : 0 5 : 4 2 E DT 2 0 0 2
$ wai t 3423

Отпра вить зада ние на
сор тир овку в фоновый р ежим
Номер зада ния и идентифика тор
проце сса от о боло чки
Выполнить другое з ада ние
А тепер ь ожида ть за в ершения

з ада ния на сор тир овку
$

П еремен н а я $ !

Если в фоновом режиме выполняется лишь оди н процесс, то для ожидания его
завершения достаточно указать команду wai t без аргументов. Но если в фоно­
вом режиме выполняется несколько процессов и требуется подождать заверше­
ния только того процесса, который был запущен самым последним, то для досту­
па к его идентификатору можно обратиться к специальной переменной $ ! . Таким
образом, следующая команда:
wa i t $ !

означает ожидание завершения того процесса, который был последним отправ­
лен на выполнение в фоновом режиме. Идентификаторы процессов можно также
хранить в ряде промежуточ ных перемен ных для последующего доступа, как де­
монстрируется в следующем примере:
progl &
pid1=$ !
prog2 &
pid2=$ !
wa i t $ p i d l

# ожида т ь з а вершения програ:ммы

progl

wa i t $ p i d 2

# ожида т ь за вершения про граммы

prog2

Чтобы проверить, выполняется ли запущенный процесс по-прежнему, доста­
точно вызвать команду ps с параметром -р и идентификатором данного процесса.
К о м а нда trap

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

Ком анда tra p

307

получаете приглашение ввести следующую команду. Но это не всегда желательно
в программах оболочки. Ведь в конечном итоге у вас может оказаться целый ряд
временных файлов, которые не будут удалены, как это обычно происходит при
нормальном завершении программы.
При нажатии клавиши выполняющейся программе посылается
так называемый сигнал. В программах можно указать действие, которое следует
выполнить при получении данного сигнала, вместо того чтобы опираться на та­
кие выполняемые по умолчанию действия, как н емедленный выход из текущего
процесса.
Обработка сигнала в программе оболочки выполняется по команде trap, об­
щая форма которой выглядит следующим образом:
t rap кома нды сигналы

где кома нды обозначает одну или больше команд, которые будут выпол няться
всякий раз, когда получаются указанные сигналы
Наиболее употребительные мнемонические имена и номера, присваиваемые
разным типам си гналов, перечислены в табл . 1 2. 1 . Более полный их перечень
можно найти в описании команды t r ap, приведенном в приложении А.
Табли ца 12 . 1. Наиболее употребительные
мнемон ические имена и номера с и гналов

С и гнал

Мнемон ическое и м я Ко гда генерируется

о
1

При выходе из оболочки

2

EXI T
HUP
INT

15

ТЕRМ

При получении сигнала о завершени и программы ( по
умолчанию этот сигнал посылается командой k i l l )

При зависании программы
При прерывании ( например, в результате нажатия кла­
виши < DELETE> или комбинации клавиш < Ctrl+c>)

В приведенном ниже примере выполнения команды t rap демонстрируется,
каким образом сначала удаляются некоторые файлы, а затем происходит выход
из программы, если кто-нибудь попытается прервать программу с терминала.
t rap " rm $ WORKD I R/ wo r k l $ $ $ WORK D I R / da t a o u t $ $ ; e x i t " I N T

Как только эта команда t rap будет выполнена, оба файла, wo r k l $ $ и
da taou t $ $ , будут автоматически удалены, если программа получит сигнал
S I G I NT (под номером 2). Если же пользователь прервет выполнение программы
по завершении данной команды t rap, то оба указанных в ней временных файла
будут удалены из файловой системы. Команда exi t , следующая после команды
rrn, необходима потому, что без нее программа продолжит свое выполнение с того
места, где был получен сигнал.

308

Гн а в а 1 2 .

Н евыяснен ные воп росы

Сигнал номер 1 ( S I GHUP или просто HUP) генерируется при зависании про­
граммы. Первоначально это было связано с установлением коммутируемых со­
единений, но теперь это, как правило, означает неожиданный разрыв соединения,
аналогичного подключени ю к Интернету. Так, если вернуться к приведенному
выше примеру команды t r ap, то, добавив сигнал S I G I NT (или просто I N�) в пе­
речень сигналов, оба указанных в ней файла можно удалить и в случае зависания,
как показано ниже. Если теперь линия связи зависнет или же пользователь пре­
рвет обработку, нажав клавишу < DELETE> или комбинацию клавиш ,
оба указанных файла будут удалены.
t rap " rm $ WORKD I R / wo r k l $ $ $WORKD I R / d a t a o u t $ $ ; e x i t ' '

INT HUP

Последовательность команд, указанная в команде t rap и называемая обра­
бот чиком прерываний, должна быть заключена в кавычки. Следует также иметь в
виду, что оболочка просматривает командную строку, когда выполняется коман­
да t r ap, и делает это снова, когда получается оди н из сигналов, перечисленных в
данной команде.
В приведенном выше примере значения переменных WORKD I R и $ $ подставля­
ются в момент выполнения команды t rap. Если же требуется, чтобы подстанов­
ка произошла в момент получения си гнала, последовательность команд следует
заключить в одиночные кавычки:
t rap

' rm $WORKD I R / wo r k l $ $ $WORKD I R / d a t a o u t $ $ ; e x i t '

I NT H U P

Команда t rap может быть использована и для того, чтобы сделать разрабаты­
ваемые программы более удобными для пользователей. Так, при рассмотрении
программы rolo в следующей главе в нее будет внесено изменение, предусма­
тривающее перехват сигнала при нажатии комбинации клави ш , а также
возврат к основному меню пользователя, а не к полному выходу из программы.
Команда trap без а р гу мен то в

Выполнение команды t rap без аргументов приводит к отображен ию любых
определенных или видоизмененных обработч иков прерываний, как демонстри ­
руется в следующем примере:
$ trap ' echo logged off at $ (date) >>$HOМE/ logoffs ' EXIT
$ trap
Пере числить измененные прерыв а ния
t rap - ' e cho l o g g e d o f f a t $ ( da t e ) > > $ HOME / l o g o f f s ' EX I T
Выйти из сис темы
$ Ctrl+d
Снов а в ойти в систему
l o g i n : steve
P a s sword :
Выяснить , что пр оиз ошло
$ cat $HOМE / logoffs
l og g e d o f f at Wed O c t 2 1 5 : 1 1 : 5 8 E DT 2 0 0 2
$

Кома н да tга р

309

Прерывание должно устанавливаться в данном примере всякий раз, когда про­
исходит выход из оболочки (после получения сигнала О или E X I T ) . А посколь­
ку это преры вание было установлено в исходной оболочке, то обработчик пре­
рываний используется при выходе из системы для записи времени наступления
данного события в файле $ НОМЕ / logo f f s . В данном случае последовательность
команд заключена в одиночные кавычки для того, чтобы предотвратить выполне­
ние команды da te в оболочке при определении прерывания.
Затем в данном примере выполняется команда t rap без аргументов, перечис­
ляющая новое действие, которое должно быть выполнено по сигналу О или EX I T .
Когда ж е пользователь s t eve выходит из системы и снова входит в нее, в файле
$ НОМЕ / l ogo f f s проверяется, была ли выпол нена команда e cho и сработало ли
прерывание.
И г но р и р о в а н и е си г на л о в

Если в команде t rap указан пустой список команд, заданный сигнал будет
проигнорирован при его получении. Например, в команде
t r ap

11 11

S I G I NT

указывается, что сигнал прерывания должен быть проигнорирован. При выпол ­
нении отдельной операции может возникнуть потребность проигнорировать
определенные сигналы, чтобы не прерывать ее.
Следует, однако, иметь в виду, что команда t rap позволяет указывать сигна­
лы по их номеру, сокращенному ( I NT) или полному наименованию ( S I G I NT).
В связи с этим рекомендуется пользоваться мнемоническими именами сигналов,
чтобы повысить удобочитаемость исходного текста программ . Хотя это, конечно,
дело личных предпочтений.
В приведенном выше примере в качестве первого аргумента следовало указать
пустое значение, чтобы проигнорировать сигнал. Но это не равнозначно написа­
нию следующей команды, которая имеет отдельное назначение:
t r ap 2

Если сигнал игнорируется, он игнорируется и во всех подоболочках. Но если
указать действие для обработки прерывания, то при получении данного сигна­
ла во всех подоболочках будет автоматическивыполнено действие, заданное по
умолчанию, а не новая последовательность команд.
Допустим, что сначала выполняется следующая команда:
'

t r ap

11 11

2

а затем запускается подоболочка, где, в свою очередь, другие программы оболоч­
ки выполняются как подоболочки. Если далее сгенерируется сигнал прерывания,
он не окажет никакого влияния на выполняющиеся оболочки или подоболочки,
поскольку он будет проигнорирован в них по умолчанию.

310

С1 а в а :1. 2 .

Н евыяснен н ы е воп рос ы

А если вместо предыдущей команды выполнить сначала следующую команду:
t r ap

2

а затем запустить на выполнение подоболочки, то в текущей оболочке не будет
предпринято никаких действий при получении прерывания (т.е. фактиче'ски бу­
дет выполнена пустая команда), тогда как действие подоболочек будет (по умол­
чанию) прервано.
Сбр о с п рер ы в а н и й

Если действие, предпринимаемое по умолчанию при получении сигнала, было
изменено, его можно восстановить по команде t r ap, опустив в ней первый аргу­
мент. Таким образом, по следующей команде:
t r ap HUP I NТ

сбрасывается действие, предпринимаемое при получении сигнала S I GHU P или
S I G I NT, и восстанавливается режим работы оболоч ки по умолчанию.
Во многих программах оболочки применяется также конструкция, аналоги ч­
ная следующей:
t r ap " /Ь i n / rm -f $ t emp f i l e ;

e x i t " I NТ QU I T EX I T

чтобы команда r m не выводила сообщение о б ошибке, если временный файл еще
не был создан после выхода. Обработчи к прерываний удаляет временный файл,
если он существует, но ничего не делает, если он отсутствует.
Д о п ол н ит е л ь н ы е св еден и я
о б о р га н и з а ц и и в в ода- в ы вода

Как известно, стандартные конструкции и >> служат для переадресации
ввода, вывода и вывода с присоединением соответственно. Известно также, что
стандартный вывод ошибок можно переадресовать из любой команды, просто
указав 2> вместо > в следующей конструкции:
кома нда 2 > фа йл

Иногда в программе требуется явным образом направить сообщения в стан­
дартный вывод ошибок. Внеся незначительное изменение в предыдущую кон­
струкцию, стандартный вывод можно переадресовать в стандартный вывод оши­
бок следующим образом:
кома нда > & 2

Конструкция > & обозначает переадресацию вывода в файл, связанный с ука­
занным далее дескриптором файла. В частности, дескриптор файла О обозначает

Дополн ител ьн ы е свед ен ия об орга н иза ц и и в вода - в ы вод а

31 1

стандартный ввод, дескриптор файла 1 стандартный вывод, а дескриптор фай­
ла 2 стандартный вывод ошибок. Очень важно запомнить, что между знаками
> и & не должно быть пробела. Например, направить сообщение в стандартный
вывод ошибок можно следующим образом:
-

-

echo " I nva l i d nwnЬe r of a rgume n t s " > & 2

Иногда требуется переадресовать как стандартный вывод (зачастую обознача­
емый сокращенно как s tdout), так и стандартный вывод ошибок (нередко обо­
значаемый сокращенно как s tde r r ) из программы в оди н и тот же файл. Если из­
вестно имя файла, это нетрудно сделать, используя приведенную ниже конструк­
цию, где стандартный вывод s t dout и s tde r r переадресовывается в указанный
файл имя_ фа йла .
кома нда > имя_ файла 2 > > имя_ фа йла

Чтобы добиться того же самого результата, можно воспользоваться следую­
щей конструкцией:
кома нда > имя_ файла 2 > & 1

где стандартный вывод переадресовывается в указанный файл имя_ файла, а
стандартный вы вод ошибок - в стандартный вывод, который уже переадресо­
ван в указанный файл имя_ файла. Но поскольку оболочка определяет порядок
переадресации в командной строке слева направо, то последовательность команд
в последнем примере будет выполнена неверно, если переадресация в стандарт­
ный вывод s tde r r указана в командной строке первой, как показано ниже. Ведь
в этом случае сначала будет выпол нена переадресация результатов выполнения
заданной кома нды в стандартный вывод ошибок, а затем переадресация стан­
дартного вывода в указанный файл имя_ файла.
кома нда 2 > & 1 > имя_ фа йла

Стандартный ввод или вывод можно также динамически переадресовать в
своей программе, используя команду е х е с следующим образом:
е х е с < da t a f i l e

В данном примере стандартный ввод переадресовывается в указанный файл
data f i l e . И тогда последующие команды, читающие данные из стандартного
ввода, будут читать их из указанного файла da ta f i l e . То же самое делается в
следующей команде:
ехес > / tmp / o u t p u t

где все последующие команды, направляющие данные в стандартный вывод, на­
правляют их в указанный файл / tmp / output, если только не указано явно ка­
кое-нибудь другое место их переадресации.

312

Гл < ш / tmp / e r r o r s

Кон струкци и < & - и > & -

Конструкция >&- оказывает действие закрытия стандартного вывода. Если
эта конструкция предваряется дескриптором файла, то закрывается соответству­
ющий файл, а не стандартный вывод. Таким образом, команда
ls > & -

направляет результат своего выполнения в "никуда", поскольку стандартный вы­
вод закрывается оболоч кой перед выполнением команды l s . Следует, однако,
признать, что пользы от этого практически никакой !
Встр а и в а е ма я п ер е ад рес а ция вв ода

Если последовательность символов

Удалить текущее слово

emacs

352

Гh а в а 1 4 .

И нтера кти в н ы е и неста нда ртные средства оболочки

Окончание табл. 1 4.2
Ко ма н д а

Н азначен ие

Символ отирания

< Ctrl+p>

Удалить предыдущи й сим вол ( символ стирания определяется
пользователем; как правило, это знак # или комбинация клавиш
< Ctrl+h>)
Получить предыдущую команду из предыстории



Получить следующую команду из предыстории

строка

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

Д р у г и е с п особы доступ а к п р ед ы сто р и и ко м а нд

Имеются и другие способы доступа к предыстори и команд, о которых стоит
знать на тот случай, если вам не подойдет ни оди н из рассмотрен ных выше режи­
мов редактирования строк в редакторе vi или ema c s .
Команда hi s tory

Чтобы получить доступ к предыстории команд, проще всего ввести команду
hi s tory:
$ history
507
508
509
510
511
512
513
514
515
516
517
518
519
52 0
52 1
522

c d she l l
c d ch 1 5
vi int
ps
e cho $ Н I S T S I Z E
c a t $ ENV
ер i n t i n t . s v
hi story
exit
cd s h e l l
cd c h l б
vi all
run - n 5 a l l
ps
l p r a l l . ou t
h i s tory

Слева о т команд указаны их относительные номера. Так, команда номер 1 счи­
тается первой или самой давней в предыстории.
Но следует иметь в виду, что действие команды h i s tory несколько отличает­
ся в оболочках Korn и Bash. Так, в оболочке Korn команда hi s tory направляет в
стандартный вывод 1 6 последних команд, тогда как в оболочке Bash всю преды­
стори ю команд, даже если она состоит из 500 или 1 000 строк.
-

Другие способы доступа к п редыстори и команд

353

Если вы работаете в оболочке Bash и не желаете выводить сразу всю преды­
сторию, укажите в качестве аргумента количество одновременно отображаемых
команд, как показано в следующем примере:
$ history 10

ер i n t i n t . s v
history
exit
cd s he l l
c d ch l б
vi all
run - n 5 a l l
ps
l p r a l l . ou t
history 10

513
514
515
516
517
518
519
520
521
522

$

Кома нда fc

Эта команда позволяет запустить редактор по одной команде или больше из
предыстории или направляет сп исок команд из предыстории на терми нал. Она
действует аналогично команде h i s t or y, но только в более удобной форме, где с
помощью параметра - 1 можно указать количество выводимых из предыстории
команд. Например, команда
fc -1 5 1 0 5 1 5

направляет в стандартный вывод команды под номерами 5 1 0 - 5 1 5, а команда
fc -n

-1

-20

последние 2 0 команд, опуская и х номера ( с помощью параметра n ) Допустим,
что вы только что выполнили длинную команду и решили, что было бы неплохо
преобразовать введен ную командную строку в программу оболочки под назва­
нием runx. Используя команду fc, вы можете получить команду из своей пре­
дыстории и переадресовать ввод-вывод, чтобы записать данную команду в файл,
как показано ниже.
-

f c - n -1

.

-1 > runx

В данном примере число - 1 , указан ное после параметра 1, обозначает извле­
чение самой последней команды из предыстории, т.е. с отступом на одну команду
от текущей команды вглубь предыстории. Более подробно команда fc рассма­
тривается в приложении А.
Кома нда r

Эта простая команда оболочки Korn позволяет повторно выполнять предыду­
щие команды нажатием нескольких клавиш. Достаточно ввести команду r, чтобы
оболочка Korn повторно выполнила последнюю команду, как демонстрируется в
следующем примере:

354

Гл а в а 1 4 . И нтеракт и в н ы е и неста нда ртн ые с редства оболочки

$ date
Thu O c t 2 4 1 4 : 2 4 : 4 8 E S T 2 0 0 2
Повторно выполнить предыдущую кома нду
$ r
da t e
Thu Oct 24 1 4 : 2 5 : 1 3 EST 2 0 0 2

$
'

Как только вы введете команду r, оболочка Korn повторно отобразит предыдущую команду и сразу же выполнит ее. Если вы укажете в команде r имя коман­
ды в качестве аргумента, оболочка Korn повторно выполнит самую последнюю
из вашей предыстории команду, начинающуюся с заданного шаблона. И в этом
случае оболочка Korn сначала выведет командную строку из предыстории, а за­
тем выполнит ее автоматически, как показано ниже.
$ cat docs/planA
$ pwd
/ u s e r s / s t e ve
Воз вра тить по следнюю кома нду ca t

$ r cat
c a t doc s / p l anA

$

И наконец, команда r позволяет заменить первое вхождение одной символь­
ной строки следующим ее вхождением. Чтобы повторно выполнить последнюю
команду cat для вывода содержимого файла p l anB вместо файла pl anA, доста­
точно ввести следующее:
$ r cat planA=planВ
cat doc s / p l an B

$

а еще проще:
$ r cat А=В
c a t doc s /p l anB
$

Аналогичная сокращенная команда имеется и в оболочке Bash. Так, команда
повторно
выполнить предыдущую команду, как показано ниже. Следует, однако, иметь в
виду, что знак ! и указанная строка вводятся подряд без пробела.
! с трока позволяет произвести поиск в предыстории·, а команда ! !

$ !!
c a t doc s /p l an B

$ !d
da t e
Thu Oct 24

$

1 4 : 3 9 : 4 0 EST 2 0 0 2

-

Фун к ц и и

355

Команду fc можно ввести с параметром -s, чтобы выполнить ту же самую
операцию в любой оболочке, совместимой со стандартом POSIX, как показано
ниже. А команда r , по существу, служит псевдонимом команды fc в оболочке
Korn (подробнее об этом - далее в главе).
$

fc -s cat

cat doc s / p l anB

$ fc -s В=С
c a t do c s /p l a nC
$

Ф у н к ци и

В оболочках Bash и Korn поддерживаются функции, н е доступные в оболочке,
совместимой со стандартом POSIX. Рассмотрим их более подробно в последую­
щих разделах.
Л о ка л ьн ы е п е р емен н ы е

В оболочках Bash и Korn функции могут иметь локальные переменные, бла­
годаря которым функции могут быть сделаны рекурсивными. Эти п еременные
определяются с помощью команды type s e t, как демонстрируется ниже. Если
перемен ная с таким же самым именем уже существует, она сохраняется при вы­
полнении команды type s e t и восстанавливается при выходе из функции.
t yp e s e t i j

Приобретя некоторый опыт работы в оболочке, вы можете разработать ряд
функций, чтобы постоянно пользоваться ими в интерактивных сеансах работы в
оболочке. Такие функции удобнее всего разместить в файле ENV, чтобы они опре­
делялись всякий раз, когда вы запускаете новую оболочку.
Автома ти ч е ски за груж аем ые фу н кции

В оболочке Korn можно установить специальную переменную F PATH анало­
гично переменной окружения РАТН. Если затем попытаться выполнить фун кцию,
которая еще не определена, оболочка Korn произведет поиск файла по имени дан ­
ной функции в разделяемом двоеточиями списке каталогов, указанных в пере­
менной FPATH. Если оболочка обнаружит такой файл, она выполнит его, предпо­
лагая, что в нем находится определение искомой функции.
Ц ел оч и сл е н н ы е а р и ф м е ти ч ес к и е о п е ра ци и

В оболочках Bash и Korn поддерживается вычисление арифметических выра­
жений без специального развертывания арифметического аппарата. С этой це­
лью используется синтаксис, аналогичный конструкции $ ( ( . . . ) ) , только без

Гп " )
Приглаше ние, употребляемое при отслеживании выполнения отлаживаемы х программ, когда задается параметр - х оболочки или вводится коман­
да set - х . П о умолчанию используется приглашен ие "+ "
Путь к текущему рабочему каталогу

П одста но вка п а р а метров

В простейшем случае значение параметра может быть доступ но по ссылке, где
номер параметра предваряется знаком денежной еди ницы ( $ ) . В табл. А.3 пере­

числены различные виды конструкций для подстановки значений параметров.
Оболочка подставляет параметры прежде подстановки имени файла и разделе­
ния командной строки на аргументы.
Наличие двоеточия после параме тра , указан ного в табл. А.3, обозначает,
что этот параме тр проверяется на наличие в нем непустого значения. Есл и же
двоеточие отсутствует, то параметр проверяется только на установку в нем
значения.

П озицио н н ы е па раметры

381

Таблица А. З . К о н струкции дл я подста н ов к и з н а че н и й параметров

Конструкц ия

Назначение

$паране!l'р или $ { параме!I'р} Подставить значение указанного параме!l'ра
$ { параме!l'р : - зна чение}
Подставить значение указанного параме!l'ра, если зада­
но непустое его значение, а иначе - заданное значение
$ { параме!l'р-зна чение }
Подставить значение указанного параме!l'ра, если задано его значение, а иначе - заданное значение
$ { параме!I'р : =зна чение }
Подставить значение указанного параме!l'ра, если зада­

$ { параме!I'р=зна чение }

$ { параме!I'р : ? зна чение }

$ { паране!I'р : +зна чение}

$ { параме!l'р+зна чение }
$ { #паране!I'р }

$ { паране!l'р#шаблон }

но непустое его значение, а иначе - подставить задан­
ное значение и присвоить его указанному параме!l'ру
Подставить значение указанного паране!l'ра, если это
значение установлено, а иначе - подставить заданное
зна чение и присвоить его указан ному параме!l'ру
Подставить значение указанного параме!l'ра, если это
значение установлено и не является пустым, а иначе направить заданное зна чение в стандартный вывод
ошибок и на этом завершить операцию. Если же зна ­
чение пропущено, вывести сообщение об ошибке
"parame ter : parameter nul l or not set " (пара­
метр: пустой или не установленный)
Подставить заданное значение, если в указанном па ­
раме!l'ре установлено непустое значение, а иначе подставить пустое значен ие
Подставить заданное зна чение, если оно установлено в
указанном паране!l'ре, а иначе - пустое значение
Подставить длину указанного параме!l'ра. Если в каче­
стве параме!l'ра указан знак * или @, результат данной
операции не определен
Подставить значен ие указанного параме!l'ра, удалив
слева наименьшую его часть, совпадающую с заданным
шаблоном, где могут использоваться символы подста­
новки имен файлов ( * , ? , [
] , ! и @)
То же, что и выше, только слева удаляется наибольшая
часть значения указанного параме!l'ра, совпадающая с
заданным шаблоном
То же, что и подстановка $ { параметр#шаблон } , толь­
ко наименьшая часть значения указанного параме!l'ра,
совпадающая с заданным шаблоном, удаляется справа
То же, что и выше, только справа удаляется наибольшая
часть значения указанного параме!l'ра, совпадающая с
заданным шаблоном
.

$ { параме!l'р# #шаблон }

$ { паране!l'р%шаблон }

$ { параме!l'р% %шаблон }

.

.

382

П р и л ож е н и е А .

Краткое изложен ие оболоч ки

П о вто рн ы й в в о д к о м а н д
В оболочке ведется список предыстории недавно введенных команд. Коли­
чество команд, доступных в предыстории, определяется значением переменной
H I S T S I Z E (по умолчанию оно, как правило, равно 1 2 8), а файл, в котором хра­
нится предыстория, - значением переменной H I S T FI LE (по умолчанию она со ­
держит путь к файлу $ НОМЕ / . s h h i s t o ry). А поскольку предыстория команд
хранится в файле, то они становятся доступными после выхода и повторного вхо­
да в систему. Доступ к командам из предыстории можно получить одним из трех
способов.
_

Ком а нда fc

Встроенная в оболочку команда f c позволяет запустить редактор для правки
одной или нескольких команд из предыстории. Как только отредактированная
команда будет записана и завершится работа в редакторе, поправлен ная версия
команды будет благополучно выполнена. Конкретный редактор определяется
значением переменной FCE D I T (по умолчани ю ed). Для обозначения конкрет­
ного редактора вместо переменной FCE D I T можно также ввести команду fc с
параметром е
Параметр - s позволяет выполнять команды, не вызывая сначала редактор.
Простая возможность отредактировать команду встроена в команду fc - s .
Аргумент в следующей форме:
-

-

.

пр ежняя= нов а я

может быть использован для замены первого вхождения символьной строки
прежняя в символьной строке нов ая для повторного выполнения редактируе­
мых команд.
Р е ж и м реда кти рова н и я стро к в реда кторе vi

В оболочке поддерживается режим редактирования строк, совместимый с ре­
дактором v i . Когда этот режим включен, пользователь переносится в состояние,
дублирующее режим ввода в редакторе vi. Для перехода в режим редактирования
достаточно нажать клавишу . В этом режиме больш инство команд редак­
тора vi надлежащим образом и нтерпретируются оболоч кой. Текущая командная
строка может быть отредактирована таким же образом, как и любые строки из
предыстории команд. Находясь в режиме ввода или командном режиме и нажав
клавишу , можно в л юбой момент выполнить поправленную команду.
Все команды редактирования строк в режиме редактора vi перечислены в
табл. А.4. При этом следует иметь в виду, что [ подсче т ] означает целочисленное
значение и может быть опущено.

П овтор н ы й ввод команд

383

Таблица А.4. К оманды реда ктирован и я строк в режиме реда ктора vi

Кома нды режима ввода
Кома нда

Наз начение

eras e

Удалить предыдущий символ (символ стирания; обычно
знак # или комбинация клавиш < Ctrl+h>)
Удалить предыдущее слово, отделяемое пробелом
Удалить полностью текущую строку (символ удаления стро­
ки; обычно знак @ или комбинация клавиш < Ctrl+u>)
Прервать выполнение оболочки, если текущая строка ока­
зывается пустой (символ конца файла; обычно комбинация
клавиш < Ctrl+d>)
Если сначала нажать комбинацию клавиш , то затем
можно ввести знак следующей кавычки, знаки редактирова­
ния, стирания и удаления
Выполнить текущую строку
Перейти в режим редактирования


kill

eof



< Enter>


Кома нд ы режи ма редакrиро вания
Ко ма нда

Назн ачение

[ подсче !l'] k
[ подсче!l' ] ­
[ подсче !l'] j
[ подсче!l' ] +
[ подсче!l' ] G

П олучить предыдущую команду из предыстории
Получить предыдущую команду из предыстории
Получить следующую команду из предыстории
Получить следующую команду из предыстории
Получить из предыстории команду по указанному номеру
подсче!l'

/ C!l'pOXa

? C!l'pOXa

n
N
[ подсче!l'] 1 или
[ подсче!l'] пробел
[ подсче!l' ] w

Найти в предыстории самую последнюю команду, содержа­
щую заданную C!l'pOXY. Если указанная C!l'pOxa окажет­
ся пустой (т.е. ее ввод будет прерван нажатием клавиши
или комбинации клавиш ) , будет использо­
вана предыдущая строка. А если указанная C!lpoxa нач ина­
ется со знака л, то поиск в предыстории начнется с указан ­
ной С!lрОХН
То же, что и команда / C!lpoxa, только на этот раз будет про­
изведен поиск самой первой команды
Повторить последнюю ( / } или прежнюю ( ? ) команду
Повторить последнюю ( / ) или прежнюю ( ? ) команду, но из­
менить направление поиска на обратное
П ереместить курсор на один символ вправо
Переместить курсор на одно буквенно-цифровое слово
вправо

384

П р и r юж е н и е А .

Краткое изложен ие оболочки

Про должени е табл . А. 4
Кома н д а

Наз начение

[ подсчет] W

Переместить курсор вправо к следующему слову, отделяемо­
му пробелом
Переместить курсор в конец слова
Переместить курсор в конец текущего слова, отделяемого
пробелом
Переместить курсор на один символ влево
Переместить курсор на одно слово влево
Переместить курсор в начало строки
Переместить курсор к первому непробельному символу
Переместить курсор в конец строки
Переместить курсор к столбцу под указанным номером
подсчет (по умолчанию
1)
Переместить курсор вправо к указанному символу с
Переместить курсор влево к указанному символу с
То же, что и команда f с, только затем выполняется команда h
То же, что и команда Fc, только затем выполняется команда 1
Повторить последнюю команду f, F, t или Т
Выполнить команду, противоположную команде ;
Перейти в режим ввода и ввести текст после текущего символа
Присоединить текст в конце строке; то же, что и ссылка $а
Удалить символы от текущего до указанного в параметре
движение и перейти в режим ввода; если параметр движе­
ние принимает значение с, удаляется вся строка
Удалить символы от текущего до конца строки и перейти в
режим ввода
То же, что и команда се
Удалить символы от текущего до указанного в параметре
движение; если параметр движение принимает значение d,
удаляется вся строка
Удалить символы от текущего до конца строки; то же, что и
команда d$
Перейти в режим ввода и ввести текст прежде текущего символа
Перейти в режим ввода и ввести текст прежде первого слова
в строке
Разместить предыдущее изменение текста прежде курсора
Разместить предыдущее изменение текста после курсора
С копировать символы от текущего до указанного в параме­
тре движение непосредственно в буфер, применяемый в ко­
мандах р и Р; если параметр движение принимает значен ие
у, копируется вся строка

[ подсчет ] е
[ подсчет ] Е
[ подсчет] h
[ подсчет] Ь
о
л

$
[ подсчет] 1

-

[ подсчет] f с
[ подсчет] Fс
[ подсчет] t c
[ подсчет] Т е

а

А
[ подсче т]

с

движение

с
s

[ подсчет] d движение

D
i
I

[ подсче т] Р
[ подсче т] р
[ подсче т] у движение

За кл ючен ие в ка в ыч ки

385

Окончание табл. А . 4
Ко манда

Назна ч ен ие

у

Скопировать символы от текущего до конца строки; то же,
что и команда у$
Перейти в режим ввода и перезаписать символы в строке
Заменим текущий символ указанным символом с
Удалить текущий символ
Удалить предыдущи й символ
Повторить предыдущую команду изменения текста
Сменить на противоположный регистр букв текущего сим ­
вола и переместить курсор вперед
Присоединить слово под указанным номером подсчет из
предыдущей команды и перейти в режим ввода; по умолча­
нию это последнее слово
Вывести список файлов, нач инающийся с текущего слова
Дополнить путь текущим словом; если текущее слово явля­
ется каталогом, добавить знак / ; а если текущее слово явля­
ется файлом, то добавить пробел
Отменить последнюю команду изменения текста
Восстановить первоначальное состояние текущей строки
Программируемая функциональная клавиша. Если опреде­
лен псевдоним имени _буква, будет выполнена команда,
определяемая его значением
Запустить редактор vi для правки строки под указанным
номером подсчет; если же подсчет опущен, используется
текущая строка
Перевести строку и вывести текущую строку
Вывести текущую строку снова
Выполнить текущую строку
Выполнить текущую строку
Выполнить текущую строку
Вставить знак # в начале строки и ввести строку в предысто­
рию команд; то же, что и последовательность I #

R
[ подсчет] r c
[ подсчет] х
[ подсчет] Х
[ подсчет] .

[ подсчет]

=

\

и

u

@ буква

[ подсчет] v


L




#

З а кл ю ч ен и е в ка в ы ч к и
В оболо ч ке приняты четыре механизма заключения в кавыч ки (табл. А . 5) .
Табл и ца А. 5 . Сводка меха н из мов з аключе н и я в кавычки

Меха н и зм

Оп иса н ие

Отменяет специальное назначение все х символов, заклю­
ченных в кавыч ки

386

П р и n о же н и е А .

Краткое изложен ие оболочки

Окончание табл. А .5
Меха н и з м
"
"

Оп исан ие

О т меняе т специал ь ное назначение всех символов, заклю ­
ченных в кавычки, к р оме знаков $ , ' и \
О т меняе т специал ь ное назначение указ а нного "имвола

с; в двойных кавычках от меняе т ся н азначение указанных
знаков $ , ' , " , \ и новой с тр оки, кот о рые ин аче не ин ­
те рп р е т и рую тся; п р именяе т ся для п р одолжения с тр оки,
если оказывае т ся последним символом в с т роке (зн ак но ­
вой с троки удаляе т ся )
' команда ' и л и $ ( команда ) Выполняе т у казанн ую команду и вс т а вляе т в д а нном ме ­
с т е с т андарт ный вывод
З а ме н а з н а ка тил ьд ы

Каждое слово и переменная оболочки в командной строке проверяется на на­
личие в ее начале знака тильды ( -) без кавычек. Если есть этот знак, остальная
часть слова или значения переменной вплоть до знака / считается регистраци­
онным именем пользователя, которое и щется в системном файле (как правило,
в файле / e t c /pa s swd) . И если такой пользователь существует, то его начальный
каталог заменяет знак - и регистрационное имя пользователя. А если пользова­
тель отсутствует, то текст не изменяется. Сам же знак ... или следующий за ним
знак / заменяется значен ием переменной НОМЕ.
Арифмети ческие в ы р аже н и я

Общая форма конструкции для выполнения арифметических операций вы­
глядит следующи м образом:
$ ( ( выраже ни е ) )

Оболочка вычисляет целочисленное арифметическое выражение. Такое вы­
ражение может содержать операции, константы, перемен ные оболочки, которые
совсем не обязательно предваряются знаками денежной еди ницы ( $ ) . Наиболее
употребительные операции перечислены н иже в порядке приоритетности .

*, /, %
+, >

Унар ны й м ин ус
По р аз рядное НЕ
Логическое о тр ицание
Ум ножение, деление, пол учение ос т ат ка от
деления
Сложение, вычи т а ние
С двиг влево, сдви г вп р а во

П одста нов ка и мен фа йлов

=,
==, ! =
&

&&
1 1
аыражение1 ? аыражение2 : аыражение3
=, * =, /=, %=, +=, =, &=, л=, 1 =

387

С равнен ие
Равенство, нер авен ство
Поразрядное И
Поразрядное исключающее ИЛИ
Пор азрядное ИЛИ
Логическое И
Логическое ИЛИ
Услов н ая оп ерация
П р исваивание

Для переопределения приоритетности операций можно воспользоваться кру­
глыми скобками. Нулевой код завершения (т.е. истинное значение) возвращается
в том случае, если последнее выражение дает ненулевой результат, и единичный
код завершения (т.е. ложное значение), если последнее выражение дает нулевой
результат. Операции s i z e o f, + + и - языка С могут быть доступны в конкретной
реализации оболочки, хотя рассматриваемый здесь стандарт этого не требует.
Чтобы выяснить их доступность в кон кретной реализации, достаточно ввести
операцию s i z e o f и посмотреть, что же произойдет.
Ниже приведены характерные примеры применения упомянутых выше опера­
ций в арифметических выражениях.
у= $ ( ( 2 2 * 3 3 ) )
z=$ ( ( у * у / ( у

-

1) ) )

П одста н о в ка и м е н ф а й л о в
После подстановки параметров и команд в командной строке оболочка про­
изводит поиск специальных символов * , ? и [ . Если они не заключены в кавыч­
ки, оболочка производит поиск текущего или другого каталога при условии, что
он предваряется знаком / , а затем подставляет и мена всех совпадающих файлов.
А если ни одного совпадения не найдено, то специальные символы остаются без
изменения.
Следует, однако, и меть в виду, что имена файлов, начинающиеся с точки ( . ),
должны совпадать непосредственно. Иными словами, скрытые файлы отобразят­
ся не по команде e cho *, а по команде e cho * . Все символы подстановки имен
файлов сведены в табл. А.6.
.

Табли ца А.6. Си м вол ы подстановки и мен фа й лов

Си м вол ( ы )

Назначение

?

С овпадение с любым одиночным символом
С овпаден и е с нулевым или б ольшим количеством символов

*

388

П р и л ож е н и е А .

Краткое изложен ие оболочки

Окончание табл . А . 6
Си м вол ( ы )

Назначение

[ СИНВОJПJ]

С овпадение с любым одиночным символом, присутствующим среди ука­
занных синволоз; для совпадения с любым символом в пределах от С1
до С2 включительно можно воспользоваться формой С1 - С2• Напl"имер с
шаблоном [ A- Z ] совпадает любая прописная буква
С овпадение с любым одиночным символом, отсутствующим среди ука­
занных синволов; диапазон сопоставляемых с шаблоном символов мо­
жет быть указан, как описано выше

[ ! СИНВОJПJ]

П ереадреса ция в вода - в ы вода
Просматривая коман д ную строку, оболочка ищет специальные символы пере­
а дресации < и > . Если такие символы обнаружены, они обрабатываются и уд а­
ляются (вместе с любыми связанными аргументами) из коман д ной строки . Раз­
личные ви ды переадресации ввод а - вывод а, которые подд ержи ваются в оболочке,
перечислены в табл . А.7.
Табл и ца А. 7 . Переадреса ц и я ввода - в ы вода

Конструкция

Назначение

< файл

Переадресовать стандартный ввод из указанного файла
П ереадресовать стандартный вывод в указанный файл; если этот файл
не существует, он создается, а есл и он существует, то обнуляется
Переадресовать стандартный вывод в указанный файл, если этот файл
не существует, он создается, а если он существует, то обнуляется; при
этом параметр noclobber ( -С ) команды set и гнорируется
То же, что и >. только результат вывода присоединяется к указанному
файлу, если он существует
Переадресация стандартного ввода из последующих с т рок до тех пор,
пока не вс т ретится строка, содержащая указанное слово. В с т роках вы­
полняется подстановка параметров, выполняются команды, заключенные
в кавычки, а также интерпретируется знак обратной косой черты. Если
любой символ в указанном слове заключен в кавычки, то ни одна из
перечисленных выше операций не выполняется; а если указанное слово
предваряется знаком -, то из строк удаляются начальные знаки табуляции
П ереадресация стандартного ввода из файла, связанного с указанным де­
скриптором цифра
П ереадресация стандартного вывода в файл, связанный с указанным де­
скриптором цифра
Закрытие стандартного ввода
Закрытие стандартного вывода
О ткрытие указанного файла как для чтен ия, так и для записи

> файл
> 1 файл

>> файл
& цифра
& ­
файл

Э кспорти руем ы е перемен ные и выпол нен ие подоболочек

389

Следует, однако, и меть в виду, что имя указанного файла не подставляется.
Любой из конструкций, перечисленных в табл. А.7, может предшествовать номер
дескриптора, оказывающий аналогичное воздействие на связанный с н и м файл.
В частности , дескриптор О связан со стандартным вводом, дескриптор 1 - со
стандартным выводом, а дескриптор 2 - со стандартным выводом ошибок.

Э к сп орти руе м ы е п е р е м е н н ы е
и в ы п ол н е н и е п одо б ол о ч е к
Все команды, кроме встроенных в оболоч ку, как правило, выполняются в но­
вом экзем пляре оболоч ки, называемом подоболочкой . В подоболоч ках нельзя из­
менять значения переменных из родительской оболочки, и в них доступны толь­
ко те переменные, которые (явно или неявно) экспорт ированы из родительской
оболоч ки. Если в подоболоч ке изменяется значение одной из этих переменных
и требуется известить об этом ее собственные подоболоч ки, такая переменная
должна быть экспортирована перед выполнением подоболочки. А по завершении
подоболочки любые установленные в ней переменные становятся недоступными
для родительской оболоч ки.

. . .)
Если заключ ить одну или несколько команд в круглые скобки, эти команды
будут выполнены в подоболочке.
Ко н стр у к ц ия (

. . . ; }
Если заключ ить одну или несколько команд в фигурные скобки, эти команды будут выполнены в текущей оболочке. С помощью конструкций { . . . ; } и
( . . . ) можно переадресовать и направить ввод-вывод по каналу в ряд команд,
заключен ных в скобки, а также отправить их на выполнение в фоновый режим,
указав в конце знак &. Напри мер, в следующей строке:
Ко н стр у к ц ия {

( p ro g l ; p r o g 2 ; p r o g З )

2 >e r r o r s &

три переч исленные программы отправляются на выполнение в фоновый режим,
а стан'дартный вывод ошибок из всех трех программ переадресовывается в файл
errors.
Д о п ол н ител ь н ы е с вед е н ия о п ере м е н н ы х о б ол о ч ки

Переменную оболоч ки можно поместить в среду команды, присвоив ей пара­
метр в командной строке перед именем самой команды :
PHONE BOOK= $ HOME /mi s c / phone r o l o

П р и 11 о же н 11 е А .

390

Краткое и зложение оболоч ки

Здесь переменной PHONEBOOK присваивается указанное значение, а затем она
помещается в среду программы r o l o. При этом среда текущей оболоч ки остается
без изменения, как будто бы вместо предыдущей команды была выполнена следу­
ющая последовательность команд:
( PHONEBOOK=$ HOME /mi s c /phone ;

expo r t PHONE ВООК ;

rolo )

Ф у н кци и
Функции принимают следующую форму:
имя ( )

составная_ кома нда

где со ста вна я_ кома нда - это ряд команд, заключенных в скобки ( . . . ) ,
{ . . . } или блок операторов for, c a s e , unt i l, whi l e. Чаще всего функции
определяются в следующей форме:
имя

()

{

команда ;

кома нда ;

кома нда ;

}

где имя - это имя функции, определяемой в текущей оболочке, поскольку функ­
ции нельзя экспортировать. Определение функции можно распространить на
столько строк, сколько потребуется. С помощью команды re turn можно пре­
рвать выполнение функции, не прерывая выполнение самой оболочки (подроб­
нее об этом - в описании команды return). Так, в следующем примере:
nf

(

) {

ls

1

wc

-1 ; }

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

Уп ра влен и е з ада н и я м и
В последующих разделах вкратце поясняется, каким образом организуется
управление заданиями.
З ада н ия в о б о л о ч ке

Каждой последовательности команд, выпол няемых в фоновом режиме, при­
сваивается номер задания, начиная с первого. На задание можно ссылаться по
его идентификатору ( j оЬ i d) , который состоит из знака % и номера задания,
последовательности знаков %+, % - , % % , знака % и первых нескольких букв канала
или последовательности % ? С!lрОЖа.
Идентификатор задания может быть задан в качестве аргумента следующим
встроенным в оболочку командам: k i l l , fg, bg и wa i t. Специальные иденти­
фикаторы %+ и %- обозначают текущие и предыдущие задания соответствен­
но, а идентификатор %% - текущее задание. Текущим считается самое послед­
нее задание, отправленное на выполнение в фоновый режим, или же задание,
_

Сводка команд

391

выполняемое в приоритетном режиме. Идентификатор % с�ожа обозначает за­
дание, имя которого начинается с указанной с�ожи, а идентификатор % ? с�о­
жа
задание, имя которого содержит указанную с�ожу. Для вывода текущего
состояния всех выполняемых задани й можно воспользоваться командой j ob s .
Если активизирован параметр mon i t o r команды s e t, оболочка выводит со­
ответствующее сообщение по окончании каждого задания. Если попытаться вый ­
ти и з оболочки при наличии в н е й незавершенных заданий, будет выведено сооб­
щение, предупреждающее об этом. Если при этом попытаться выйти из оболочки
снова, выход из нее произойдет без всякого предупреждения. В интерактивных
оболоч ках параметр mon i tor активизируется по умолчанию.
-

Останов к а зада н и й

Если оболочка выполняется в системе с управлением заданиями и при этом
активизирован параметр mon i t o r команды s e t , задания, выполняемые в
приоритетном режиме, могут быть перенесены в фоновый режим, и наоборот.
Как правило, текущее задание останавл ивается нажатием комби нации клавиш
. По команде bg остановленное задан и е переносится в фоновый ре­
жим, а по команде fg
фоновое или остановленное задание в приоритетн ый
режим
Всякий раз, когда в фоновом задан ии предпринимается попытка прочитать
данные с терминала, оно приостанавливается до тех пор, пока не будет перене­
сено в приоритетный режим. Результаты, выводимые из фоновых заданий, как
правило, направляются на терминал. Если выполняется команда s t ty tos top,
вывод из фоновых заданий запрещается, а задание, выводящее результаты на тер­
минал, приостанавливается до тех пор, пока не будет перенесено в приоритетный
режим. При выходе из оболочки все остановленные задания уничтожаются.
-

Сводка ко м а нд
В этом разделе вкратце поясняются команды, встроенные в стандартную обо­
лочку. В действительности некоторые из этих команд ( например, e cho и t e s t )
могут н е быть встроены в оболочку и л и иметь упрощен ную версию для встраи­
ваниЯ' в оболочку, а более сложную версию - в виде отдельной программы. Но
в любом случае подобные функции должны быть предоставлены в виде утилиты
в системе, совместимой со стандартом POSIX. Они встроены в оболочки Bash и
Korn и при меняются практически во всех сценариях оболочки.
Команда :
Общая форма:

По существу, это пустая команда. Она нередко применяется с целью удовлет­
ворить требованию наличия команды.

392

П р и л ож е н и е А.

Краткое изложение обол оч ки

Пример:
if

who

1

grep

j ac k

> / d e v / nu l l

t h en

e l se
echo " j a c k ' s n o t l o g g e d i n "
fi

В данном примере команда : возвращает нулевой код завершения.
Ком анда .
Общая форма:

.

фа йл

Команда-точка ( ) вынуждает оболочку прочитать и выполнить указанный
файл, как будто строки из этого файла были введены в данный момент. Однако
указанный фа йл совсем не обязательно должен быть исполняемым, а только до­
ступным для чтения. Для поиска указанного файла оболоч ка обращается также
к переменной РАТН.
.

Пример
p r o gde f s

Выполнить кома нды из файла progdexs

В данном примере команда . вынуждает оболочку искать указанный файл
progde f s в текущей перемен ной РАТН. Если она обнаружит этот файл, то про­
читает и выполнит команды из него. Тем не менее оболочки, устанавливаемые и/
или изменяемые в указан ном фа йле, продолжают действовать и по завершении
команд из этого фа йла .
Ком а нда alias

.]
Общая форма: a l i a s имя= строка [ имя= строка
Команда a l i a s присваивает указан ную строку заданному псевдониму имя.
Всякий раз, когда используется псевдони м имя, оболочка подставляет сначала
указанную строку, а затем выпол няет остальные подстановки после размещения
этой строки в командной строке.
.

.

Примеры:
alias ll= ' ls -1 '
a l i a s d i r= ' b a s ename $ ( pwd ) '

Если псевдоним оканчивается пробелом, следующее далее слово также прове­
ряется, не является ли оно псевдонимом. А в следующей форме данной команды:
a l i a s имя

выводится указанный псевдоним имя. Если же команда a l i a s указана без аргу­
ментов, она выводит все псевдонимы. Команда a l i a s возвращает нулевой код
завершения, если только не задано имя, для которого определен псевдоним, как,
например, в команде a l i a s имя.

Сводка команд

393

Кома нда Ьg

Общая форма: bg j оЬ_ i d
Если активизировано управление заданиями, т о задание, обозначаемое иден­
тификатором j оЬ i d, переносится в фоновый режим . Если же команда bg вве­
дена без аргументов, то в фоновый режим переносится самое последнее приоста­
новлен ное задан ие.
Пример:
bg '1. 2

Кома нда break

Общая форма: b re a k
Выполнение данной команды приводит к немедленному завершению наиболее
глубоко вложенного цикла f o r , wh i l e или unt i l . Выполнение будет продолже­
но с команд, сразу же следующих после данного цикла. Если же команда b r e a k
используется в следующей форме:
break

п

то автоматически завершаются

п

наиболее глубоко вложенных циклов.

К ома нда case

Общая форма:
c a s e зна чение i n
ша блон , ) кома нда
команда

ша блон)

кома нда ; ;
кома нда
кома нда
команда ; ;

ша блонп )

команда
команда
кома нда ; ;

e sac

Указанное слово зна чение последовательно сравнивается с ша блономl' ша б­
лоном2 и ша блоном11 до тех пор, пока не будет обнаружено совпадение. А далее
команды, следующие сразу же после совпавшего шаблона, выполняются до тех
пор, пока не встретятся две следующие подряд точки с запятой ( ; ; ). В этот мо­
мент выполнение команды, реализующий оператор ca s e , завершается.

394

П ри л оже н и е А.

Краткое изложен ие оболочки

Если же указанное зна чение не совпадает ни с одним из заданных шаблонов,
то ни одна из команд, расположенных в ветвях выбора из оператора c a s e , не вы­
полняется. Шаблон * , обозначающий любое совпадение, нередко употребляется в
последней ветви оператора ca s e в качестве "универсального" варианта выбора
по умолчанию.
В шаблонах могут быть использованы следующие метасимволы:




* (совпадение с нулевым или большим количеством символов);
? (совпадение с любым одиночным символом);
[ . . . ] (совпадение с любым одиночным символом, заключенным в ква­
дратные скобки).

А знак 1 может служить для обозначения логического объединения двух ша­
блонов по ИЛИ. Так, следующее выражение:
ша блон1 1

ша блон2

означает совпадение с заданным ша блоном1 или ша блоном2•
Примеры:
case

$1 in
- 1 ) l o p t =TRUE ; ;
- w ) wopt=TRUE ; ;
- с ) copt =TRUE ; ;
* ) e c h o " Un known opt i on " ; ;

esac
case $choice in
[ 1 - 9 ] ) va l i d=TRUE ; ;
* ) e ch o " P l e a s e choo s e
esac

а

numЬ e r f rom 1 - 9 " ; ;

Ком а нда cd

Общая форма: cd ка талог
Выполнение этой команды приводит к тому, что оболочка делает указанный
ка талог текущим. Если же ка талог опущен, оболочка сделает текущим каталог,
указанный в перемен ной НОМЕ.
Если значение переменной оболочки C D PATH окажется пустым, в качестве
ка талога следует указать полный путь к каталогу ( например, / u s e r s / s t eve /
document s ) или путь относительно текущего каталога (напри мер, docume n t s
или . . /pat). Если же значение переменной оболоч ки C D PATH окажется непу­
стым, а в качестве ка талога указан полный путь, оболочка произведет поиск
каталога, содержащего заданный ка талог, в списке разделяемых двоеточием ка­
талогов, находящемся в переменной C D PATH.
Примерь�:
$ cd docume n t s /memo s
$ cd

Перейти в ка талог documen ts/mвmos
Перейти в на чальный ка талог

Сводка команд

395

Если в команде cd указан аргумент -, оболочка переместит пользователя об­
ратно в предыдущий каталог. В итоге выводится путь к новому текущему каталогу.
Примеры:
$ pwd
/ u s r / l i Ь / uucp

$ cd /
$ cd

-

/ u s r / l i Ь / uucp
$

Команда cd устанавливает в переменной PWD новыйтекущий каталог, а в пере­
менной OL DPWD предыдущий.
-

Команда con tinue

Общая форма: cont i nue
Выполнение команды cont i nue в цикле f o r , wh i l e или unt i l приводит к
пропуску любых команд, следующих после этой команды. А выполнение цикла
продолжается далее, как обычно. Если же данная команда применяется в следу­
ющей форме:
con t i nue

п

пропускаются команды, находящиеся в п наиболее глубоко вложенных циклах.
А выполнение цикла продолжается далее, как обычно.
Команда echo

Общая форма: echo аргументы
Выполнение этой команды приводит к тому, что указанные аргументы на­
правляются в стандартный вывод. Каждое слово, которое содержат указанные
аргументы, разделяется пробелом. Знак новой строки выводится последним.
Если же аргументы опущены, то происходит обычный пропуск строки. Неко­
торые символы, экранированные знаками обратной косой черты, и меют специ ­
альное назначение в команде e cho (табл. А.8).
Табл и ца А.8. Уп равл я ющие с и м волы, при меняемые в команде
'

Си мвол

Назначение




\f
\n
\r
\t

Предупрежде н ие
Возвр ат на од н у позици ю
Строк а без з а верш а ющего знака н овой стро к и
Перевод стр ан ицы
Нов ая строк а
Перевод к а ретки
Горизон т а ль ная т абуляция

echo

396

П р и л оже н и е А .

Краткое изложен ие оболочки

Оконч ание табл. А . В
Си м вол

Н азначен и е

\v

Верти кальная табуляция
Обрат ная косая черта
С имвол со значением nnn в коде ASCII, где nnn
восьмерич ное 'число,
состоящее из одной-трех цифр и начи нающееся с нуля

\\
\ Onnn

-

Перечисленные выше символы следует заключить в кавычки, чтобы они были
правильно интерпретированы командой e cho, а не оболочкой .
Пример ы:
$

echo *

b i n doc s
$ echo
$

Пере числить в се файлы
в текущем ка талоге
ma i l mi s e s r c
Пропустить строку
Выв е сти буквы Х и У,
ра зделенные зна ком та буляции

echo ' X\ tY '

х у

$

echo " \n\nSales Report"

S a l e s Rep o r t
$ echo "Wake

up ! ! \a "

Пропустить две строки , прежде чем
отобража ть слова saies Report

Выв ести сообщение и
предупреждающий сигнал на терминал

Wa k e up ! !
$

Ком а нда eval

Общая форма: eva l аргументы
Выполнение этой команды приводит к тому, что оболочка сначала выч исляет
указанные аргументы, а затем выполняет полученные результаты. Это удобно в
том случае, есл и требуется, чтобы оболоч ка дважды просматривала командную
строку.
Пример:
$ x= ' ahc def '
$ у= ' $х '
$ echo $у

$ eval echo $у
а Ь с de f

$

Присв оить переменной у зна чение переменной $х

Свод ка ко м а нд

Кома нда

397

е хес

Общая форма: е х е с кома нда аргументы
Когда оболочка выполняет команду е х е с , она инициирует выполнение указан­
ной кома нды с задан ными аргументами. В отличие от других команд, указанная
кома нда заменяет текущий процесс, а это означает, что новый процесс не созда­
ется. Как только указанная кома нда начнет выполняться, вернуться в програм­
му, иници ировавшую команду е х е с, уже нельзя. Если же указана переадресация
ввода-вывода, то соответственно переадресовывается и ввод- вывод для оболочки.
Примерь�:
ехес
ехес

/Ьin/ sh
< datafi le

Заменить текущий проце сс оболочкой sh
Перена зна чить ста ндартный в в од из файла dataxile

Кома нда exi t

Общая форма: e x i t п
Выполнение команды e x i t приводит к тому, что текущая программа оболоч­
ки немедленно прерывается. Код завершения программы принимает целочислен­
ное значение аргумента п, если он предоставлен. Если же аргумент п не предо­
ставлен, то возвращается код завершения последней команды, выполнявшейся
прежде команды e x i t.
Нулевой код завершения служит для обозначения удачного исхода, а ненуле­
вой код завершения - неудачного исхода ( например, ошибочного условия). Этот
код используется оболочкой для вычисления условий в операторах i f, wh i l e и
unt i l , а также в операциях & & и 1 1 .
Примеры:
who 1 grep $ u s e r > / d e v / nu l l
exit
Выйти с кодом з а в ершения по следней кома нды grep
exit 1
Выйти с кодом за в ершения 1
i f f i ndu s e r
Если кома нда xinduser в озвраща ет нулевой
код за в ершения , то . . .
then
fi

Однако следует иметь в виду, что выполнение команды exi t в исходной обо­
лочке приведет к выходу из системы.
Кома нда export

Общая форма: e xpo r t переменные
Команда expo r t сообщает оболочке, что указанные в ней переменные долж­
ны быть помечены как экспортируемые. Это означает, что их значения должны
быть переданы далее подоболочкам.

398

П р и л ож е н и е А .

Краткое изложен ие оболоч ки

Примеры:
expo r t РАТ Н P S l
expo r t dbhorne x l y l d a t e

При экспорте переменные могут быть установлены в следующей форме: ,
expo r t переменна я= з на чение . . .

Таким образом, следующие строки:
PATH= $ PAT H : $ HOME / b i n ; e xp o r t РАТН
C D PATH= . : $ HOME : / u s r / sp o o l / uu cppuЬ l i c ;

expo r t C D PATH

могут быть переписаны таким образом:
expo r t PATH= $ PATH : $ HOME / b i n C DPAT H = . : $ HOME : / u s r / sp oo l / uu cppuЫ i c

В результате выполнения команды exp o r t с аргументом -р выводится список
экспортируемых переменн ых и их значений в следующей форме:
expo r t переменная=зна чение

или в такой форме:
expo r t переменна я

если указанная переменная экспортирована, но ее значение еще не установлено.
Команда fal se

Общая форма: f a l s e
Команда f a l s e возвращает ненулевой код завершения.
Ко м а нда fc

Общая форма: fc

- е реда ктор - l nr перв ая последняя
f c - s прежняя=нова я перв ая

Команда f c служит для редактирования команд, н аходящихся в предыстории.
Команды указываются в пределах от перва я до по следняя, где перв ая и по ­
следняя команды могут быть обозначены номерами или символьными строка­
ми. Отрицательный номер интерпретируется как смещение от номера текущей
команды, тогда как символьная строка обозначает самую последнюю введенную
команду, нач и нающуюся с данной строки. Команды вводятся в указанный ре ­
да ктор и выполняются после выхода из него. Если же реда ктор не указан, то
используется значение из переменной оболочки FCE D I T . А если переменная
FCE D I T не установлена, используется редактор ed.

Сводка команд

399

Параметр - 1 команды fc обозначает простое перечисление команд от пер ­
вой до по следней, когда редактор не вызывается. Если же указан и параметр
-n, эти команды не предваряются номерами . А параметр -r позволяет вывести
команды в обратном порядке.
Если аргумент прежняя не указан, то по умолчанию принимается значение
аргумента перв ая. А если не указан аргумент перв а я, то по умолчанию для ре­
дактирования выбирается предыдущая команда, а также значение - 1 б для пере­
числения списка команд. Параметр - s обусловливает выполнение выбранной ко­
манды без предварительного ее редактирования. Следующая форма команды fc:

f c - s прежняя= новая перва я

вызывает повторное выполнение команды перва я после замены в ней символь­
ной строки прежняя на строку новая. Если же команда перв а я не указана, то ис­
пользуется предыдущая команда. А если не указано выражение прежняя= нова я,
то команда не изменяется.
Примеры:
fc 1
fc - е vi sed
fc 100 1 1 0
f c -s
fc -s aЬc=def 1 0 4
-

Перечислить 1 6 по следних кома нд
Про чита ть кома нду реда ктора sed в реда ктор vi
Про чита ть кома нды 1 00 - 1 1 0 в переменную $FCEDIT
Выполнить пов торно предыдущую кома нду
Выполнить пов торно кома нду 104 ,
заменив аЬс на def

Кома нда fg

Общая форма: fg j ob_ i d
Если активизировано управление заданиями, т о задание с указанным иден ­
тификатором j оЬ_ i d переносится в приоритетный режим. Если же аргументы в
данной команде отсутствуют, то задание, приостановленное или отправленное в
фоновый режим самым последним, переносится в приоритетный режим.
Пример:
fg

\\ 2

Ко манда for

Общая форма:
for переменна я in слов о , слов о2 • • •
do
кома нда
команда
done

слово"

400

П р иложен и е А.

К раткое изложен ие оболоч ки

Выполнение этой команды приводит к тому, что команды, указанные между
операторами do и done, будут выполнены столько раз, сколько слов перечисле­
но после элемента i n. На первом шаге цикла for указанной переменной этого
цикла присваивается первое слово (т.е. слов о1) и далее выполняются команды,
указанные между операторами do и done. На втором шаге данного цикла у� азан ­
ной переменной присваивается второе слово ( слов о2) и те же самые команды
выполняются снова.
Этот процесс повторяется до тех пор, пока указанной переменной цикла не
будет присвоено последнее слово (т.е. слов о") и выполнены команды, указанные
между операторами do и done. В этот момент цикл завершается и выполнение
продолжается с команды, следующей сразу же после оператора done.
В следующей специальной форме команды f o r :
f o r пер еменна я
do
done

предполагается употребление списка позиционных параметров $ 1 , $2 и т.д., что
равнозначно такой форме:
f o r пер еменна я i n " $ @ "
do
done

Пример:
# Обработа т ь все файлы в т е кущем каталоге п о команде nroff
f o r f i l e in *
do
n ro f f - T l p $ f i l e
done

1 lp

Ко ма нда getopts

Общая форма: g e t o p t s параметры переменна я
Эта команда обрабатывает аргументы командной строки. Здесь параме т ­
ры
это список достоверных однобуквенных параметров. Если после любой
буквы параме тры содержат двоеточие ( : ), такему параметру требуется допол нительный аргумент, отделяемый от параметра хотя бы одним пробелом в ко­
мандной строке.
Всякий раз, когда команда g e t opt s вызывается, она обрабатывает следую­
щий аргумент в командной строке. Если обнаруживается достоверный параметр,
команда g e t o p t s сохраняет соответствующую букву параметра в указанной пе ­
ременной и возвращает нулевой код завершения. Если же указан недостоверный
-

Сводка команд

401

параметр (или, наоборот, параметр, отсутствующий в списке параметров), ко­
манда getop t s сохраняет знак ? в указанной переменной и возвращает нуле­
вой код завершения. Она направляет также сообщение об ошибке в стандартный
вывод ошибок.
Если параметр принимает аргумент, команда g e t op t s сохраняет соответству­
ющую букву параметра в указан ной переменной, тогда как аргумент командной
строки - в специальной переменной O PTARG. Если же аргументы оставляются в
командной строке, команда g e topt s устанавливает знак ? в указанной пере ­
менной и направляет сообщение об ошибке в стандартный вывод ошибок. А если
в командной строке больше не остается параметров (т.е. следующий аргумент в
командной строке не начинается со знака ) , то команда g e t op t s возвращает
ненулевой код завершения.
В команде getop t s применяется также специальная переменная OPT I N D.
Первоначально в ней устанавливается значение 1 , а затем оно корректирует­
ся всякий раз, когда происходит возврат из команды g e t op t s , указывая номер
следующего аргумента, который следует обработать в командной строке. Чтобы
обозначить конец списка аргументов, в командной строке может быть указан ар­
гумент - - .
В команде ge topt s поддерживаются составные аргументы, как показано
ниже.
-

repx - i a u

что равнозначно следующему:
repx -i



-u

Параметры, которым требуются аргументы, могут и не быть составными. Если
используется следующая форма команды g e t opt s :
g e t opt s параме тры переменна я аргументы

данная команда выполняет синтаксический анализ указанных аргументов, а не
аргументов командной строки.
Прим ер :
u s a ge= " U s a g e : foo [ - r ]
wh i l e g e t op t s r o : opt

[ -О o u t f i l e ]

do
c a s e " $ opt "
in
r) r flag=l ; ;
О ) o f l ag = l
o f i l e = $ 0PTARG ; ;
\ ? ) e ch o " $ u s a g e "

infile"

402

П р и л оже н и е А.

Краткое изложен ие оболочки

exit 1 ; ;
esac
done
i f ( $ 0PT I N D -gt $# ]
then
e ch o "Needs i np u t f i l e ! "
e c h o " $ u s a ge "
exit 2
fi
s h i f t $ ( ( OPT I N D
i fi le=$ 1

-

1) )

Ко ма нда hash

Общая форма: ha s h кома нды
Эта команда предписывает оболочке найти указанные кома нды и запомнить
каталоги, в которых они н аходятся. Если кома нды не указаны, то выводится спи­
сок хешированных команд. Если же данная команда используется в следующей
ф орме:
hash -r

т о оболочка удаляет все команды из своего хеш-списка. А при последующем вы­
полнении любой другой команды оболочка применяет обычные методы поиска
команд.
Примеры:
h a s h r o l o whoq
hash
hash -r

До ба вить кома нды rol.o и whoq в хеш- список
Выв е с ти хеш- список
Удалить хеш - список

Кома нда i f

Общая форма:
i f кома нда ,
then
команда
команда
fi

Сначала выполняется указанная кома нда1, а затем проверяется код ее завер­
шения. Если этот код оказывается нулевым, выполняются команды, находящиеся
между операторами then и f i . В противном случае эти команды пропускаются.

Сводка ком а нд

403

Прим ер:
i f g rep $ s ys s y s name s > / d e v / n u l l
then
echo " $ s y s is а va l i d s ys t em n ame "
fi

Если команда g rep возвращает в данном примере нулевой код завершения,
а это происходит в том случае, если она обнаружит переменную $ s ys в ф айле
s y s name s , то выполняется команда e cho. В противном случае эта команда про­
пускается. Нередко после условного оператора i f в описываемой здесь команде
для непосредственного вызова указывается встроенная команда t e s t, обознача­
емая явно или неявно в сокращенной ф орме [ ] .
Прим ер
if

[ $ # -eq О ] ; then
echo " U sage : $0 [ - 1 ]
exj t

f i le

"

1

fi

Условный оператор i f может быть дополнен оператором e l s e , если рассма­
триваемая здесь команда возвращает ненулевой код завершения. В этом случае ее
общая ф орма выглядит следующим образом:
i f команда ,
then
кома Нда
кома Нда
else
кома нда
кома Нда

fi

Если указанная кома нда1 возвращает нулевой код завершения, то выполня­
ются команды, находящиеся между операторами then и e l s e , а команды, следу­
ющие после оператора e l s e, пропускаются. Если же указан ная команда1 возвра­
щает flенулевой код завершения, то команды, н аходящиеся между операторами
then и e l s e , пропускаются, а выполняются команды, находящиеся между опе­
раторами e l s e и f i .
Прим ер:
if [
then

-z

" $ l i ne "

echo

"I

cou l dn ' t f i n d $ n ame "

else
echo " $ l i ne "
fi

П р и n о ж е н и е А.

404

Краткое изложен ие оболочки

Если переменная l i ne в приведенном выше примере содержит нулевую дли­
ну, то выполняется команда echo, выводящая сообщение " I c o u l dn ' t find
$ name " ( Не удалось найти имя, указанное в переменной $ name). А приведенная
ниже завершающая форма команды i f удобна в том случае, если требуется сде­
лать двойной выбор.
Пример:
i f кома нда ,
then
команда
кома нда
e l s e i f кома нда 2
then
команда
кома нда
e l s e i f кома нда "
then
команда
кома нда
else
команда
команда
fi

Указанная последовательность кома нда р кома нда2, команда" вычисляет­
ся по порядку до тех пор, пока одна из этих команд не возвратит нулевой код
завершения. И в этот момент выполняются команды, следующие сразу же после
оператора then и вплоть до очередного оператора e l i f, e l s e или f i . Если же
ни одна из указанных команд не возвратит нулевой код завершения, то выполня­
ются команды, следующие сразу же после оператора e l s e , при условии, что они
заданы.
•••

Пример:
[

then
" $ ch o i ce " = а
a dd $ *
t he n
e l i f [ " $ ch o i ce "
d
de l e t e $ *
1
then
e l i f [ " $ ch o i ce "
list
else
e ch o " Bad cho i c e ! "
e r r o r =TRUE
if

fi

Сводка ко м а нд

405

Кома нда j obs

Общая форма: j obs
По этой команде выводится список активных заданий. Если в этой команде
указан параметр 1 то каждое задание перечисляется вместе с присвоенным ему
идентифи катором процесса. Если же указан параметр -р, то перечисляются толь­
ко идентифи каторы процесса, присвоенные активным заданиям. А если в коман­
де j ob s указан дополн ительный идентификатор задания j ob_ i d, то перечисля­
ются только сведения об этом задании.
-

,

Пример :
$ sleep 100 &
[1]

1104

$ jobs
[1]

Run n i n g s l e e p 1 0 0 &

+

$

Кома нда k i l l

Общая форма: k i l l - сигнал з ада ние
Команда ki 1 1 посылает сигнал указанному процессу на его прерывание,
где з ада ние
идентификатор процесса или идентификатор задания j оЬ_ i d,
а сигнал
номер или одно из наименований сигналов, определенных в заго­
ловочном файле < s i g na l . h> (подробнее об этом см. далее оп исание команды
t rap). Имена сигналов перечисляются по команде k i l l - 1 . Если вместе с пара­
метром -1 указан номер сигнала, то выводится соответствующее имя сигнала.
А если вместе с параметром - 1 указан идентификатор процесса, то выводится
наименование си гнала, прервавшего данный процесс, если он действительно был
прерван этим сигналом.
Вместе с наименованием сигнала может быть также указан параметр - s . В этом
случае наименование си гнала не предваряется знаком дефиса, как демонстриру­
ется в одном из при веденных ниже примеров. Если же конкретны й сигнал не
указан, то используется наименование сигнала S I GTERМ (или просто ТЕRМ). Сле­
дует также иметь в виду, что в одной строке с командой k i 1 1 может быть указано
несколько идентификаторов процессов.
-

-

Пример ы:
kill -9 1234
k i l l - H U P '(, 2 3 4 5 6
k i l l - s T E RM '{, 2
1
kill

406

П р и п оже н и е д,

Краткое и зложен ие оболочки

Команда newgrp

Общая форма: newgrp труппа
Эта команда заменяет настоящий иденти ф икатор группы (GID) указанной
труппой. Если она указана без аргументов, то происходит возврат к группе, ис­
пользуемой по умолчанию.
Пример:
newgrp s hb o o k
newgrp

Заменить труппу на shЬook
Вернуть ся о бра тно к исполь зуемой
по умолча нию труппе

Если с новой группой связан пароль, а текущий пользователь не перечислен
в качестве члена этой группы, ему будет предложено ввести свой пароль. По ко­
манде newgrp -1 происходит возврат к исходной груп пе, выбираемой при реги­
страции в системе.
Ком а нда рwd

Общая форма: pwd
Эта команда предписывает оболочке вывести рабочи й каталог текущего поль­
зователя, направив его в стандартный вывод.
Пример ы:
$ pwd
/ u s e r s / s t e ve /docшne n t s /memo s
$ cd
$ pwd
/ u s e r s / s t e ve
$

Команда read

Общая форма: r e a d переменные
Выполнение этой команды приводит к тому, что оболоч ка читает строку из
стандартного ввода и присваивает указанной переменной слова, разделяемые
пробелами далее в строке. Если в строке указано меньше переменных, чем слов,
дополнительные слова сохраняются в последней переменной.
Указание лишь одной переменной означает, что этой переменной присваива­
ется прочитанная строка. Команда read возвращает нулевой код завершения,
если только не обнаруживается условие, обозначающее конец ф айла.
Пример :
$ read hours mins
10 1 9
$ echo " $hours : $mins "
10 : 19

С водка команд

407

$ read num rest
3 9 E a s t 1 2 t h S t re e t , New Y o r k C i t y 1 0 0 0 3
$ echo "$num\n$rest"
39
E a s t 1 2 t h S t r e e t , New Y o r k C i t y 1 0 0 0 3

$ read line

Here

$ echo " $ 1 ine "
Here
$

is an entire

i s an e n t i re

line \r
l i ne r

В последнем примере обратите внимание на то, что любые начальные пробель­
ные символы будут "поглощены" оболочкой при чтени и строки. Если это вызыва­
ет труд ности, можно соответственно изменить значение переменной I FS.
Следует также иметь в виду, что знаки обратной косой черты интерпретиру­
ются оболочкой при чтени и строки и любой подобный знак (например, д войная
косая черта как од иночная) интерпретируется коман д ой e cho, если отображает­
ся значение переменной. Если же в коман д е read указан параметр -r, то знак \
не должен интерпретироваться в конце строки как ее прод олжение.

Команда readonly

Общая форма: re adon l y переменные
Эта коман д а сообщает оболочке, что перечисленным в ней переменным
нельзя присваивать значения. Значения этим переменным могут быть дополни­
тельно присвоены только в командной строке r e adon l y. Если же впоследствии
попытаться присвоить значение переменной, указанной в командной строке
readonl y, оболочка выдаст соответствующее сообщение об ошибке.
Переменные удобно устанавливать в коман д ной строке r e adon l y для того,
чтобы исключить неумышленную перезапись их значений. Этим также гаранти­
руется, что другие пользователи программы оболочки не смогут изменить зна­
чения отдельных перемен ных (например, переменных НОМЕ или РАТН). Атрибут
readon l y (только для чтения) не передается далее подоболочкам. Если команда
re adon l y указана с параметром -р, она вывод ит список переменных с атрибу­
том reado n l y.
Пр1jмер ы :
$ readonly DB=/users /s teve/dataЬase

$ DB=foo
sh :

DB :

i s read - on l y

$ echo $DB
/ u s e r s / s teve / da t aba s e
$

Присв оить з на чение
переменной DВ и сдела ть
ее доступной толь ко
для чтения
Попыта ть ся присв оить
зна чение переменной DB
Сообщение о б ошибке ,
выв одимое о боло чкой
Тем не менее ее зна чение
по -прежнему доступно

408

П р и л о ж е н и е А.

Краткое изложен ие оболочки

Команда return

Общая форма: r e t u rn п
Выпол нение этой команды приводит к тому, что оболочка прерывает выпол­
нение текущей функции и сразу же возвращает код завершения п вызывающей
части программы. Если же аргумент п опущен, то возвращается код завершения
команды, выполнявшейся непосредственно перед командой re turn.
Кома нда set

Общая форма: set параме тры аргументы
Эта команда служит как для установки и сброса указанных параме тров, так
и для установки позиционных параметров, обозначаемых задан ными аргумен­
тами. Каждый из указанных однобуквенных параметров устанавливается, если
он предваряется знаком - , или сбрасывается, если он предваряется знаком +. Па­
раметры могут быть сгруппированы, как демонстрируется в приведенном ниже
примере, где устанавливаются параметры f и х .
s e t - fx

В табл. А.9 сведены параметры, которые могут быть выбраны для установки
или сброса в команде s e t .
Табли ца А.9. Параметры, доступ ные дл я установки и л и сброса в команде set

П а ра метр

Наз н ачение

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


Автоматически экспортировать все переменные, которые последовательно
определяются или видоизменяются



Если этот параметр поддерживается в конкретной реал изации, оболочка
уведомляет пользователя о завершении ф оновых заданий
Не разрешать переадресацию вывода для перезаписи существующих ф ай­
лов. Чтобы обеспеч ить перезапись отдел ьных ф айлов, можно указать после­
довательность символов > 1 , даже если данный параметр установлен
Завершить выполнение при неудачном исходе выполнен ия любой команды
или возврате ненулевого кода завершения





-f

-h

Запретить генерирование имени ф айла
Ввести команды из ф ункций в хеш -сп исок по мере их определения, но не
делать этого по мере их выполнения

-m

Включить мон итор заданий

-n

Проч итать команды, не выполняя их (это удобно для проверки уравнове­
шенности блоков операторов do ". done и i f ." f i )
Записать текущие настройки режима установки параметров в ф ормате ко­
манды



Сводка команд

409

Окончание табл. А . 9
Пара метр
-

о

m



Наз начение

Включить режим установки параметров m (см. табл. А. 1 0 )
Выдать ошибку, если происходит обращение к переменной, которой еще не
было присвоено зна•1ение, или же обращение к неустановленному еще по­
зиционному параметру

-v

Вывести каждую командную строку по мере ее чтения в оболоч ке



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

Режимы оболочки включаются или выключаются с помощью обозначения
- о или +о, после которого следует имя параметра. Эти параметры сведены в
табл . А. 1 0.
Табли ца А. 10. Реж и м ы оболоч к и

Р еж и м

Назначение

allexport
errexit
ignoreeof
moni tor
noclobber
noexec
noglob

То же, что и параметр

-

То же, что и параметр



nolog
nounset
verbose
vi
xtrace

а

Для выхода из оболочк и следует воспользоваться командой e x i t
То же, что и параметр -m
То же, что и параметр -С
То же, что и параметр -n
То же, что и параметр - f
Не размещать определения ф ункций в предыстори и
То же, что и параметр -u
То же, что и параметр -v
Установить vi в качестве строкового редактора
То же, что и параметр



По команде s e t - о без имени какого- нибудь из перечисленных выше режи­
мов оболочки выводится список всех подобных режимов и их текущие установки.
Переменная оболочки $ - содержит установки текущих параметров.
в к аждом слове, перечисленном в указанных аргумента х, задаются соответ­
ственно позицион ные параметры $ 1 , $ 2 и т.д. Если первое слово может начи­
наться со знака "минус", то надежнее указать в команде set параметр - - , чтобы
исключить интерпретацию его значения. Если же аргументы указаны, то в пере­
менной $ # будет установлено количество параметров, присвоенных после выпол­
нения дан ной команды.

П р и л оже н и е А .

410

Краткое изл ожен ие оболо ч ки

Примеры:
set

-

vx

s e t " $ name " " $ addre s s " " $ phone "

Выв ести в се кома ндные строки
по мере их чтения , а та кже
каждую кома нду и ее аргументы
по мере их выполнения
Уста новить параметр $1 в
переменной $пате , параметр
$2
в переменной $address ,
а параме тр $3
в переменной
$phone
Уста новить в параметре $1
зна чение - 1
Уста новить режим реда ктиров а ния
строк в реда кторе vi
Выключить многословный режим ,
в ключить режим nogl.oЬ
-

-

set

-1

set -о

vi

s e t +о ve rbo s e - о n o g l ob

К ома нда shif t

Общая форма: s h i f t
Выполнение этой команды приводит к смещению позиционных параметров
$ 1 , $ 2 , ... , $ п на одну позицию влево. Это означает, что на позиции параметра $ 1
оказывается п араметр $ 2 , н а позиции параметра $ 2 - параметр $ 3 , а на пози ­
ции параметра $ п - 1 - параметр $ п. Соответственно корректируется и значение
переменной $ # .
Если же используется следующая форма данной команды:
shi ft

п

то смещение происходит на п позиций влево.
Примеры:
$ set а Ь с d
$ echo " $ # \n$ * "
4
а ь с d
$ shift
$ echo "$#\n$ * "
3
ь с d
$ shift 2
$ echo "$ #\n$ * "
1
d
$

Сводка команд

411

Команда tes t

Общая форма :
test

условие

или
условие

Оболочка вычисляет заданное условие и возвращает нулевой код заверше­
ния, если в результате будет получено логическое значение TRUE. Есл и же в ре­
зультате будет получено логическое значение FALSE, то возвращается ненулевой
код завершения. А есл и при меняется форма [ условие ] , то после открывающей
скобки ( [) и перед закрывающей скобкой ( ] ) указывается пробел .
Заданное условие состоит из одной или нескольких операций, приведенных
в табл. А. 1 1 . Операция -а имеет больший приоритет, чем операция - о . Но в лю­
бом случае для группирования подвыражений употребляются круглые скобки.
Не следует только забывать, что круглые скобки при нимаются во внимание обо­
лочкой, поэтому они должны быть заключены в кавычки. Операции и операнды,
включая и круглые скобки, должны разделяться одни м или несколькими пробе­
лами, поэтому команда t e s t интерпретирует их как отдельные аргументы. Чаще
всего команда t e s t применяется для проверки услови й в операторах, реализуе­
мых командами i f, wh i l e или unt i l .
Пример ы:
#

выяснит ь , является ли файл

i f test
then



perms

и с п ол н я е мым

/ e t c / pe rms

fi
#
#

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

if [
then
fi

-d

$ f i l e - о \ ( - f $ f i l e -а -r $ f i l e \ ) ]

412

П ри л о же н и е А .

Краткое изложен ие оболочки

Табл ицы А. 1 1 . Операции , исполь зуемые в ком анде tes t

Воз вра щает ло ги ч еское зна ч ен ие ТRUE,
т.е. нул евой код завер ш ен и я п ри услови и , что" .

Опера ц и я

Файл овые операции
-Ь файл

Указанный файл является специальным файло r.:. блоч ­
ного устройства

файл

Указанн ы й файл является специальным файлом сим­
вольного устройства
Указанный файл является каталогом



-d файл


Указанн ы й файл существует

файл

- f файл
-g файл

-h

Указанный файл является обычным файлом
В указанном файле установлен бит смены идентифика­
тора группы ( SGID)
Указанный файл является символической ссылкой

файл

В указанном файле установлен бит закреплен ия

-k файл
- L файл

Указанный файл является символической ссылкой

-р файл

Указанный файл является именованным каналом

-r файл

Указанный файл доступен для чтения в текущем процессе
Указанн ы й файл является сокетом
Указанн ы й файл имеет ненулевую длину

- S файл
- s файл
- t fd

Указанный параметр fd является дескриптором откры ­
того файла, связанным с терминалом ( по умолчанию он
равен 1 )



файл

В указанном файле установлен бит смены идентифика­
тора пользователя ( SUID)

-w

файл

Указанный файл доступен для записи в текущем про­
цессе



файл

Указанный файл является исполняемым

Стро ков ы е опера ц и и

Указанная С11!р0Ка не является пустой

C'l!pOKa
-n

строка

Указанная строка не является пустой и должна быть
проверена в команде tes t

-z

строка

Указанная строка является пустой и должна быть про­
верена в команде tes t
Указан н ая строка1 равна заданной строже2

строка1

с трока2

строжа1

! = строка2

Указанн ая строка1

не

равна задан ной строке2

Цел очи сл енные операц ии сравнения
in t1 -eq int2

Указанн ые целоч исленные значения in t1 и in t2 равны

int1 -ge in t2

Указанное целоч ислен ное значение int1 больше или
равно задан ному целоч исленному значению in t2

Сводка ко манд

413

Окончание табл. А . 1 1
Оп ера ц ия

Воз вращает л о ги ч еское значение ТRUE,
т.е. нулевой код за вершен и я п р и услови и , что" .

Указанное целочисленное значение int1 больше задан­
ного целочисленного значения int2
Указанное целочисленное значение int1 меньше или
равно заданному целочисленному значению in t2
Указанное целочисленное значение int1 меньше задан ­
ного целочисленного значения int2
Указанные целочисленные значения int1 и int2 не равны

Ло гич ески е оп ерации
! выражение

Заданное выражение оказывается ложным ( FALSE ) , а
иначе - истинным (TRUE )
Истин ным (TRUE ) оказывается как выражение1 так и
выражение,

выражение1 - о выражение2

Истинным (TRUE ) оказывается выражение1 или
ражение2

вы­

Ко ма нда times

Общая форма: t ime s
Выполнение этой команды приводит к тому, что оболочка направляет в стан­
дартный вывод общее коли чество времени, использованного оболочкой и всеми
порожденными ею процессами. Для каждого из этих процессов выводятся два
числа: первое обозначает н акоплен ное пользователем время, а второе - время,
накоплен ное системой. Однако команда t ime s не сообщает время, использован­
ное встроенными командами.
Пример:
$ times
lm5 s 2m9 s

8m2 2 . 2 3 s 6m2 2 . 0 l s

Выве сти время , использова нное проце с сами
1 минута , 5 секунд польз ов а тель ского
времени , 2 минуты, 9 секунд
системного времени
Время , исполь зова нное
порожденными проце с сами

$

Команда trap

Общая форма : t rap команды сигналы
Эта команда предп исывает оболочке выполн ить указанные кома нды всякий
раз, когда она получает один из переч исленных сигналов. Эти сигналы могут
быть указаны по имени или номеру.

414

П р и тюже н и е А .

Краткое и зложен ие оболоч ки

Если команда t rap введена без аргументов, она выводит список назначенных
обработчиков прерываний. Если же в качестве первого аргумента указана пустая
строка, как следующем примере:
t rap " " сигналы

то перечисленные сигналы и гнорируются оболочкой при их получении.
А если команда t rap используется в следующей форме:
t r ap сигналы

то обработка каждого из перечисленных сигналов сводится к стандартному
действию, устанавливаемому по умолчанию.
Пример ы :
t r ap " e cho hangup > > $ E RR F I LE ; e x i t "

HUP

t rap " rm $ TMP F I LE ; e x i t " 1 2 1 5

t r ap
t r ap 2

2

При за виса нии вывести
сообщение в журнал
регистра ции и выйти
Удалить фа йл , ука за нный
в п ереме нной $ТМPFILE ,
по сигналу 1 , 2 или 15
Игнорирова ть прерыва ния
Восста новить ста ндартную
обра бо тку прерыва ний

В табл. А. 1 2 перечислены значения, которые могут быть указаны в списке сиг­
налов, обрабатываемых по команде t r ap.
Табл и ца А. 1 2 . Наи меновани я и номера сигналов ,
перечисл яемых в команде trap

Номер
си гн ала

Н а и мен ова н и е
си гн а л а

Когда генерируется

о

EXIT
HUP
INT

При выходе из оболочки
При зависани и

6

QUI T
АВRТ

При выходе из программы
При авари йном или преждевременном завершении про­
граммы

9
14
15

KILL
ALRМ
ТЕRМ

1
2
з

При прерывании ( например, нажатием клавиши
или комбинации клав и ш )

При уничтожени и процесса
По истечени и аварийной выдержки времен и
По сигналу прерывания программы, посылаемому коман­
дой kill по умолчанию

Сводка ком а нд

41 5

Оболочка просматри вает указанные кома нды, когда обнаружи вает команду
t r ap, и делает это снова при получени и одного из перечисленных сигналов. Это,
например, означает, что при обнаружении следующей команды:
t r ap " e cho $ co u n t l i n e s p ro c e s s e d > > $ LOGF I LE ; e x i t "

HUP

I NT ТЕRМ

оболочка подставляет в данный момент значение переменной count, но не дела­
ет этого при получении одного из перечисленных сигналов. Получить значение
перемен ной count, подставляемое при поступлени и одного из перечисленных
сигналов, все-таки можно, если заключить указанные команды в оди ночные ка­
вычки, как показано ниже.
t r ap

' e cho $ c ount l i n e s p r o c e s s ed >> $ LOGF I LE ; e x i t '

HUP

I NT

ТЕRМ

Кома нда true

Общая форма : t rue
Эта команда возвращает нулевой код завершения.
Ко манда type

Общая форма: t уре кома нды
Эта команда выводит сведения об указанных кома нда х.
Примеры:
$ type troff echo
t r o f f i s / u s r / b i n / t ro f f
echo i s а s he l l b u i l t i n
$

Ко ма нда umask

Общая форма: uma s k ма ска
Эта команда устанавливает стандартную ма ску для создания файлов. Задан­
ная маска накладывается н а создаваемые в дальнейшем файлы по логической
операции И, чтобы определить режим доступа к файлу. Если команда uma s k ука­
зана без аргументов, она выводит текущую маску. А параметр - S предписывает
вывес_ти маску в символическом виде.
Примеры:
umask
0002
$ umask 022

$

$

Выв е с ти текущую ма ску
З а пре тить за пись в фа йл другим пользова телям
З а прети т ь за пись в ф а йл в сем членам труппы

416

П р и л о же н и е А .

К раткое изложен ие оболочки

Ко ма нда unal ias

Общая форма: una l i a s имена
По этой команде указанные имена удаляются из списка псевдонимов. Пара­
метр -а предписывает удалить все псевдонимы.
Ко м а н да unset

Общая форма: un s e t имена
Выполнение этой команды приводит к стиранию определений переменных
или функций, перечисленных среди указанных имен. Переменные, доступные
только для чтения, не могут быть восстановлены в исходное состоя ние. Параметр
-v команды un s e t указывает на то, что далее следует имя переменной, тогда как
параметр -f
имя функции. Если же ни один из параметров не задан, то далее
предполагаются имена переменн ых .
-

Примеры:
un s e t dЬ l i s t f i l e s

Удалить определения переменных dЬli st и files

Ко м а нда u n til

Общая форма:
un t i l кома нда ,
do
кома нда
кома нда
done

Сначала в приведенном выше цикле unt i l , реализуемом описываемой здесь
командой, выполняется указан ная кома нда , и проверяется код ее завершения.
Если этот код оказывается ненулевым, то выполняются команды , указанные в
промежутке между операторами do и done. Затем указанная кома нда , выполня­
ется снова и проверяется код ее завершения. Если и на этот раз код завершения
оказывается ненулевым, то команды, указанные в промежутке между оператора­
ми do и done, выполняются повторно. Этот процесс продолжается до тех пор,
пока указанная команда, не возвратит нулевой код завершения. Далее выполне­
ние продолжается с команды, следующей сразу же после оператора done.
Указанная кома нда, выполняется в самом начале ци кла unt i l , и поэтому ко­
манды, заданные в промежутке между операторами do и done, могут быть вооб­
ще не выполнены, если в результате первой же проверки условия данного цикла
возвратится нулевой код завершения.

Сводка команд

41 7

Пример:
# ожидат ь по 60 се кунд до т е х пор , пока по л ь зователь
# j ack не войдет в с и с тему
unt i l who 1 g r e p j a c k > / d e v / n u l l
do
s l e ep 6 0
done
echo j a c k ha s l o gged on

В при веденном выше примере цикл unt i l продолжается до тех пор, пока ко­
манда grep не возвратит нулевой код завершения (т.е. обнаружит имя пользова­
теля j a c k в результате, выводимом командой who). В этот момент цикл unt i l
завершается и далее выполняется команда e cho.
Команда wai t

Общая форма : wa i t зада ние
Выполнение этой команды при водит к тому, что оболочка приостанавливает
свое выполнение до тех пор, пока не заверш ится процесс, который обозначает
указанное зада ние. Если же зада ние не указано, то оболочка ожидает заверше­
ния всех порожденных процессов. А если указано несколько заданий, то команда
wa i t будет ожидать завершения всех этих заданий. Команда wa i t удобна в тех
случаях, когда требуется организовать ожидание завершения процессов, отправ­
ленных на выполнение в фоновый режим. Для получения идентификатора по­
следнего процесса, отправлен ного на выполнение в фоновый режим, можно вос­
пользоваться перемен ной $ ! .
Пример:
s o r t l a rge f i l e > s o r t ed f i l e &
wa i t

Отсортиров а ть в фоновом режиме
Продолжить о бра бо тку
А теперь подожда ть за в ершения
сортиров ки

p l o t da t a s o r t e d f i l e

Команда whi le

Общая форма:
wh i l e кома нда ,
do
кома нда
команда
done

Сначала в при веденном выше цикле wh i l e , реализуемом описываемой здесь
командой , выполняется указанная кома нда , и проверяется код ее завершения.

418

П р и л о же н и е А .

Краткое изл ожен ие обол очки

Если этот код оказывается нулевым, то выполняются команды, указанные в про­
межутке между операторами do и done. Затем указан ная команда1 выполняет­
ся снова и проверяется код ее завершения. Если и на этот раз код завершения
оказывается нулевым, то команды, указанные в промежутке между операторами
do и done, выполняются повторно. Этот процесс продолжается до тех пор, пока
указанная кома нда 1 не возвратит ненулевой код завершен ия. Далее выполнение
продолжается с команды, следующей сразу же после оператора done.
Указанная кома нда 1 выполняется в самом начале цикла wh i l e, и поэтому
команды, указанные в промежутке между операторами do и done, могут быть
вообще не выполнены, если в результате первой же проверки условия данного
цикла возвратится ненулевой код завершения.
Пример:
# з а п о л ни ть ос т а л ь ную час т ь буфера пус т ыми с т ро к а ми
wh i l e
do

[ $ l i ne s - l e $ma x l i n e s
echo > > $ B U FFER
l ines=$ ( ( l ines + 1 ) )

done

Дополн и тел ьн ые
и с т оч ни ки и нформ ац ии
Имеется немало источников информации п о оболочкам, действующим в ре­
жиме командной строки систем Unix, Linux и Мае OS Х, но в этом приложении
выбрана литература и ссылки на веб-сайты, представляющие особую ценность
для программирующих на языке оболочки. Все приведенные ниже ссылки на веб­
сайты были актуальны на момент выхода данной книги из печати, но, как часто
бывает в Интернете, некоторые из н их могут оказаться недействительными на
момент чтения книги.

О п е ра ти в н о до ступ н а я до ку м ен та ци я
Если документация на вашу систему недоступ на в печатном виде, воспользуй ­
тесь командой man, чтобы получить нужную и нформацию о конкретной команде
Unix из так называемых оперативных стр аниц руководства. Ниже приведена об­
щая форма данной команды.
man кома нда

Есл и вы не знаете точно наименование искомой команды, то команда man k
поможет вам выявить ее в системе Linux или Unix, как демонстрируется в следу­
ющем примере из версии Ubuntu системы Linux:
-

$ man - k dvd
brasero

(1)

Ьtcflash

(8)

dvd+ rw-bo o k t ype

(1)

dvd+ rw - f o rma t

(1)

dvd+ rw-me d i a i n f o

(1)

- S imp l e a n d e a s y t o u s e C D / DVD b u r n i n g
a pp l i ca t i o n f o r . . .
( Прос та я команда для за пи с и CD/DVD )
- f i rmw a r e f l a s h u t i l i t y f o r ВТС DRW 1 0 0 8
DVD+ / - RW r e c o r de r .
( Утилита для пропмвки в страива емого ПО
с помощью устройства за пи си В ТС DRW1 0 0 8
н а ди ски D VD + / - R W)
fo rma t DV D+ - RW / - RAМ di s k w i t h
а l o g i c a l f o rma t
( Кома нда логического форма тирова ния
дисков DVD+ - RW/ - RAМ)
- f o rma t DVD+ - RW / - RAМ d i s k
( Кома нда форма тирова ния дисков

-

DVD+ - R W/ - RAМ)

- d i s p l a y i n f o rma t i on abou t dvd

420

П р и л ож е н и Р Б.

Доп ол н ител ьн ы е источ н и к и и нф ор мации

dvd - r am- con t r o l

(1)

g rowi s o f s

(1)

rp l 8

(8)

d r i ve and d i s k
( Кома нда для выв ода св едений о
на копителе и диска х DVD )
- che c k s fea t u r e s o f DVD - RAM d i s c s
( Кома нда , пров еряюща я состояние
ДИСКОВ

DVD-RAМ)

- c omЬ i ne d g en i s o image f r o n t e n d / DVD
r e c o r d i n g p r o g r am .
( Утилита , объ единенна я с клиентской
пporpatvrМoй gen i s o iшa ge созда ния обра зов
и за писи дисков D VD )
- Fi rmw a r e l o a de r f o r D V D d r i ve s
( За rруз чик в строенного ПО с дисков D VD )

$

В некоторых системах документация доступн а в диалоговом режиме по ко­
манде i n fo. Для доступа к документации достаточно набрать сначала команду
i n fo, а после ее запуска ввести h, чтобы получить справку.

Д о ку м ент а ция , до ступ н а я в И нте р н ете
Самым лучшим местом для поиска в Интернете сведений о стандарте POSIX
служит веб-сайт, доступный по адресу www . un i x . o r g. На этом веб-сайте под­
держивается Открытая группа ( Open Group) - международный консорциум,
принимавший участие вместе с институтом IEEE в работе над созданием текущей
спецификации стандарта POSIX, а также имеется полное описание дан ной специ­
фикации . Для ее чтен ия нужно сначала зарегистрироваться на данном веб - сайте,
причем бесплатно. Соответствующая документация доступ на по ссылке www .
un i x . o r g / o n l ine . h tml .

Фонд свободного программного обеспечения (Free Software Foundation) под­
держивает оперативно доступную документацию на самые разные утилиты Linux
и Unix, включая комп илятор Bash и С, по ссылке www . f s f . o r g /manua l .
Дэвид Корн, являющийся разработчиком оболочки Korn, поддерживает веб­
страницу по адресу www . ko r n s he l l . com. На этой странице содержится доку­
ментация, загружаемое программное обеспечение, сведения о литературе по обо­
лочке Korn, а также ссылки на информаци ю о других оболочках.
Если у васимеется доступ только к системам Microsoft Windows, но вы все же
стремитесь освоить программирование на языке оболочки или хотя бы опробо­
вать систему Linux, рекомендуется установить пакет Cygwin, доступный по адре­
су www . cygw i n . сот. В состав базовой системы входит оболоч ка Bash и немало
других утилит командной строки, благодаря которым система Linux действует
аналогично Unix. Но самое главное, что пакет Cygwin свободно доступен для за­
грузки и применения.

Л итерату ра

421

Л ите ра ту ра
Ниже приведен перечень рекомендованной для чтения литературы по про­
граммированию на языке оболочки в системах Unix.
И здател ьство O ' R e i l ly & Associ ates

В издательстве O'Reilly & Associates (www . o r a . с от) вышло в свет немало ли­
тературы по системам Linux и Unix. Темати ка книг этого издательства охватывает
самые разные предметы. Эти книги можно приобрести на веб-сайте издательства,
а также в рознич ной торговле через Интернет и в книжных магазинах. На веб­
сайте издательства O'Reilly & Associates можно также найти немало полезных ста­
тей по системам Linux и Unix.
К рекомендуемой л итературе по системам Linux и Unix относятся следующие
книги.

Unix in а Nutshell, 4th Edition, А. Robblпs, O'Reilly & Associates, 2005 (в русском
переводе вышла под названием UNIX. Справочник, А. Роббинс, издательство
"Кудиц- Пресс", 2006 г. ).

Linux in а Nutshell, бth Edition, Е. Siever, S. Figgins, R. Love апd А. Robblпs, O'Reilly
& Associates, 2009.
Для обучения программирован и ю на языке Perl от начального до продви нуто­
го уровня можно порекомендовать следующую л итературу.




Learning Perl, бth Edition, R. L. Schwartz, В. Foy апd Т. Phoeпix, O'Reilly & Associates,
201 1 .
Perl in а Nutshell, 2nd Edition, S. Spaiпhour, Е. Siever, апd N. Patwardhaп, O'Reilly
& Associates, 2002.

Версии команд awk и s e d по стандартам POSIX и GNU хорошо описаны в
следующей книге.


Sed & Awk, 2nd Edition, D. Dougherty апd А. Robblпs, O'Reilly & Associates, 1 997
(ISBN 978- 1 - 56592 - 225-9).
Для пользователей системы Мае OS рекомендуется следующая книга.



Learning Unixfor OS Х, D. Taylor, O'Reilly & Associates, 20 1 2 .

И зда'тел ьство Pea rson

Изучить основы программирования на языке оболоч ки в системе Uпix можно
в следующей кни ге.

Sams Teach Yourself Shell Programming in 24 Hours, 2nd Edition, S. Veeraraghaven,
Sams PuЬlishiпg, 2002.
Хорошим пособием для обучения программированию на язы ках С и Perl в си­
стеме Uпix служит следующая кни га.


Sams Teach Yourself Unix in 24 Hours, Sth Edition, D. Taylor, Sams PuЬlishiпg, 20 1 6.

422

П р и л ож е н и е Б.

Допол н ител ьные источ н и к и и н фор ма ц и и

В приведенной ниже книге рассматривается широкий круг вопросов, связан­
ных с FreeBSD - надежной и свободно доступной версией UNIX, которая при­
меняется вместо Linux на многих требовательных предприятиях. В дан ной книге
приводятся подробные сведения о версии FreeBSD, которые вряд ли удастся най­
ти где-нибудь еще .

FreeBSD Unleashed, 2nd Edition, М. Urban and В. Tiemann, Sams PuЬlishing, 2003.
Для начинающих изучать версию FreeBSD рекомендуется следующая книга,
где подробно излагаются не только самые основы, но и особенности данной опе­
рационной системы.


Sams Teach Yoиrself FreeBSD in 24 Hoиrs, Michael Urban and Brian Tiemann, 2002.

Исчерпывающим справочником по оболочке С служит следующая книга.


Тhе Unix С Shell Field Gиide, G. Anderson and Р. Aпderson, Prentice Hall, 1 986.

Полное описание языка awk дается его создателями в следующей книге.


Тhе AWK Programming Langиage, А. V. Aho, В. W. Kerпighaп, and Р. J. Weiпberger,
Addison-Wesley, 1 988.

Следующая книга служит отличным пособием для совершенствования навы­
ков программирования в среде Unix.

Тhе Unix Programming Environment, В. W. Kernighan and R. Pike, Prentice Hall,
1 984 (в русском переводе вышла под названием Unix. Программное окружение,
Брайан У. Керниган, Роберт Пайк, издательство "Символ-Плюс", 2003 г.).
И наконец, следующая книга служит удобным пособием для совершенствова­
ния навыков программирования в среде Liпux.


Advanced Linиx Programming, М. Mitchell, J. Oldham, апd А. Samuel, New Riders
PuЬlishiпg, 200 1 (в русском переводе вышла под названием Пр ограммир ование
для Linиx. Пр офессиональный п одход, Марк Митчел, Джеффри Оулдем, Алекс
Самьюэл, ИД "Вильяме': 2004 г. ).

П редмет н ы й ук аз ател ь
А
Аргументы
определение, 22
передача по ссылке
на любой позиции, 1 63
переменного кол ичества, 1 57
порядок, 1 55
в
Ввод-вывод
кон вейеризация из ци кла, 220
переадресация
встраиваемая, 3 1 2
механизмы, 48; 50
разновидности конструкций, 388
стандартный
из команд на терминал, принцип, 46
ошибок, механ изм, 53
переадресация, 3 1 0
Встраиваемые документы, определен ие, 3 1 2

д

Дополнительные источники информаци и
документация
доступная в И нтернете, 420
оперативно доступная, 4 1 9
перечень рекомендованной литерату­
ры, 42 1

3
Задания
незавершенные, вывод состояния, 369
определение, 368
остановка и возобновление, 369; 39 1
ссылк-а по идентифи катору, 390
текущие и предыдущие, обозначение, 369
указание идентифи каторов, 390
управление, 369
Заключение в кавычки
двойные, механ изм, 1 39
обратные, механизм, 1 45
одиночные, механ изм , 1 35
разновидности механ измов, 385
типы знаков кавычек, 1 35
Замена знака тильды, механизм, 372; 386

к
Каналы
в сложных конвейерах, организация, 53
назначен ие, 5 1
организация, 52
применение фильтров, 53
Каталоги
копирование, файлов, 34
корневые, назначение, 27
начальные, н азначение, 27
организация и структура, 26
перемещен ие файлов, 35
родительские, назначение, 28
создание, 33
текущие рабочие, назначение, 27
удаление, 40
указание путей к файлам, 27
Коды завершения
назначение, 1 65; 397
определение, 377
разновидности, 1 65
Ком анды
оболочек Korn и Bash
!строка и ! ! , описание, 354
cd, описание, 372
h istory, описание, 352
r, описание, 353
typeset, описание, 357
стандартной оболоч ки
alias, описание, 360; 392
Ьg, описание, 369; 393
Ьrеаk, описание, 2 1 6; 393
саsе, описание, 1 90; 1 97; 393
cat, описание, 23
сd, описание, 37 1 ; 394
chmod, описание, 1 22
continue, описание, 2 1 7; 395
ер, описание, 24; 34
cut, описание, 89
date, назначение, 2 1
echo, описание, 22, 395
eval, описание, 303; 396
ехес, описание, 276; 397
exit, описание, 1 84; 397

424

П редметн ы й указател ь

export, описание, 256; 260; 397
expr, описание, 1 5 1 ; 1 53
tс, описание, 353; 382; 398
fg, описание, 369; 399
for, описание, 203; 400
getopts, описание, 22 1 ; 400
grep, описание, 1 05; 1 1 1
hash, описание, 402
if, описание, 1 65; 402
j obs, описание, 405
kill, описание, 369; 405
ln, описание, 36
ls, описание, 23
mkdir, описание, 33
mv, описание, 25; 35
newgrp, описание, 406
paste, описание, 94
printf, описание, 246
ps, описание, 56
pwd, описание, 28, 406
read, описание, 227; 406
readonly, описание, 302; 407
return, описание, 32 1 ; 408
rm, описание, 2 5
rmdir, описание, 40
sed, описание, 96
set, описание, 292; 298; 408
shift, описание, 1 63; 4 1 0
sort, описание, 1 1 1 ; 1 1 6
test, описание, 1 70; 1 75; 4 1 1
times, описание, 4 1 3
trap, описание, 307; 3 1 0; 4 1 3
true и false, оп исание, 2 1 6
tr, описание, 1 00; 1 05
type, описание, 322; 4 1 5
umask, описание, 4 1 5
unalias, описание, 362; 4 1 6
uniq, описание, 1 1 6; 1 1 9
unset, описание, 302; 4 1 6
until, описан ие, 4 1 6
wait, описан ие, 305; 4 1 7
wc, описание, 23
while, описание, 208; 4 1 7
who, описание, 2 1
общая форма ввода, 377
одновременный ввод в одной строке, 55
организация ввода-вывода, принцип, 46
переадресация ввода-вывода,
механизм, 49

передача на выполнение в фоновый
режим, 5 5
порядок ввода, 377
пустые, описание, 1 98; 39 1
сводка, 39 1
точ ки, описание, 272; 392
Комментарии
назначение, 1 24
обозначение, 378
применение, 1 24
Конструкции
$(( выражен ие) ), описание, 1 32
${n}, описание, 163
$( . . . ), оп исание, 1 46
${ переменная } , описание, 1 32
&&, описание, 1 99
1 1 , описание, 200
&-, назначение, 3 1 2
elif, оп исание, 1 87
else, описание, 1 8 1
для выполнения команд, 389
для сопоставления с шаблоном, 289
круглые и фигурные скобки, описание, 277

м
Массивы
доступ к элементам, 362
индексация, 363
применение, 365
разреженные, определение, 364
о
Оболоч ки
Bash и Korn
арифмети•1еские операции,
целоч исленные, 355
конструкции массивов,
разновидности, 368
манипулирован ие массивами, 362
назначение, 339
операции над ч ислами в разн ых
системах счисления, 357
типы дан ных, целочисленные, 357
фун кции, поддержка, 355
встроенный интерпретируемый язык,
назначение, 7 1
выбор, порядок, 340
запуск, механизм, 377
исходные, назначение, 62
как служебные программы, назначение, 59

П редм етн ы й указател ь

командная строка, назначение, 66
контроль окружения, 7 1
обязанности, 65
переадресация ввода-вывода, 68
подключение конвейера, механизм, 70
подстановка значений переменных и
имен файлов, 67
поиск, порядок, 373
разновидности, 65
режимы, доступные в команде set, 409
совместимость, 374
специальные символы, применение, 66
среда
назначение, 253
настройка, 273; 28 1
установка, 340
Операции
арифметические
общая конструкция
для выполнения, 386
приоритетность, 387
разновидности, 386
круглые скобки , применение, 1 80
логические
И, применение, 1 79
ИЛИ, применен ие, 1 80
отрицан ия, применение, 1 79
сравнения, целочисленные, разновидности, 1 76
строковые, разновидности, 1 72
употребляемые в команде test, 4 1 2
файловые, разновидности, 1 78

п
Параметры
- х , применение
для отладки программ, 1 94
для трассировки команд, 293
дост у пные в команде set, 408
позиционные
определение, 1 55
переназначен ие, способ, 294
подстановка, 1 56
присваивание и ссылка, 378
смещение, 1 63
указание, порядок, 24
Переменные
арифметическое расширение, опера­
ции, 1 32

425

локальные
доступность, 254
принцип действия, 259
назначен ие, 1 2 5
неопределенные, обработка, 1 29
оболочки
дополнительные возможности, 389
обозначение, 378
специальные, разновидности, 378
окружения
CDPATH, назначение, 27 1
ENV, назначение, 340
НISTFILE, назначение, 342
HISTSIZE, назначение, 342
НОМЕ, применение, 2 6 1
РАТН, назначение, 263
PS 1 и PS2, назначение, 260
SHELL, назначение, 34 1
TERM, назначение, 282
TZ, назначение, 283
отображение значений, 1 26
присваивание значени й , 1 25; 285
специальные
$0, применен ие, 29 1
$$, назначение, 242
$ ! , назначение, 306
$?, назначен ие, 1 66
$@, назначение, 207
$*, назначен ие, 1 57
$#, назначение, 1 56
IFS, назначение, 298
OPTARG, назначение, 223
OPТIND, назначение, 223
целочисленные операции, 1 26; 1 32
экспортируемые
доступ н ость, 256
принцип действия, 259
Подоболочк и
доступность локальных переменных, 254
назначение, 254
определен ие, 389
особенности среды, 255
передача переменных
другой способ, 280
путем экспорта, 256; 389
Подстановки
значений
параметров, конструкции , 285; 29 1 ; 380
переменных в командной строке, 67; 1 30

426

П редметн ы й указател ь

имен файлов
в командной строке, 67; 1 30
механ измы, 4 1
специальные символы, 387
характерные примеры, 44
команд
вложенные, применение, 1 50
применение, 1 48
способы, 1 45
позицион ных параметров, порядок, 1 56
сложные, по шаблонам, 43
Предыстория команд
в режиме редактора
emacs, доступ, 349
vi, доступ , 345
ведение, 342; 382
доступ к командам, 346; 382
другие способы доступа, 352
Программы
аdd, описание, 1 60; 266; 328
addi, описание, 243
align, описание, 2 5 1
change, описание, 333
ctype, описание, 1 93 ; 1 96
db, описание, 274
display, описание, 329
greetings, описание, 1 86; 1 9 7
listall, описание, 3 3 4
lu, описание, 1 58; 265; 266; 328
mycp, описание, 227; 230; 232
number, описание, 1 9 1 ; 1 92; 244
number2, описание, 300
оп, описание, 1 67; 1 8 1
rem, описание, 1 6 1 ; 1 84; 1 88; 266; 33 1
reverse, описание, 364
rolo, описание, 236; 266; 323; 3 3 5
run, описание, 206
shar, описание, 3 1 7
waitfor, описание, 2 1 1 ; 2 1 5; 223; 278
words, описание, 295; 297
Процессы
идентификаторы, получение и хране­
ние, 306
родительские и порожденные, выполне­
ние, 305
Псевдонимы
назначение, 359
определение, 359
удаление, 362

р
Регулярные выражения
в команде grep, описание, 1 09
применение, 73
совпадение
с заданным количеством сим вощ>в, 79
с концом строки, 76
с началом строки, укоренение слева, 75
с одиночным символом, 73
с точным количеством подшаблонов, 83
с шаблонами, 73
сохранение совпавших символов, 85
специальные символы, применение, 87; 1 92
Редактирование строк
в редакторе
emacs, особенности, 347
vi, режимы и команды, 343; 347; 382
выбор режима, 342
Редакторы
ed
назначение, 74
примеры применения, 78
emacs
доступ к командам из предыстории, 349
команды редактирования строк, 348; 35 1
sed
назначение, 96
примеры применения, 99
vi
команды редактирования строк, 344;
347
режимы редактирования строк, 343
с
Сигналы
назначение, 307
наименования и номера, 307
обработка, 307
сброс прерываний, 31 О
указываемые в команде trap, 4 1 4
Символические ссылки
назначение, 38
висячие, определение, 39
Системы Unix
активизация терминала, процесс, 60
командная строка как стандартный поль­
зовательский интерфейс, 1 7
команды как инструменты, 1 7

П редметн ы й указател ь

427

оболоч ки
как интерпретируемый язык
программ ирован ия, 1 8
назначение, 1 7
происхождение, 1 7
подоболоч ки и процессы, 63
ядро и утилиты, 59
Специальные символы
в регулярных выражениях, примене­
н ие, 87
интерпретация в оболоч ке, 1 37
обратная косая черта
в двойных кавычках, употребление, 1 44
продолжение строк, 1 43
экранирование сим волов, 1 42
совпадения с шаблоном, применение, 1 92
управляющие, применение в команде
echo, 230; 395
экранирование, 1 42
Специфи каторы формата
модификаторы, применение, 250
применение, 246
разновидности, 247

подстановка имен, 4 1
пробелы в именах, указание, 44
пути абсолютные и относител ьные, указание, 27
разновидности и назначение, 22
режимы доступа, обозначение, 33
связывание
особенности , 38
символические ссылки, назначение, 38
создание копии, 24
специальные символы в именах, указа­
ние, 45
удаление, 25
Функции
выполнение, порядок, 3 1 8
назначен ие, 3 1 8
определение
общая форма, 3 1 8; 390
удаление, 32 1
преимущества, 320
применение, 3 1 8
размещение, порядок, 3 1 9

ф
Ф айлы
profile
назначение, 28 1
настройка, 28 1
.sh_history, назначение и ведение, 342
/etc/profile, назначение, 28 1
ENV, назначение, 34 1
дескрипторы, обозначение, 3 1 О
командные, применение, 1 23
оболочек, архивные
применение, 3 1 6
создание, 3 1 4
отображение содержимого, 23
пере� менование, 25
перечисление, 23

Циклы
for
без списков, 208
организация, 204
применение, 204
until
организация, 2 1 О
применение, 2 1 1
while
организация, 209
применение, 209
ввод в одной строке, 220
выполнение в фоновом режиме, 2 1 8
конвейеризация ввода-вывода, 220
прерывание, 2 1 6
пропуск шагов цикла, 2 1 7

ц

КОМАНДНАЯ СТРОКА LI NUX
И СЦЕНАР И И ОБОЛОЧ КИ .
Б И БЛИЯ ПОЛ ЬЗОВАТЕЛЯ

2-е издание
Ричард Блум,
Кристина Бреснахэн
в :пo i i

I O \ l l l "l'

в ы 1 1 a i i;tt'Тl' B 1 10

во .\ll l O l ' l l X it l l l' T j) l l U)'T l l B< I X ( _ i 1 н 1 х


1 1 1 1терфе i i с о м 1ыuо • 1 с 1 '0 сто.· 1 а .

с у м е ют IIO!' l lO Л l>: IOB ою т р я 1 1 а м а л ы й о б ъ е м
к а р �1 а 1 1 1 ю го н :щ ан и я ,
в 1 1 (.' М С О/ll'\)Ж И Т С Я в с е , ч то

1 1 еобхол и м о

:ш ап,

дл я

разработ к и п ро ф е с с и о н а л ь н ы х
веб-п риложен и й .
I :'! а в ы

1-9

посвя щен ы

о п и с а н и ю с и н т а кс и с а

п оследней в е р с и и я з ы к а
(с п е ц иф и к а ц и я E C M A S cгipt 5 ) .
· Ти п ы дан н ы х , значения
и п е р е м е н н ые
O'REILLY' �

)i.7f�/I() Ф'Ullfl?ШI

·

·

www.williamspuЬlishing.com

И н с т ру к ц и и о п е раторы
u ы раже н и я
О б ъ е к т ы и м ас с и в ы
,

и

· Классы н фун к ц и н
· Ре 1·у:1 я р 11 ы с в ы р а ж е н и .и
В гл а в а х 1 0 - 1 /i
рас с м ат р и в а ю т е я
фу 1 1 к 1 ню 1 1 а л ы1 ы е в о : 1 м о ж 1 юс т и

я :i ы к а н а р я д у с м о;tе:� ь ю
f)()M

И

C j) l'J\C T B il M ll

1 1 од л е рж к н

I S B N 978 - 5 - 8 4 5 9 - 1 8 30 - 7

в

п родаже

1 IТ М 1. 5 .

РНР и MySQL™

Карманны й справочник
Кристиан Уэнц

Эта к н �1 га , н е п рете ндуя
на п ол н оту о п и с а н ин всех
воз м о ж н осте й , п редоста вл яе м ы х
НЮ6ХОДММWЙ КОД И КОМАНДЫ

8
.

РН Р и
MySQLm

я з ы ко м Р Н Р, п редл а гает дл я
расс мотре н и я те м ы , с которы м и
Р Н Р - п рогра м м и ст стал к и ваетсн
п р а кт и ч е с к и е жедне в н о . Автор
п р и л ож и л м а к с и м у м ус ил и й ,
чтобы этот карман н ы й с п раrюч н и к
с оответство вал п ослед н и м
ста ндарта м ю ы ка Р Н Р, и
а к ц е н тировал в н и м а н и е на н о в ы х
1ю3 м о ж н остях верс и й Р Н Р 5 . 3 и 5 . 4 .
П ос кол ьку

СУБД

MySQ L остается

п о вс е м естно п р и н ят ы м ста ндартом
баз да н н ы х для п р иложе н и й на Р Н Р,

о н а за служ и л а отдел ь н о й гла в ы .

Все л и сти н ги и з к н и ги доступ н ы дл я

за груз к и , а и х код п ротестирован
н а та к и х пл атфо р м а х , к а к Linux,
Wi ndows, М а е O S Х и S o laris.

www.wi lliamspuЫishing .com

I S B N 978 - 5 - 8459-2019-5

в

п р одаже

П РО ГРАМ М И РО ВАН И Е
КО МАНДН Ы Х О БО/\ОЧ Е К
В U N IX, LI N UX И O S Х
4-Е ИЗДАН И Е
Это полностью обновленное изда н и е кла ссическо го пособ и я п о п рогра м м и ро ва н и ю ко м а н д н ы х оболочек
в с и сте м а х U п i x . Следуя м етоди ке изложе н и я мате р и а л а , п р и нятой в п е р в о н а ч а л ь н о м изда н и и , а вто р ы
к н и ги уделили о с н о в н ое в н и м а н ие ста ндартной оболоч ке POS IX, п о я с н я я особен ности разра ботки полез н ы х
п рогра м м в это й удо б н о й среде, чтобы из влеч ь м а кс и м альную пользу и з поте н ци а л а , заложе н н о го в основу
U п i x и подо б н ы х ей о п е р а ци о н н ы х с и сте м .
П осле кратко го обзора ко м а н д U п ix в к н и ге подро б н о рассматр и в а ется п оэта п н ы й п роцесс созда н и я
п рогра м м и л и с це н а р и е в оболо ч к и , их отладки и особ е н н осте й ра боты в с реде оболо ч к и . В с е о с н о в н ы е
средства оболо ч к и п о я с н я ются н а м н огих п ра ктических п р и мерах, что у п р о щает н а п и с а н и е с це н а р и е в
оболо ч к и для кон крет н о го п р и м е н е н и я . В к н и ге о п и с ы в а ются та кже осно в н ы е с редства оболочек К о r п и

Bas h .

УЗНАЙТ Е КАК" .
• В ы годно п ользоваться м н о ги м и утилита м и , п редоста вля е м ы м и с и сте м о й U п i x


П исать эффе кт и в н ы е сце н а р и и оболо ч к и

• И с п ользовать встрое н н ы е в оболоч ку кон струкц и и д л я в ы бора в а р и а нтов и о р га н и з а ц и и ц и клов


П р и м е н ять эффе кти в н ы е м еха н и з м ы за ключ е н и я в ка в ы ч ки

• И з вле кать м а кс и м а льную пользу из встрое н н о й в оболоч ку п редысто р и и ко м а н д и с редств их
реда кти рова н и я

• П ользоваться регуля р н ы м и в ы ра же н и я м и в ком а ндах U п ix


В ы годно пользо ваться с п е ци а л ь н ы м и с редства м и оболо ч е к Коrп и Bash

• В ы я влять о с н о в н ы е отл и ч и я в е р с и й я з ы ка оболо ч к и
• И з м е н ять п о рядок реа кци и с и сте м ы U п ix на дейст в и я пользо вателя


Н а стра и вать с реду оболочки



Пользо ваться фун к ци я м и

• Отлажи вать п рогра м м ы и с це н а р и и оболо ч к и

"Самая луч шая и действителыю класси ческая кн ига для обучен ия
программ ирован ию командных оболочек ".
Dr. Dobb 's Journal.

Стефа н Коча н

я вляется а втором нескольких популя р н ы х к н и г по ОС U п i x и я з ы ку С, в ключая Programmiпg iп

Programming iп Objective-C, Topics iп

С

С,

Progra mming и Exploring the Unix System . П режде о н ра ботал консультантом по

п рогра м м ному обеспеч е н и ю в ком п а н и и

АТ&Т

Bell Laboratories, где соста вил и вел курсы по Uпix и п рогра м м и ро ва н и ю

на я з ы ке С .

Патрик Вуд

ра ботает техн ическим ди ректором в филиале ком п а н и и E l ectro n ics for l m agi ng, н аходя ще мся в штате

Н ь ю-Дже рс и . Он входил в соста в и нженерно-техн и ч еского персонала ком п а н и и B e l l Laboratories, где в

1985

году

познаком ился со Стефа ном Коч а н о м . Совместно о н и основали консульта ционную ф и р м у P i p e l i п e Assoc iates, l nc . по ОС
U n i x , где Патр и к за н и м ал п ост в и це-президента . Кроме того, о н и сов местно н а п и сали ряд к н и г, в то м ч исле Exploriпg

the Ипiх System, Ипiх System Security, Topics iп

С

Programming и Unix Shell Programming.

Категория: операцион н ы е систе м ы U n i x
П редмет рассмотре н и я : п рогра м м и ро в а н и е

I S B N 978-5-9909445-3-4

Урове н ь : начальн ы й - пром ежуточ н ы й

�.№д.ila