Text
                    Д.Топхем,Хай  ВанЧыонг  ЮнИКС  И  КЬёНИКС
 Д.Топхем
 и
 •
 Хай  ВанЧыонг
 Издательство
 „Мир“


Юникс и Ксеникс
UNIX and XENIX A Step-by-StepGuide Douglas W. Topham Hai Van Truong Brady Communications Company, Inc. A Prentice-Hall Publishing Company Bowie
Д.Топхем, Хай Ван Чыонг Юникс и Ксеникс Перевод с английского B.B. Макарова и канд. техн. наук В.Ф. Оверченко под редакцией канд. техн. наук В.Д. Никитина Москва «Мир» 1988
ББК 32.973-01 T 58 УДК 681.31 Топхем Д., Чыонг X. В. T58 Юникс и Ксеникс: Пер. с англ. — M.: Мир, 1988. — 392 c., ил. ISBN 5-03-000403-3 Книга американских специалистов представляет собой пособие для самостоятельного освоения приемов работы с одной из самых распространенных зарубежных операционных систем и ее версиями. Материал имеет практическую направленность, хорошо систематизирован, иллюстрирован. Может слу¬ жить руководством для пользователя при работе за терминалом. Для специалистов в области вычислительной техники, программирования и САПР. 2405000000-263 T 199-88, ч. 1 ББК 32.973-01 041(01)-88 Редакция литературы по информатике p робототехнике ISBN 5-03-000403-3 (русск.) ISBN 0-89303-928-7 (англ.) © 1985 by Brady Communications Company, Inc. © перевод на русский язык, «Мир», 1988
Предисловие редактора перевода Наступило время, когда уже не надо представлять операционную систему Юникс советско¬ му читателю: она ему знакома по целому ряду работ, посвященных ей самой или системам, совместимым с ней. Наступила пора ее использовать самым широким программистским кругам. Такому контингенту пользователей требуется знать, что может делать система и как этим воспользоваться, а не каким образом система выполняет ту или иную функцию. Предлагаемая книга отвечает этому требованию и является одной из первых, полностью ориентированных на программистов-прикладников. Как сама система Юникс, так и изложение материала данной книги в полной мере отве¬ чают известной мысли средневекового английского философа Оккама о том, что понятия и утверждения не должны усложняться без необходимости. История создания системы Юникс — убедительное тому подтверждение. Основная цель, которую авторы преследова¬ ли при ее разработке, — ориентация на пользователя, активная поддержка в ее составе средств программирования и средств подготовки документов в максимально удобной для пользователя форме, а не в угоду системе (как это было, например, в системе Multics). Пер¬ вая система Юникс прежде всего устранила трудности, возникающие при общении с ней, и обеспечила дружеский интерфейс для рядового пользователя. Знаменательно, что реали¬ зация дружеского интерфейса средствами Юникс совпала во времени с реализацией та¬ ких же задач в области программирования и архитектуры ЭВМ. В начале 70-х годов поя¬ вился язык Паскаль — простой в усвоении и легко воспринимаемый рядовым пользовате¬ лем язык высокого уровня. К концу 70-х годов были созданы персональные компьютеры, архитектура и уровень операционных систем которых максимально приспособлены к ин¬ дивидуальному пользователю. Систему Юникс по аналогии можно было бы назвать «персо¬ нальной» операционной системой. Авторы частично отразили это свойство в названии своей первой системы, использовав в качестве корня английское слово unique (единствен¬ ный). Тем самым они хотели подчеркнуть, что это однопользовательская многопрограм¬ мная система. В настоящее время эта система обладает чрезвычайно обширным набором системных средств и возможностей. Прежде всего — это уже многопользовательская мультизадачная система. Поэтому название перестало отражать суть системы. Появились многочисленные потомки первой системы, каждый из которых имеет собственное название (например, си¬ стема Ксеникс). Несмотря на множественность и возросшие функциональные возможности потомков системы Юникс, их первоначальная суть остается прежней. Все версии системы Юникс максимально ориентированы на пользователя, что нашло отражение в содержании и форме изложения книги. Авторы исходили из того, что рядовой пользователь системы Юникс большую часть времени работает в ней с монитором (интерпретатором shell), а также с редактором тек¬ стов. Поэтому основу книги составляет описание интерактивного взаимодействия пользо¬ вателя с shell-интерпретатором и редактором. По сути это учебное пособие, посвященное ведению диалога пользователя с системой по тому или иному протоколу (в зависимости от решаемой задачи). Для читателя оптимальный способ усвоения представленного материа¬ ла — работа за терминалом машины, снабженной системой Юникс. Действия системы и пользователя описаны по шагам, со множеством альтернатив и пояснений. Пользователю не требуются никаки§ предварительные знания о системе, можно сразу приступить к рабо¬ те. Это одна из особенностей книги. Другая особенность книги связана с функциональной избыточностью системы. В насто¬ ящее время известны, например, несколько версий редакторов для обработки текстов, не¬ сколько версий shell-интерпретаторов, наконец, несколько версий собственно операцион¬ ных систем. Естественно, что пользователю в такой ситуации необходимы определенные ориентиры. Он должен знать, чтб дает ему та или иная версия, насколько она ему подхо¬ дит. Данная книга поможет пользователю проводить подобные оценки. В частности, в ней рассмотрены две версии редактора, две версии shell-интерпретатора и дана справочная
Предисловие авторов информация (на командном уровне) о нескольких, наиболее распространенных версиях си¬ стемы Юникс (Версия 7, Система III, реализации BSD 4.1 и 4.2, Ксеникс 2.3). На наш взгляд наибольшее удовлетворение от данной книги получат читатели, которые будут использовать персональные компьютеры с Юникс для работы со всевозможными до¬ кументами (подготовка текстов статей, отчетов, рукописей книг и т. д.). Кроме того, читате¬ ли получат полезные рекомендации и приобретут практический опыт работы с файловой системой. Эти вопросы нашли полное отражение в книге. Читателя, несомненно, должна заинтересовать новая версия интерпретатора C-shell. В отличие от других изданий в книге представлены вопросы, касающиеся сетевой обработки данных с помощью Юникс. Книга написана простым и доступным языком. Для удобства пользования в ней содер¬ жится обширный справочный материал, помещенный в приложениях. Книга не лишена не¬ достатков. Излишне лаконично представлена система Ксеникс, хотя название системы вы¬ несено на титул книги. Оригинал содержит большое число опечаток, особенно в примерах. Мы, к сожалению, не можем быть уверены, что все опечатки при переводе удалось устра¬ нить. Эти опасения касаются в основном тех опечаток, обнаружить которые можно только при работе на машине с системой Юникс, а такой возможности у нас не было. Поэтому мы будем благодарны всем читателям, которые по мере выявления опечаток в тексте сообщат об этом в редакцию. Перевод книги выполнен канд. техн. наук В.Ф. Оверченко (ч. I, III, V, приложения 1, 3, 4, 6—9) и B.B. Макаровым (ч. II, IV, приложения 2 и 5). В.Д. Никитин Предисловие авторов При написании данной книги мы сделали все возможное, чтобы приблизиться к подходу, который использовал Вильям Странк в своей работе "Элементы стиля* (Strank W., Jr., White E.B. The Elements of Style, The Macmillan Company, 1959). Он относился к читателю, как к человеку, "тонущему в болотем, и считал, что долг каждого, пишущего на английском языке, — быстро "осушить это болото или по крайней мере бросить ему спасательную ве¬ ревку*. Если вы почувствовали, что эта книга для вас такая же "спасательная веревка*, хватайтесь за нее и держитесь. Если вы уже чувствуете, что почва под ногами становится твердой, вставайте на ноги как можно быстрее. Если при изучении системы Юникс по этой книге вы получили удовольствие, радуйтесь этому. Нам бы хотелось поблагодарить Билла Потса и Дж. Эдела за консультации по основ¬ ным главам книги. Мы также благодарим M. Роджерса, П. Хьюбер и сотрудников фирмы Brady Art Department за помощь, которую они оказали нам при издании книги. На всех эта¬ пах подготовки книги полезной и ценной была совместная работа с сотрудниками фирмы Brady Communication Company.
Часть I. Основные сведения о системе Юникс Глава 1. Введение в систему Юникс Книга и ее структура Книга посвящена операционной системе Юникс. Если вы новичок в этой системе, подобная книга вам просто необходима. Работу в системе Юникс (если вы рань¬ ше пользовались одной из простых операционных систем для микроЭВМ) можно сравнить с применением современной зеркальной фотокамеры человеком, кото¬ рый до этого пользовался только простой фотокамерой. В этой системе имеются все необходимые вам средства (и даже больше). Хотя справочные руководства по системе Юникс входят во многие коммерче¬ ские описания, в них часто упускается важная информация. Вы читаете страни¬ цу за страницей описание средства, которое вы хотите использовать, только за¬ тем, чтобы в конце концов обнаружить, что основные сведения, которые вам не¬ обходимы, в этом описании отсутствуют. Программисты, составлявшие эти спра¬ вочники, полагали, что вы знаете, для чего предназначено данное средство и как его использовать. К сожалению, многие книги, посвященные системе Юникс, на¬ писаны на основе этих руководств. Данная книга отличается от руководств для программистов тем, что все при¬ веденные в ней концепции объясняются. Основополагающие идеи излагаются, а не предполагаются известными. Она обладает еще одним достоинством — раз¬ влекательностью: в меру смешна и не слишком скучна. Вам предлагаются реаль¬ ные, а не надуманные примеры. Они упрощены, чтобы проиллюстрировать рас¬ сматриваемые понятия; ознакомившись с ними, вы будете подготовлены к пони¬ манию более сложных ситуаций. Книга содержит пять более или менее независимых друг от друга частей. Каждая часть начинается с рассмотрения простых понятий, а затем формируют¬ ся более сложные концепции. Часть I адресована всем читателям; в ней даны основные сведения по ис¬ пользованию системы Юникс. В части II показано, как использовать исходный ре¬ дактор системы Юникс для создания и модифицирования памяток, писем, про¬ грамм и информации. Редактор ed вобрал в себя многое из основных свойств си¬ стемы Юникс. Использование двух более современных многофункциональных ре¬ дакторов vl и ex рассмотрено в ч. III. Сортировка, перемещение, форматирование и выполнение других операций по обработке текстовых файлов (обычно при под¬ готовке их к печати) описаны в ч. IV. Материал ч. V предназначен для более опыт¬ ных пользователей и знакомит их со средствами проектирования собственных процедур на языке shell и освоением системы Юникс. Если вы хотите узнать только, как пользоваться системой Юникс, и не имеете желания изменять поря¬ док работы основной системы, для вас этот материал не представляет интереса. В приложениях в сжатой форме излагается приведенный материал, а также со¬ держатся сведения справочного характера. Приложения могут быть полезны, ес¬ ли необходимо быстро получить справки о системе Юникс. Мы сделали все возможное, чтобы каждая тема вводилась до того, как она упоминается в связи с другими темами. Почти в каждом случае нам удалось это-
8 Часть I го достичь. Но, поскольку основные понятия в системе Юникс пересекаются, мы столкнулись при размещении материала со множеством дилемм типа "курица или яйцо“. В результате в некоторых примерах тема упоминается до того, как излага¬ ется полностью. Не бойтесь обращаться сразу к тем частям книги, которые представляют для вас наибольший интерес. Мы надеемся, что вы получите удовлетворение при изу¬ чении системы Юникс по нашей книге. Операционные системы Что такое операционная система? Наличие на вашей ЭВМ операционной системы можно сравнить с проживанием в современном доме: чтобы вкжочить воду и зажечь свет, вам достаточно открыть кран и повернуть выключатель. Без обширных обслуживающих систем, которые делают воду и электричество такими доступными, вы должны были бы проде¬ лать большую работу, чтобы получить эти основные ресурсы. Вы должны были бы уподобиться одному из первооткрывателей необитаемого острова, который вынужден сам копать колодцы, валить деревья, чтобы получить строительные материалы и топливо, и выращивать зерно, чтобы получить продукты питания. На заре эпохи ЭВМ затрачивались огромные усилия, чтобы выполнить работу, которую сегодня пользователи ЭВМ делают относительно легко. Это стало воз¬ можным благодаря разработке программ, называемых операционными система¬ ми, которые управляют выполнением огромного числа часто повторяющихся за¬ дач, возникающих при работе вычислительной системы. Как можно было бы использовать ЭВМ без операционной системы? Прежде всего вы должны были бы поддерживать гигантский "вахтенный журнал", кото¬ рый указывал, в какое место в памяти ЭВМ вы что-то записали. При отсутствии операционной системы вы должны были бы записать, где были ваша программа и данные, и куда вы намеревались поместить результаты работы вашей програм¬ мы. Вы должны были бы писать специальную программу всякий раз, когда необ¬ ходимо использовать периферийное оборудование ЭВМ: ее клавиатуру, видео¬ терминал или дисководы. Вам понадобилось бы, кроме того, иметь "вахтенный журнал" для каждого дисковода. Без операционной системы для управления все¬ ми этими работами вы должны были бы позаботиться о каждой мелочи в работе этих устройств. Еще вы должны были бы так определить схему работы с файла¬ ми, чтобы иметь возможность хранить программные и текстовые документы в определенном порядке. При отсутствии операционной системы вы должны со¬ здавать файловую систему самостоятельно. ЭВМ предоставляет основные ресурсы для решения задачи (вычисления, пе¬ чать, управление информацией, программирование и т. д.). Однако, чтобы сде¬ лать эти ресурсы легкодоступными для вас и ваших программ, требуется деталь¬ но разработанная программа, называемая операционной системой. При наличии операционной системы все, что вы должны сделать — это нажать несколько клавиш, чтобы файл был передан из памяти ЭВМ на один из ее накопителей на магнитных дисках. Итак, операционная система — это программа, которая позволяет относитель¬ но легко пользоваться ресурсами ЭВМ. Для этого операционная система должна обеспечить по меньшей мере некоторые средства для разработки и запуска про¬ грамм на ЭВМ, средства управления пространством памяти ЭВМ, средства досту¬ па к периферийным устройствам ЭВМ и некоторую файловую систему.
Основные сведения о системе Юникс 9 Кроме перечисленных выше средств, более сложные операционные системы могут предоставлять и другие возможности, делающие ЭВМ еще более удобной для использования: одновременный доступ к ЭВМ множества пользователей (раз¬ деление времени); средства связи между различными пользователями; одновре¬ менное выполнение множества различных программ (мультизадачность); средст¬ ва разработки и поддержки файлов; средства, облегчающие разработку про¬ граммного обеспечения; средства для ввода и обработки текста и некоторые средства защиты. Что представпяет собой операционная система Юникс? Теперь, когда вы имеете некоторые общие представления о том, что такое опера¬ ционная система, рассмотрим характеристики системы Юникс, по которым она отличается от других операционных систем. Ниже приведены наиболее сущест¬ венные из них: • Структурированная многоуровневая файловая система. • Средства, позволяющие многим пользователям одновременно работать на од¬ ной и той же ЭВМ, что делает систему Юникс многопользовательской. • Возможность для любого пользователя, работающего на ЭВМ, выполнять одно¬ временно более одной программы. • Механизмы, которые позволяют одной программе передавать ее результаты не¬ посредственно в другую программу (поэтому необязательно использование до¬ полнительного пространства памяти). • Возможность для любого пользователя переводить выдачу результатов работы программы с одного периферийного устройства на другое (например, с дисплей¬ ного терминала на дисковод). • Встроенный командный интерпретатор и язык shell. • Структурированный язык Си для системного программирования. • Расширенные средства для написания и разработки программ на Си и других языках программирования. • Расширенные средства для ввода, внесения изменений и обработки текста и подготовки его к печати. Система Юникс и ее производные Ниже рассмотрены этапы создания системы Юникс и ее отличия от системы Ксеникс и других ее производных. Разработка системы Юникс была начата двумя инженерами, приглашенными фирмой Bell Telephone Laboratories, которая была заинтересована в разработке удобной операционной системы. В вычислительном центре Murray Hill (шт. Нью- Джерси), где работали эти инженеры, был установлен базовый комплект ЭВМ "Дженерал Электрик 645“ с операционной системой Малтикс — одной из первых многопользовательских интерактивных систем. До системы Малтикс были широ¬ ко распространены операционные системы, ориентированные только на пакет¬ ную обработку (часто использующие перфокарты для ввода и устройства печати для вывода). Следуя принципам, традиционно существующим при пакетной обработке, в си¬ стеме Малтикс пользователи были изолированы друг от друга несколькими уров¬ нями защиты. Это предохраняло от непреднамеренной порчи дисковых файлов. Поскольку в фирме возникла необходимость совместного использования файлов бригадой программистов, Кен Томпсон приступил к разработке более удобной для этой цели операционной системы. Система Юникс была написана не вся cpa-
10 Часть I зу, а развивалась в течение нескольких лет по мере того, как Томпсон сталкивал¬ ся в своей работе со специфическими потребностями. Заметный скачок в развитии системы Юникс связан с разработкой Томпсоном программы "Космическое путешествие", в которой моделировалось движение ос¬ новных небесных тел Солнечной системы. Так как выполнение программы на ба¬ зовом комплекте "Дженерал Электрик" стоило 75долл., Томпсон решил перепи¬ сать ее для малоиспользуемой ЭВМ PDP-7 фирмы DEC, обладающей хорошим дис¬ плеем. Проект показал, какой трудной может быть разработка программы на ЭВМ, на которой отсутствует соответствующая операционная система. Первоначально программы для PDP-7 разрабатывались на "Дженерал Электрик 645“ и переноси¬ лись на перфоленте на ЭВМ фирмы DEC. Вскоре эта работа Томпсону надоела, и он занялся разработкой операционной системы, а затем и транслятора с ассем¬ блера для PDP-7, полностью написанных на языке ассемблера (машинный язык низкого уровня, который использует мнемонику, соответствующую примитивным машинным кодам). Эта задача заставила его подумать о файловой системе, кото¬ рая бы поддерживала коллективные программные разработки. Когда эти идеи были реализованы, Томпсон предложил дать название для этой системы — Юникс, созвучное с названием МалтиксЧ После того как число пользователей системы Юникс существенно возросло, Томпсон откликнулся на запросы первых пользователей и расширил возможности системы. Эта система после модернизации приобрела современный вид. Интерес патентного отделения фирмы Bell Labs. к системе возник после включения воз¬ можностей расширенной обработки текста. Вначале основная часть работы с ис¬ пользованием системы Юникс была связана с текстовой обработкой. Отсутствие высокоуровневого языка для постоянно развивающейся системы натолкнуло Томпсона на мысль разработать язык, названный Би, до того как вся система будет перенесена на одну из первых вычислительных систем PDP-11/45. Он написал несколько утилит на Би (расширенная версия языка BCPL, разрабо¬ танного в Массачусетском технологическом институте), но вскоре выяснилось, что такой неструктурированный интерпретирующий язык, как язык Би, без средств описания типов данных неудобен для написания системы. Наконец, чтобы придать системе Юникс более удобную форму, Деннис Ритчи написал новый язык, основанный на Би и названный Си. Язык Си, разработан¬ ный вместе с проектом системы Юникс, позволяет добавлять к системе мульти¬ обработку и переносить ее на другие машины. Один из самых распространенных в настоящее время языков программирования язык Си способствует широкому ис¬ пользованию системы Юникс во многих многопользовательских системах. В 1970-х годах система Юникс наиболее быстро внедрялась в университетах и исследовательских организациях. Она была доступна за относительно низкую ли¬ цензионную плату и ориентирована на многопользовательский режим работы, что и определило ее широкое распространение в научном мире. В Калифорний¬ ском университете в Беркли система Юникс была существенно улучшена: объеди¬ нены текстовые редакторы ex и vi, созданы интерпретатор C-shell, компилятор языка Паскаль, интерпретатор языка ЛИСП и система управления базой данных под названием INGRES. Основные версии этой усовершенствованной системы Юникс для вычислительных машин фирмы DEC получили название 2BSD для ce- 1)Система Малтикс (Multics) является многоабонентской системой, что отражено в ее названии (корневое слово multi — много). Система Юникс (Unix) была первоначально разра¬ ботана как одноабонентская система, что Томпсон отразил в названии системы (корневое слово unique — единственный). Он противопоставил ее тем самым системе Малтикс, в раз¬ работке которой принимал участие. — Прим. ред.
Основные сведения о системе Юникс 11 мейства PDP*11 и 4BSD для семейства VAX (BSD — сокращение словосочетания Berkeley Software Distribution). Поскольку система Юникс развивалась с ориентацией на область научных ис¬ следований, в ней отсутствовали некоторые возможности, необходимые в ком¬ мерческих применениях. Ряд разработчиков программного обеспечения предло¬ жили собственные коммерческие версии системы Юникс, полученные путем ее расширения, например системы Идрис, Кромикс, Когерент, Оникс и Ксеникс. По¬ следняя система — одна из наиболее широко известных, разработана фирмой Microsoft в конце 1970-х — начале 1980-х годов для того, чтобы иметь полную реа¬ лизацию системы Юникс с возможностями для коммерческих применений. В 1984 г. фирма IBM выпустила операционную систему PC/IX для своего персональ¬ ного компьютера PC-XT, затем систему VM/IX, ориентированную на соответствую¬ щую аппаратную среду. (Более подробно варианты системы Юникс рассматрива¬ ются в приложении 9.) Функционирование системы Юникс Когда вы запускаете прикладную программу под управлением операционной си¬ стемы Юникс, то совместно работают три программы. Программа, которая взаи¬ модействует непосредственно с вычислительной машиной, называется ядром. Как пользователь системы Юникс, вы редко будете ощущать присутствие ядра, а будете работать с интерпретатором shell, который распознает и выполняет ко- манды, вводимые вами с клавиатуры, и готовит другие программы к запуску. Строго говоря, интерпретатор shell является лишь одной из программ и не дол¬ жен отличаться от них. Однако его принято изображать как "средний слой“ меж¬ ду ядром и прикладными программами (рис. 1.1)4 Дело в том, что интерпретатор shell играет исключительно важную роль при взаимодействии ЭВМ с пользовате¬ лями. Вместе с тем он при необходимости почти полностью может быть скрыт от них. 1Рис. 1.1. Структура системы Юникс. 1) Этим, вероятно, объясняется название интерпретатора shell (оболочка). — Прим. ред.
12 Часть Ядро Ядро выделяет такие аппаратные ресурсы ЭВМ, как накопители на магнитных дисках, лентопротяжные механизмы и оперативная память для каждого про¬ граммного запроса. Оно непосредственно взаимодействует с аппаратурой ЭВМ и поэтому может различаться для разных моделей вычислительных машин. По¬ скольку ядро составляет небольшую часть системы Юникс, создавать ее новую версию для другой ЭВМ относительно просто. (Программа, которая может быть выполнена на разных моделях ЭВМ, называется мобильной. Понятие мобильно¬ сти рассматривается в этой главе ниже.) Интерпретатор shell Когда вы начинаете сеанс работы с системой Юникс, именно интерпретатор shell приветствует вас, принимает и выполняет ваши инструкции. Он распознает, вы¬ полняет команды системы Юникс и работает как программный уровень над яд¬ ром. Интерпретатор shell представляется на экране дисплея с помощью специ¬ ального знака-подсказки1), за которым следует курсор, например: $ _ Если вслед за этим знаком-подсказкой вы вводите команду, интерпретатор shell начинает связанный с данной командой процесс в системе Юникс. Этим процес¬ сом может быть простая программа вывода текущей даты и времени или очень сложная система редактирования текстов (сам интерпретатор shell тоже являет¬ ся процессом). Если при обращении к процессу что-либо выполняется неверно, интерпретатор shell выдаст на экран вашего дисплея сообщение об ошибке. Ког¬ да процесс завершается, интерпретатор shell вновь выводит на экран знак- подсказку, указывая на готовность принимать следующую вашу команду. На самом деле для системы Юникс существует не один интерпретатор shell. Во-первых, имеется первоначальная версия интерпретатора, разработанного для системы Юникс в фирме Bell Telephone Laboratories Стефаном P. Бурном (извест¬ ный как бурновский интерпретатор shell2^. Во-вторых, существует версия интер¬ претатора shell, которая создана в Калифорнийском университете в конце 1970-х годов и известна под названием C-shell. Наконец, существует много других вари¬ антов интерпретатора shell, поскольку он может быть модифицирован любым пользователем, имеющим исходные тексты программ интерпретатора. По мере дальнейшего изучения книги вы освоите работу интерпретатора shell. Прикладные программы Из-за возрастающей популярности системы Юникс перечень прикладных про¬ грамм, способных работать под ее управлением, постоянно увеличивается. Име¬ ются программы обработки текстов, верстки газет, управления базами данных, трансляторы для языков Бейсик, Фортран, Кобол, Си, других языков программи¬ рования и ассемблеров. Многие наиболее популярные программы, разработан¬ ные для микроЭВМ, сейчас переписываются на языке Си, чтобы их можно было использовать в системе Юникс. Кроме того, на микроЭВМ, работающие под 1 21)В литературе этот знак еще называют "приглашение*. Дальше в тексте используются оба термина как синонимы. — Прим. ред. 2) В дальнейшем для краткости будем называть его как В-shell (по аналогии с C-shell). — Прим. ред.
Основные сведения о системе Юникс 13 управлением системы Юникс, переносятся достаточно сложные задачи, решавши¬ еся ранее на ЭВМ общего назначения или мини-ЭВМ. В недалеком будущем станет возможным выполнение в системе Юникс боль¬ шинства программ, которые широко применялись под управлением операционных систем CP/M, MS-DOS и PC-DOS. Еще недавно микроЭВМ не обладали достаточ¬ ными вычислительными ресурсами, необходимыми для работы системы Юникс. Они не могли сравниться с мини-ЭВМ по объему оперативной памяти, быстро¬ действию и емкости накопителей на магнитных дисках. Но в настоящее время благодаря техническому прогрессу микроЭВМ имеют достаточно мощные вычис¬ лительные ресурсы, чтобы удовлетворить жестким требованиям функционирова¬ ния системы Юникс. Си и мобильность Система Юникс первоначально создавалась для мини-ЭВМ PDP-7. Позже она бы¬ ла модифицирована для работы на других мини-ЭВМ, а затем и на микроЭВМ. Это повысило популярность системы Юникс и улучшило мобильность языка Си, на котором написано большинство программ и утилит этой системы. Для получе¬ ния максимальной производительности многие из первых программ для микро¬ ЭВМ были написаны на низкоуровневом языке ассемблера, близком к машинному языку. Позднее прикладные программы для обеспечения мобильности уже были написаны на языках высокого уровня типа Бейсик или Паскаль. Однако Си явля¬ ется языком среднего уровня, объединяющим высокую эффективность языка низкого уровня с мобильностью и удобством использования языка высокого уровня. Юникс — первая большая операционная система, которая написана не на языке ассемблера. Язык Си, сначала тесно связанный с системой Юникс и ее версиями, получил право на самостоятельное существование. В настоящее время владельцами мик¬ роЭВМ продается более десяти вариантов языка Си. Благодаря мобильности прикладных программ, написанных на языке Си, задача их переноса с одной вер¬ сии системы Юникс на другую в значительной степени упрощается. Версии системы Юникс За последние 15 лет система Юникс подвергалась многочисленным пересмотрам. Сначала была создана Версия 1, затем — Версия 2 и так далее до Версии 7. Впо¬ следствии было решено переименовать Версию 8 в System III. Первые реализации операционных систем Ксеникс и PC/IX основывались на Версии 7 системы Юникс с некоторыми свойствами, характерными для версии System III. По сооб¬ щениям самая последняя версия системы Юникс — System V. Она поставляется с новыми вычислительными машинами фирмы American Telephone and Telegraph. Система Юникс как единое целое Если проанализировать множество программ, которое составляет систему Юникс как единое целое, большинство из них, вероятно, можно отнести к следующим классам: • общего назначения (программы, которые обеспечивают доступ к системе, позво,- ляют работать с файлами, управлять выполнением программы, получать инфор¬ мацию, сохранять записи, производить вычисления и связываться с другими пользователями); • редактирования текстов (программы, которые позволяют вводить, модифициро¬ вать и обрабатывать текст);
14 Часть I • форматирования документов (программы, которые позволяют форматировать текст для печати и готовить рукописи к набору); • разработки программ (программы, которые позволяют проверять и компилиро¬ вать программы, написанные на языках высокого и низкого уровней, и разраба¬ тывать собственные компиляторы языков и языковые процессоры); • управления и поддержки системы (программы, которые позволяют увеличивать и уменьшать число пользователей, поддерживать, восстанавливать и сохранять файловую систему); • разнообразных функций (программы, которые позволяют строить диаграммы, играть в игры, проводить тесты и т. д.). Вопросы, рассматриваемые в книге Основное внимание в книге уделяется программам общего назначения, редакти¬ рования и форматирования текстов и программированию на языке интерпретато¬ ра shell. Приводятся основные сведения по подготовке терминала к работе в си¬ стеме. В книге не рассматриваются вопросы программирования и разработки программного обеспечения на языке Си, а также вопросы машинной графики. Для исчерпывающего ознакомления с командами системы Юникс вы можете обратиться, например, к двухтомному «Руководству программиста системы Юникс» фирмы Bell Telephone Laboratories. Первый том содержит подробную ин¬ формацию о командах и файлах и небольшое число примеров. Каждая команда или файл описывается в одной из восьми частей тома в стандартном формате: имя, общий обзор; описание; связанные файлы; дополнения; ошибки. Второй том содержит материал разработчиков системы Юникс по шести основным направле¬ ниям: общие действия; начальный запуск; подготовка документов; программиро¬ вание; средства и языки поддержки; реализация, эксплуатация и пр. О какой версии системы Юникс идет речь в данной книге? Большинство те¬ стовых программ проверялось на системе Юникс Версия 7, но некоторые из них дополнительно проверялись на версиях BSD 4.2 и System III. Авторы пытались минимизировать проявление "фактора версии“ при изложении материала. Тем не менее даже с учетом относительно небольших различий между используемыми в настоящее время версиями системы Юникс могут обнаружиться команды, кото¬ рые не выполняются при работе с конкретной системой. В этих случаях мы ре¬ комендуем ознакомиться с приложением 9, где рассмотрены возможные разли¬ чия. Глава 2. Система Юникс. Основные понятия В этой главе рассмотрены основные понятия, касающиеся системы Юникс, та¬ кие, как процедуры начальной установки, вход и выход, редактирование команд¬ ной строки, процессы (команды) запуска, использование калькулятора и вспомо¬ гательные средства для обучения.
Основные сведения о системе Юникс 15 Процедуры начальной установки Если вы работали с однопользовательской операционной системой типа CP/M, MS-DOS или PC-DOS, то привыкли к тому, что, перед тем как начать работать, вы просто включаете ЭВМ и, возможно, вводите дату и время. Однако в многополь¬ зовательской системе, подобной Юникс, необходимо принимать во внимание то, что пользователи могут получать доступ к ЭВМ в любой момент времени и с раз¬ личных терминалов. Поэтому, перед тем как вы начнете работать с системой Юникс, вам следует убедиться, что она может признать вас как пользователя си¬ стемы и может установить связь с терминалом, за которым вы собираетесь рабо¬ тать. Представление системе Юникс Вы сможете работать в системе Юникс только после того, как ваше имя будет включено в список ее пользователей. В учреждении, где вы работаете, возможно, есть администратор системы, призванный заботиться о новых пользователях. Он должен назначить вам идентификатор, пароль и терминал. Идентификатором (известным так же, как "числовое имя“, "входное имя“ или "имя пользователя") может быть часть вашего полного имени или ваши инициалы. Пароль нужен для того, чтобы никто не мог использовать систему под вашим именем (за исключени¬ ем администратора системы). Обычно терминал имеет клавиатуру для ввода ин¬ формации и телевизионный экран для вывода сообщений от системы. Идентификация вашего терминала Если система Юникс приобретена вместе с машиной, то вам, возможно, ничего не надо делать для идентификации своего терминала. В противном случае вы дол¬ жны удостовериться, что характеристики вашего терминала совместимы с харак¬ теристиками ЭВМ (иначе терминал и машина не смогут работать друг с другом). Это аналогично ситуации, когда вы с собеседником должны сначала убедиться, что говорите на одном языке, прежде чем вступать в разговор. Итак, вы должны удостовериться, что терминал и ЭВМ пересылают данные друг другу с одинаковой скоростью, используют один и тот же протокол при пе¬ редаче и приеме, один и тот же способ контроля ошибок и одинаково интерпре¬ тируют специальные символы. О правильности установления этих характеристик можно судить просто — войти в систему и посмотреть, что при этом происходит. Если вы обнаружите на экране двойные символы или вообще их отсутствие, слу¬ чайные символы (известные так же, как ”мусор“) или отсутствие реакции на на¬ жатие клавиши RETURN1*, то характеристики вашего терминала установлены не¬ верно, поэтому обратитесь за помощью к администратору системы. Если подоб¬ ные ситуации не возникают, характеристики установлены правильно. Позже, ког¬ да вы лучше ознакомитесь с системой Юникс, вы научитесь использовать коман¬ ду stty (set teletype — установить характеристики терминала) для установки ха¬ рактеристик терминала. 1) На клавиатуре отечественных дисплеев эта клавиша маркируется как < BK> (возврат каретки). — Прим, перев.
16 Часть I Вход и выход I Вход в систему Если у вас есть идентификатор, пароль и работающий терминал, вы готовы вой¬ ти в систему. Вход в систему дает вам доступ к средствам операционной систе¬ мы Юникс. Рассмотрим основные процедуры входа в систему, которые могут ме¬ няться от одной системы к другой. 1. Установите связь между ЭВМ и вашим терминалом. а) Эта процедура может означать набор номера телефона, нажатие выключате¬ ля на вашем терминале или ввод какой-то информации с клавиатуры. Узнайте у администратора вашей системы, что требуется сделать на самом деле. б) После выполнения вами нужной операции система Юникс ответит коротким простым сообщением в верхнем левом углу экрана, например, таким1): login: 2. Представьте себя системе (символы, которые вы вводите, показаны в после¬ дующих примерах заключенными в рамку). а) Вслед за подсказкой login наберите на клавиатуре свой системный идентифи¬ катор (или имя пользователя) и нажмите клавишу RETURN. б) Вероятно, система Юникс откликнется, запрашивая ваш пароль: login: robin Password: 3. Введите свой секретный пароль. а) Вслед за подсказкой Password (пароль) введите свой пароль, который не ото¬ бражается на экране, и нажмите клавишу RETURN. б) В целях сохранения секретности пароля символы, которые вы вводите с кла¬ виатуры, не будут появляться на экране. После короткой паузы вы увидите на экране следующее: login: robin Password: Last login: Sun Feb 5 20:17:26 on tty03 ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ Welcome to U N I X System III January 1985 * ★ ★ ★ ★ ★ * ★ ★ ★ ★ * * ★ ★ * ★ ★ ★ ★ ★ ★ * ★ ★ ★ ★ ★ $ _ Поздравляем! Вы успешно вошли в систему. Знак доллара $, процента % или какой-нибудь другой знак перед курсором является знаком-подсказкой интерпре¬ 1) Курсор здесь и далее обозначается в виде знака подчеркивания. — Прим, перев.
Основные сведения о системе Юникс 17 татора shell системы Юникс. Ниже мы поясним, почему этот знак имеет такое на¬ звание, и покажем, как вы можете заменить его другим знаком. А пока считайте знак-подсказку интерпретатора shell системы Юникс аналогичным подсказке (A>), которую вы видите на экране при работе с системами CP/M, MS-DOS или PC-DOS. Знак-подсказка говорит о готовности системы Юникс к тому, чтобы вы вводили команды и начинали работать. Администратор системы может войти в систему как суперпользователь1>, что¬ бы выполнять специальные задачи, которые требуют особых привилегий. Такой пользователь будет иметь особый знак-подсказку в виде знака #. Ввод команд Для проверки того, что вы действительно получили доступ к системе Юникс, вве¬ дите несколько простых команд. 1. Начните с команды, которая сообщает день недели, дату и время дня. а) Наберите на клавиатуре date и нажмите на клавишу RETURN. б) Система Юникс ответит следующим образом: $ |date Mon Jan 17 09:02:37 EST 1985 $ 2. Теперь посмотрите, кто сейчас работает с системой. а) Наберите на клавиатуре who и нажмите на клавишу RETURN. б) Система Юникс выдаст на экран следующее: $ who janis tty03 Jan 17 08:12 alex tty05 Jan 17 08:39 jkl tty07 Jan 16 21:16 robin tty12 Jan 17. 09:02 guapo $ tty16 Jan 17 08:57 Каждая строка этого экрана содержит идентификатор пользователя (например, janis), номер терминала (например, tty03), дату и время, когда пользователь вошел в систему (например, Jan 17 08:12). В конце 1960-х годов, когда была разработана система Юникс, в качестве терминала в основном использовались печатающие устройства типа телетайпа. Поэтому сокращение tty (от felefype) в системе Юникс означает просто ”терминал“. 3. Наконец, введите команду, которая неизвестна системе Юникс, и посмотрите, что получится. а) Наберите на клавиатуре why и нажмите на клавишу RETURN. б) Система Юникс ответит сообщением такого вида: $fwhy why: not found $ 1)В отечественной литературе вместо понятия ”супер-пользователь“ чаще встречается название "привилегированный пользователь". — Прим, перев.
18 Часть I Выход из системы Когда необходимо завершить работу с системой Юникс, вы не можете просто вь ключить свой терминал. Вы обязаны выйти из системы. Если вы не сделаете этс го, она будет считать, что вы работаете с ней, хотя ваш терминал уже отключен В большинстве ОС для выхода из системы достаточно набрать CTRL-D (однс временно нажмите одним пальцем клавишу CTRL1), а другим клавишу D). Посколь ку для системы Юникс CTRL-D часто означает конец файла (end-of-file) или коне1 передачи (end-of-transmission), возможны моменты, когда для выхода из системь вы будете вынуждены несколько раз нажать CTRL-D. Для некоторых версий си стемы может потребоваться нажатие и других клавиш. Так, например, если вь используете интерпретатор C-shell и переменная с именем ignoreof установлена вам придется набрать команду logout и нажать клавишу RETURN. Другие верст системы, как, например, версии System III, требуют команды exec login: $ [При нажатии CTRL-D на экране ничего не появляется] login: _ Что происходит, когда вы вышли из системы? На экране появляется подсказ ка login. Означает ли это, что система Юникс не хочет общаться с пользователем, который вышел из нее? Возможно, но вы должны запомнить одну простую вещь: сообщение login говорит вам, что вы уже вышли из системы. В этот момент вы можете или снова войти в систему, или остаться вне ее. Поскольку нам нужно еще кое-что сделать, войдем вновь в систему и перейдем к следующему разделу. Изменение пароля Так как пароль обеспечивает вам некоторую степень секретности в системе Юникс, время от времени у вас может появляться желание изменить его. Измене¬ ние пароля создаст дополнительные трудности другим пользователям, если они попытаются войти в систему под вашим системным именем. В качестве упражне¬ ния измените свой пароль. Для этого наберите на клавиатуре команду passwd и нажмите клавишу RETURN: $[passwd Changing password for robin Old password: Введите с клавиатуры свой текущий пароль (вы увидите его на экране). Затем система Юникс попросит вас ввести новый пароль (до восьми символов). После этого для подтверждения наберите на клавиатуре новый пароль еще раз: $ |passwd Changing password for robin Old password: New password: Retype new password: $ _ Если вы действительно хотите, чтобы ваш пароль трудно было угадать, со¬ ставляйте его из букв верхнего и нижнего регистров, цифр и других символов. 1) На клавиатуре отечественных дисплеев эта клавиша маркируется как <СУ) или <УС). — Прим, перев.
Основные сведения о системе Юникс 19 Чем более необычным и длинным вы его сделаете, тем сложнее другому пользо¬ вателю угадать его. Избегайте паролей, совпадающих с вашим прозвищем, номер¬ ным знаком вашего автомобиля, номером страхового полиса или инициалами. Ввод командной строки Выше мы уже использовали две простые команды: date (дата) и who (кто). Чтобы в системе Юникс выполнить любое действие, необходимо задать команду, т. e. набрать на клавиатуре командную строку и нажать клавишу RETURN. В случае команды date командную строку составляют четыре буквы date, а в случае коман¬ ды who — только три буквы. Эти две команды требуют указания только названия команды, но существует множество других команд, при работе с которыми необходимо указывать допол¬ нительную информацию об опциях команды и обрабатываемых ею файлах. Эта информация в командной строке указывается за именем команды. Например, команда who может использоваться для вывода списка пользователей, работаю¬ щих в текущий момент. Однако существует и другая форма команды: $ who am i robin tty05 Jan 17 09:02 $ _ Если вы забыли свой системный идентификатор или вошли в систему по не¬ скольким идентификаторам, с помощью этой формы команды можно опреде¬ лить, под каким идентификатором вы работаете в текущий момент. Дополнитель¬ ные слова в команде am i образуют аргумент команды, который изменяет способ ее действия. Пока вы не нажмете клавишу RETURN, можно вносить изменения в командную строку. Ниже рассматриваются способы внесения таких изменений. Удаление символа CTRL-H Чтобы удалить один символ в командной строке, используется CTRL-H (нажмите одним пальцем клавишу CTRL, а другим одновременно нажмите клавишу H). Неко¬ торые клавиатуры могут иметь клавишу, называемую BACKSPACE, которая вы¬ полняет эту же функцию. Ниже рассмотрен пример такого исправления: $ whoo [Лишний символ о в конце команды who] $ who_- [Нажмите #, CTRL-H или BACKSPACE] После этого вы можете нажимать клавишу RETURN, чтобы выполнить ко¬ манду. Удаление всей командной строки Чтобы удалить всю строку и повторить ее ввод, используется знак @. Но в вашей системе для выполнения этой функции может быть использована и другая кла¬ виша. Предполагая, что это клавиша @, ниже представлено другое типичное ис¬ правление: $ fate_ [Вы набрали fate вместо date] $ fate [Нажмите клавишу @, чтобы удалить строку. В большинстве случаев она на самом деле не удаляется, а просто курсор переходит на следующую строку] $ fate date_ [Набирайте строку вновь]
20 Часть I Теперь для выполнения командной строки нажмите клавишу RETURN. В этом простом примере использование для удаления строки клавиши @ вместо того, чтобы удалять отдельно четыре символа (с помощью CTRL-H), избавило вас от не¬ обходимости еще три раза нажимать клавишу. Если командная строка длинная, выигрыш может быть намного больше. Восстановление знака-подсказки DEL Иногда после запуска процесс зависает, и знак-подсказка интерпретатора shell не появляется на экране. В этом случае для завершения процесса и восстановле¬ ния знака-подсказки нажмите клавишу DEL1*: $ |who [Нажмите клавишу DEL, при этом на экране ничего не появляется] $ Управление процессом Правильно набрав командную строку, вы можете выполнить несколько действий по управлению процессом: можете запустить процесс как фоновый, запросить список процессов, выполняющихся в текущий момент, прекратить процесс или приостановить вывод информации от процесса на экран. Запуск фонового процесса & Когда вы выполняете команду, интерпретатор shell обычно ожидает завершения процесса, связанного с этой командой, а затем выводит на экран следующий знак-подсказку. Такой процесс называется привилегированным (foreground). Лю¬ бой процесс, который вы запускаете, по умолчанию будет выполняться как при¬ вилегированный, т. e. процесс все время будет связан с вашим терминалом, де¬ лая невозможным для вас выполнение еще каких-либо действий с системой Юникс до тех пор, пока он не завершится. Если вы указываете системе Юникс, что процесс выполняется как фоновый (background), то после его запуска можете освободить свой терминал и далее пе¬ рейти к другой задаче. Чтобы запустить фоновый процесс, введите в конце ко¬ мандной строки перед нажатием на клавишу RETURN знак &. Фоновая обработка наиболее пригодна для процессов, которые долго выполняются. Например, пе¬ ред началом форматирования и печати большого файла под названием mammoth (мамонт) введите команду: $|pr mammoth | lpr & 2167 $ _ Система Юникс выводит на экран идентификационный номер процесса PID (process identification number) и затем — знак-подсказку. Когда выполняется фо¬ новый процесс и на экране есть знак-подсказка, вы можете вводить следующую командную строку (которая может быть командой запуска другого фонового про¬ цесса), не дожидаясь завершения печати файла mammoth. Несмотря на то что 1) На клавиатуре отечественных дисплеев эта клавиша маркируется как <ЗБ) (забой). — Прим, перев.
Основные сведения о системе Юникс 21 фоновая обработка удобна для некоторых задач, она обладает следующими не¬ достатками: • фоновый процесс не допускает ввод с клавиатуры; • любой вывод от фонового процесса на ваш экран разрушает все, что вы в этот момент вводите с клавиатуры; • вы обладаете меньшей возможностью управлять развитием фонового процесса; • если вы попытаетесь инициализировать одновременно достаточно много фоно¬ вых процессов, рискуете перегрузить систему. Получение списка выполняющихся процессов ps Если вы запускаете процессы в фоновом режиме, то чтобы узнать, какие из них все еще выполняются в какой-то момент, а какие уже завершились, в системе Юникс существует команда ps (process status — состояние процесса). Эта коман¬ да выводит список всех выполняющихся в текущий момент процессов, указывая для каждого из них идентификационный номер процесса (PID), терминал, с кото¬ рого он был запущен fTTY), время, которое он уже выполняется, и еще некоторую информацию о командной строке, использованной для инициализации процесса (CMD). Например: *fps] PI0 TTY TIME CMD l905 12 1:16 -sh 2132 12 2:18 ed 2167 12 4:02 -sh 2218 12 0:58 ps $ _ Уничтожение процесса DEL kill В некоторых случаях может возникнуть необходимость прекратить процесс До того, как он сам завершится. Для уничтожения привилегированного процесса на¬ жмите клавишу DEL, а фонового процесса используйте команду kill (прекратить). Наберите на клавиатуре^/// и PID процесса, который вы прекращаете. Например, для уничтожения выше упоминавшегося процесса n^iammoth (идентификацион¬ ный номер процесса 2167) вы могли использовать команду: $[kill 2167 2167: terminated $ [Ответ системы Юникс] Если вы знаете идентификационные номера процессов, вы можете уничто¬ жить некоторые из них с помощью такой командной строки: $ kill 1905 2132 2167 1905 2132 2167: terminated $ В некоторых системах разрешается использовать команду kill, чтобы прекра¬ тить все запущенные с вашего терминала процессы. Однако такая команда мо¬ жет удалить из системы и вас, поэтому (по крайней мере пока) лучше не приме¬ нять ее.
22 Часть I Приостановка вывода на экран CTRL-S Иногда вы будете сталкиваться с тем, что информация ”бежит“ по экрану быст¬ рее, чем вы можете ее прочитать. Чтобы временно приостановить перемещение информации на экране, нажмите CTRL-S. Затем, когда вы считаете экран, може¬ те нажать CTRL-Q, чтобы возобновить продвижение информации на экране. Использование калькуляторов Система Юникс имеет калькулятор (и препроцессор для этого калькулятора), ко¬ торым вы можете пользоваться прямо на своем терминале. Использование настольного калькулятора dc Для вызова простого интерактивного настольного калькулятора используйте ко¬ манду dc (desk calculator — настольный калькулятор). Ниже представлено типич¬ ное применение команды dc (в правой части каждой строки дан комментарий): $fd( 3 4 + P 7 З+Р 10 4*p 40 2/р 20 5-Р 15 q Вызов настольного калькулятора Ввод 3 Ввод 4 Выполнение сложения Вывод результата Сложение с 3 и вывод результата Умножение на 4 и вывод результата Деление на 2 и вывод результата Вычитание 5 и вывод результата Выход из калькулятора Дополнительные возможности калькулятора включают извлечение корней, масштабирование, функции, индексацию и логическое управление. Для детально¬ го ознакомления с калькулятором смотрите Справочное руководство по системе Юникс. Использование высокоточного калькулятора bc В системе Юникс имеется также другой калькулятор, названный bc, который сво¬ ими операторами подобен языку Си и является препроцессором для калькулято¬ ра dc. Этот калькулятор обеспечивает вычисления с любой точностью. Для его вызова используйте команду bc. Калькулятор bc позволяет определять значения простых переменных, функций и массивов и использовать библиотеку из шести математических функций: вычисление синуса, косинуса, арктангенса, экспонен¬ циальной функции, логарифма и функции Бесселя. В общем калькулятор bc позволяет создавать для калькулятора dc математи¬ ческие подпрограммы в соответствии с синтаксическими правилами, используе¬ мыми в языке программирования Си. Программа может выполнять ввод из фай¬ ла или со стандартного устройства ввода (клавиатуры дисплея). Для детального ознакомления с калькулятором смотрите Справочное руководство по системе Юникс.
Основные сведения о системе Юникс 23 Вспомогательные средства для обучения Многие системы Юникс имеют два вспомогательных средства для изучения са¬ мой системы: автоматизированный курс обучения и непосредственную копию Ру¬ ководства программиста системы Юникс. Автоматизированное обучение learn Если на вашей системе есть курс автоматизированного обучения, то чтобы запу¬ стить его, следует выполнить команду learn (учиться). Этот курс проведет вас че¬ рез серию уроков, за каждым из которых следует ряд вопросов на различные те¬ мы. Такое обучение может быть полезным, но обладает рядом недостатков: • вы никогда заранее не можете сказать, сколько времени потребует конкретный урок (один урок может занять 15 минут, а другой — больше часа); • если вы отвечаете на вопрос неправильно, то сообщение просто извещает вас о неверном ответе, но не объясняет почему; • если вы прервались в середине курса, то трудно продолжить обучение с того места, на котором вы остановились. Непосредственное руководство man Если на вашей системе есть Руководство пользователя системы Юникс, то чтобы обратиться к какой-то его части, следует выполнить команду man (manual — ру¬ ководство) с именем интересующей вас команды системы Юникс. Например, что¬ бы просмотреть раздел, относящийся к команде who, вы можете выполнить ко¬ манду man who При этом вам будет предоставлено подробное описание команды и всех ее модификаций. Краткое изложение главы 2 В этой главе вы ознакомились с некоторыми основополагающими концепциями, касающимися системы Юникс: процедурами начальной установки, входом и вы¬ ходом, запуском процессов. Процедуры начальной установки Перед тем, как начать работу с системой Юникс, вы должны иметь идентифика¬ ционное имя, пароль и терминал, который выделяется вам администратором си¬ стемы. Вход и выход Вход в систЕМУ. Чтобы войти в систему Юникс, установите связь с ЭВМ, набе¬ рите свой идентификатор и пароль.
24 Часть I Выход из систЕМЫ. Чтобы выйти из системы, введите CTRL-D (возможно, не один раз) или наберите logout или exec login (в System III) и нажмите клавишу RETURN. ИЗМЕНЕНИЕ ПАРОЛЯ. Для изменения пароля используйте команду passwd. Редактирование командной строки ОБЩИЕ положЕния. Чтобы запустить процесс в системе Юникс, наберите ко¬ мандную строку и нажмите клавишу RETURN. Командная строка может содер¬ жать либо только саму команду, либо команду и аргументы. УДАЛЕНИЕ символА. Для удаления отдельного символа в командной строке ис¬ пользуйте CTRL-H (или BACKSPACE). ВосстАновлЕНИЕ знАКА-подскАЗКИ. Для восстановления знака-подсказки интер¬ претатора shell после запуска процесса нажмите клавишу DEL. Управление процессом ЗАПУСК Фонового процЕССА. Для запуска фонового процесса в конце командной строки следует набрать знак амперсанда &. ПолучЕНИЕ спискА выполняющихся процЕССов. Чтобы определить, какие процес¬ сы выполняются в системе Юникс в конкретный момент, используйте команду ps. Система выдаст список процессов, в котором для каждого процесса указыва¬ ются идентификационный номер, терминал, с которого он был инициализирован, интервал времени, в течение которого он уже выполняется, и сама командная строка. УничтожЕНИЕ процЕССА. Для уничтожения привилегированного процесса ис¬ пользуйте клавишу DEL, а для уничтожения фонового процесса — команду kill с идентификатором процесса. ПРИОСТАНОВКА выводА НА экРАН. Чтобы остановить быстрое перемещение ин¬ формации по экрану, нажмите CTRL-S; для возобновления выдачи на экран на¬ жмите CTRL-Q. Использование калькуляторов ИспользовАНИЕ НАСТОЛьного КАЛЬкулятоРА. Чтобы вызвать настольный кальку¬ лятор, введите команду dc и строки вычисляемого выражения, в котором опера¬ ции следуют за операндами. Для выхода из калькулятора используйте команду q. ИспользовАниЕ высокоточного КАЛькулятоРА. Чтобы использовать этот кальку¬ лятор, введите команду bc и операторы программы. Вспомогательные средства для обучения АвтомАтизировАнноЕ ОБУЧЕНИЕ. Чтобы пройти курс обучения в системе Юникс за своим терминалом, выполните команду learn. НЕПОСРЕДСТВЕННОЕ руководство. Для вывода на экран вашего терминала части Руководства пользователя системы Юникс выполните команду man. Наберите man с именем команды, описание которой вы хотите посмотреть, и нажмите кла¬ вишу RETURN.
Основные сведения о системе Юникс 25 Глава 3. Файловая система Юникс Что такое файловая система? Если вы пользовались какой-либо библиотекой, то знакомы с концепцией систе¬ мы картотек. Библиотека предлагает вам книги, хранящиеся на полках, и спра¬ вочник, с помощью которого вы можете определить местонахождение конкрет¬ ной книги. Справочник библиотеки называется карточным каталогом. Располо¬ женный обычно в легкодоступном месте карточный каталог не только указывает вам местонахождение каждой книги, но и дает краткую информацию о ней. Каждая операционная система имеет файловую систему, которая функциони¬ рует аналогично системе картотек библиотеки. В операционной системе едини¬ цами хранения являются файлы, а не книги. В файлах ЭВМ могут храниться тек¬ сты, данные, графическая информация, программы, а также каталоги, содержа¬ щие списки других файлов. Каждый элемент типового каталога содержит имя файла, его местоположение, размер, тип и, возможно, информацию о доступно¬ сти файла для пользователей. (В системе Юникс только имя файла находится в самом каталоге, а остальная информация хранится в другом месте.) Если вы пользовались одной из обычных операционных систем для микро- ЭВМ, то, вероятно, работали с неструктурированной файловой системой. В такой файловой системе имеется один большой каталог для всех файлов. Из-за от¬ сутствия какой-либо структуры связи файлов каталог является просто списком файлов. Структурированная файловая система Файловая система Юникс имеет не один, а много каталогов. Более того, у нее ясно определенная структура, которая позволяет помещать некоторые каталоги внутри других каталогов и различные виды файлов в различные каталоги. Как пользователь системы Юникс, вы обладаете своим собственным каталогом, имя которого совпадает с вашим идентификатором, введенным вами при входе в си¬ стему. Ваш каталог, как и другие каталоги, может содержать и файлы, и катало¬ ги, тем самым позволяя вам хранить связанные друг с другом файлы. Перед тем как мы начнем обсуждать особенности каталогов и файлов, обратим внимание на следующее: система Юникс рассматривает периферийные устройства, подоб¬ ные терминалам, печатающим устройствам и накопителям на магнитных дисках, как файлы. Процедура доступа к такому устройству идентична процедуре досту¬ па к любому файлу системы. Каталог под названием usr содержит каталоги всех пользователей системы Юникс. (В очень больших системах может быть несколько каталогов пользовате¬ лей с именами типа usr1, usr2 или какими-либо другими.) Ваш собственный ката¬ лог является вашим начальным каталогом (home directory), который администра¬ тор системы назначает вам и в котором вы начинаете работать при входе в си¬ стему. В нем вы можете иметь столько подкаталогов, сколько вам необходимо для работы. Вы можете, например, образовать один каталог для своих текстовых файлов, другой — для файлов программ, третий — для сообщений и т. д. Ниже приведены каталоги типичной системы Юникс: bin — содержит системные двоичные файлы, известные как файлы исполни¬ тельных объектных кодов (большинство команд находится в этом катало¬ ге);
26 Часть I dev — содержит файлы, представляющие системные устройства (терминалы, устройства печати, накопители на магнитных дисках и т. д.); tmp — содержит временные файлы системы; etc — содержит остальные файлы, которые используются преимущественно ад¬ министратором системы. Все эти пять основных каталогов принадлежат главному каталогу, который называется корневым каталогом (root directory) (или просто корень (root)), образу¬ ющим основные ветви дерева каталогов. Это дерево обычно изображают "вверх дном“: с корнем вверху и ветвями, направленными вниз. Часть простой файло¬ вой системы Юникс показана на рис. 3.1. Она содержит начальные каталоги пользователей, имеющих идентификаторы Dan, Robin и Ann. root Рис. 3.1. Часть структуры типичной файловой системы Юникс. ^Таким образом, система Юникс имеет структурированную файловую систему, которая содержит три вида файлов: каталоги (directories), которые хранят имена других файлов (в том числе и другие каталоги); обычные файлы (ordinary files), которые хранят текст, исходные программы и объектные коды; специальные файлы (special files), которые соответствуют периферийным устройствам. Ниже мы рассмотрим, как именуются каталоги и файлы, как генерировать имена фай¬ лов, как работать с файлами и каталогами и как разрешать или запрещать доступ к вашим каталогам и файлам. Именование каталогов и файлов Корневой каталог определяется единственным символом: / (косая черта). Для именования основных каталогов, непосредственно доступных из корневого ката¬ лога, следует указать косую черту /, означающую корневой каталог, а затем собст¬ венное имя каталога, например lusr. Косая черта / перед usr говорит о том, что
Основные сведения о системе Юникс 27 usr является подкаталогом корневого каталога. Ниже показано, как вы можете идентифицировать корень и основные каталоги, содержащиеся на рис. 3.1: / — корневой каталог; /usr — каталоги пользователей; /bin — каталог двоичных файлов; /dev — каталог устройств; /etc — каталог остальных файлов; /tmp- каталог временных файлов. Чтобы определить один из начальных каталогов пользователя, наберите по¬ сле lusr еще одну косую черту / и соответствующее имя, например lusrldan или lusrlann. В обоих случаях первая косая черта / является ссылкой на корневой ка¬ талог, а вторая определяетс/ал и ann как подкаталоги катапогаивг. [В терминоло¬ гии системы Юникс usr — это каталог-отец, или родительский каталог (parent directory), а dan и ann — подкаталоги (subdirectories)]. Для указания подкаталогов для каталогов dan иапп мы воспользуемся тем же соглашением. Поэтому каталог пользователя Dan с именем text получает имя lusr/dan/text, а каталог пользователя Ann с именем project.a — /usr/annlproject.a. Вернувшись опять к рис. 3.1, вы можете определить все их каталоги: /usr/dan/tex t /usr/ann/project a /usr/dan/c progs /usr/ann/project b /usr/danJletters /usr/ann/project с Пусть у пользователя Dan в файле содержатся три программы на языке Си с именами enter.c, files.c и proc.c, а у пользователя Ann — три файла в каталоге project.b, названные как intro, search и restore. Рассмотрим теперь другую часть файловой системы, представленную на рис. 3.2. Dan Ann Рис. 3.2. Файлы пользователей в файловой системе Юникс- Чтобы указать эти шесть файлов, вы можете написать их составные имена (pathnames): /usr/dan/c-progs/enter. с /usr/ann/project. b/intro /usr/dan/c-progs/files. с /usr/annJproject. b/search /usr/danJc-progs/p roc. с /usr/ann/project b/restore
28 Часть I Ann и другие пользователи могли бы использовать имена из левой колонки, чтобы обратиться к файлам пользователя с именем Dan, и, наоборот, Dan и дру¬ гие пользователи могли бы брать имена из правой колонки, чтобы обратиться к файлам Ann. Но, когда Dan и Ann ссылаются на свои собственные файлы в сво¬ их каталогах, они могут использовать более короткие имена (частичные состав¬ ные имена (partial pathnames)): c.progs/enter. с project b/intro C-progs/files. с project b/search c-progs/proc. с project b/res tore Ниже показано, как переходить в файловой системе от одного каталога к дру¬ гому (как менять каталоги). Если бы Dan мог перейти из своего начального ката¬ лога в каталог Ann, то он мог бы,использовать более короткие имена, чем приме¬ няет Ann, когда она находится на уровне своего собственного начального ката¬ лога, и наоборот. Более того, если бы Dan мог перейти из своего начального каталога в свой подкаталог с именем с progs, а Ann — в подкаталогрго/есЛЬ, то для доступа к своим файлам они могли бы использовать еще более короткие имена: enter.c intro files.c search proc.c restore Правила именования и доступа к файлам Правила именования и доступа к файлам (включая каталоги) тесно связаны со структурой файловой системы Юникс: • Корневой каталог идентифицируется косой чертой. • Простое имя файла может быть любой комбинацией от 1 до 14 символов, кроме косой черты, звездочек, знаков вопроса, кавычек (” или ’), квадратных скобок ([ или ]) или управляющих символов. • Составное имя файла образуется из последовательности имен каталогов, разде¬ ленных косой чертой, за которыми, возможно, следует простое имя файла. Чтобы избежать неверной интерпретации, в простом имени файла лучше все¬ го использовать буквы алфавита, цифры, точки, дефисы и символы подчеркива¬ ния. Следует отметить, что в системе Юникс буквы верхнего и нижнего регист¬ ров не являются эквивалентными, например newfile не обозначает то же самое, что NEWFILE. Постоянно назначенный вам каталог называется вашим начальным каталогом (home directory); это тот каталог, в который вы попадаете при входе в систему. Любой каталог, в который вы можете перейти после входа в систему (включая ваш начальный каталог), будет называться текущим каталогом (current directory), или рабочим каталогом (working directory) до тех пор, пока вы остаетесь в этом каталоге. Каталог, к которому принадлежит ваш текущий каталог, называется каталогом-отцом, или родительским каталогом. В системе Юникс предусмотрены стенографические знаки, чтобы сокращенно обозначить ваш текущий каталог (.) и ваш родительский каталог (..). Если составное имя файла начинается с косой черты /, то поиск файла начи¬ нается с корневого каталога. Такое составное имя файла называется абсолют¬
Основные сведения о системе Юникс 29 ным составным именем (absolute pathname), поскольку оно всегда начинается с корневого каталога. Если составное имя файла начинается с простого имени файла, то поиск для файла ведется, начиная с вашего текущего каталога. Такое составное имя файла называется относительным составным именем (relative pathname) файла, так как доступ к файлу осуществляется относительно вашего текущего каталога. Ниже мы рассмотрим процедуры предоставления права доступа (permission) к вашим каталогам и файлам и для других пользователей. Очевидно, вы можете обращаться только к тем файлам, для которых вы обладаете правом доступа. Работа с файлами При составлении писем, проведении вычислений или написании программ вы много времени проводите на ЭВМ, работая с файлами. Всегда полезно знать, как выводить, объединять, копировать или выполнять еще какие-нибудь операции с файлами. В данном разделе мы как раз и обсуждаем такие операции с файлами. Создание файла > Обычно система Юникс сама создает файлы, когда этого требуют команды при их выполнении. Следовательно, не надо создавать файл до выполнения коман¬ ды, которая сохраняет в нем результат своей работы. Но, если когда-либо воз¬ никнет потребность создать пустой файл (например, с именем put.into), для этого можно воспользоваться знаком >, как в приведенном ниже примере. Проделайте это, чтобы убедиться, что при использовании знака > создание файла происхо¬ дит перед выполнением команды, а не после. $ >put.into Вывод содержимого файла cat Для вывода содержимого любого файла используйте команду cat (concatenate — сцеплять), которая лишь отображает содержимое файла (или нескольких файлов) на экран дисплея, например: $ cat fi le.3 This that $ $ cat fi le.1 fi le.2 is а very short file contains two lines. Thi s Thi s $ is "file.1" is "file.2" Объединение файлов cat Другой функцией команды cat является объединение, или конкатенация файлов; результат слияния обычно сохраняется в другом файле. В следующем примере $ $ cat file.1 file.2 > file.1+2 содержимое файлов file.1 и file.2 объединяется и запоминается как отдельный файл с именем fHe.1+2. При использовании команды cat избегайте сохранения
30 Часть I результата объединения файлов в одном из них, поскольку это испортит исход¬ ный файл. Например, в команде [Не делайте так!] file.1 просто становится файлом file.2, а это не совсем то, что ожидается. Переименование файла mv Для переименования файла или его перемещения из одного каталога в другой можно использовать команду mv (move — передвигать). Чтобы изменить имя файла, введите, например, такую команду: $ $ Она изменит имя файла с old.name на new.name (после этого вы не сможете обратиться к файлу по имени old.name). mv old.name new.name $ cat file.1 fiLe.2 > f i Le.1 $ Перемещение файла mv Чтобы переместить один или несколько файлов из одного каталога в другой (без изменения их имен), укажите имя нового каталога в конце командной строки, на¬ пример: $ $ mv fi le.3 file.4 text Эта команда переместит file.3 и file.4 из вашего текущего каталога в подкаталог с именем text. Проверку этого можно сделать командой Is (list — список): $ f file.4 $ ls text ile.3 При перемещении файла вы можете переименовать файл, указав частичное составное имя. Например, чтобы переместить файл file.3 в подкаталог text и пе¬ реименовать его в entries, можно выполнить команду: $ $ mv file.3 text/entries Копирование файла cp Для получения копии файла используйте команду cp (сору — копировать), как в следующем примере: $ cp file.one FILE.ONE
Основные сведения о системе Юникс 31 Эта команда создаст копию файла///e.one под названием FILE.ONE, так что один и тот же файл теперь доступен по тому и другому имени. (Напомним пользовате¬ лям других операционных систем: в системе Юникс имена file.one и FILE.ONE представляют собой различные имена.) Чтобы скопировать один или несколько файлов, находящихся в одном ката¬ логе, в другой каталог, следует выполнить команду cp, например: $ $ Эта команда скопирует файлы letter_a, letter_b и letter_c из текущего каталога в каталог correspondence с теми же именами. При копировании вы можете переименовать файл. Например, чтобы скопиро¬ вать файл letter_c в каталог correspondence и переименовать его в файл ltr.04-16-85, можно использовать команду $ $ cp letter__c correspondence/ltr.04-16-85 cp letter_a letter__b letter_c correspondence Удаление файла rm Для удаления одного или нескольких файлов используйте команду rm (remove — удалять). Например: $ $ Эта команда удалит файлы intro.1, intro.2 и intro.3 из текущего каталога. Заме¬ чание. В системе Юникс файлы удаляют сразу; не выводят предупреждения типа ”Вы уверены, что хотите удалить эти файлы?“. И когда файлы удалены, вы не сможете восстановить их, если другие пользователи не имеют связь с этими файлами или они не были сохранены на магнитной ленте. rm intro,1 intro.2 intro.3 Создание связи с файлом ln Связью (или ссылкой) называется элемент в каталоге, который указывает на файл. В системе Юникс файл может иметь несколько связей, что означает его принадлежность нескольким различным каталогам (с тем же размером, содержи¬ мым и другой информацией, характеризующей файл). Ссылка на файл не может отличаться от начального элемента файла в каталоге, поэтому любые измене¬ ния, внесенные в файл, отразятся на каждом имени, под которым файл может быть известен в системе. Например, если Dan выполнит показанную в данном примере команду ln (link — связывать) из своего подкаталога letters, то он будет иметь доступ к фай¬ лу intro из своего подкаталога letters по тому же самому имени intro, но при усло¬ вии, что он имеет право доступа к этому файлу: $ cd Letters | $ Ln /usr/ann/project.b/intro intro $
32 Часть I Dan Ann Если Dan предпочитает другое имя для файла, он должен указать его в конце командной строки In. В приведенном ниже примере Dan устанавливает ту же связь, что и в предыдущем, но на этот раз файл будет доступен пользователю Dan под именем discover (рис. 3.3): $ $ ln /usr/ann/project,b/intro discover Отметим, что невозможно установить связь одного каталога с другим или связь файлов из различных файловых систем. Генерация имен файлов с помощью метасимволов При перемещении, копировании или удалении большого числа файлов вы можете сэкономить время за счет уменьшения числа набираемых символов, если при ге¬ нерации имен файлов используете один из метасимволов. Существуют три разно¬ видности генерации имен, и все, как правило, имеют один и тот же смысл во всех версиях системы Юникс. Метасимвол для одного символа имени ? Для генерации какого-нибудь отдельного символа в имени файла можно исполь¬ зовать знак вопроса (?) в нужной позиции этого имени. Например, для удаления файлов intro.1, intro.2 и intro.3, как в примере выше, вы могли бы выполнить ко¬ манду: $ $ Если в системе больше нет файлов с именами, начинающимися на intro. и закан¬ чивающимися только одним символом после точки, данная команда эквивалент¬ на команде, приведенной выше в разделе ГУдаление файла“. rm intro.?
Основные сведения о системе Юникс 33 Если файлы letter_a, letter_J> и letter_c — единственные из имеющихся в си¬ стеме и начинающихся на letter , а заканчивающихся после этого еще одним символом, то для их копирования в каталог с именем correspondence можно ис¬ пользовать команду: $ $ В каждом из приведенных выше примеров предполагалось, что указанные в них файлы существуют. Для еще несозданных файлов метасимвол типа ? исполь¬ зовать нельзя. cp letter_? correspondence Метасимвол для символа из заданного набора U Чтобы сократить процедуру генерации символа в имени файла из некоторого на¬ бора символов, необходимо в соответствующей позиции имени файла указать этот набор в квадратных скобках. Пусть, например, в вашем рабочем каталоге есть файлы с такими именами: writer.0 writer.3 wn'ter.6 writer.9 writer.1 writer.4 writer.7 writer.10 writer.2 writer.5 writer.8 writer.11 Чтобы удалить файлы writer.5, writer.7 и writer.9, вы можете использовать следую¬ щую команду: rm writer.[579] Три цифры внутри квадратных скобок позволяют выбрать три желаемых файла. В скобках можно задать также диапазон букв или цифр. Например, чтобы удалить файлы writer.1, writer.2, writer.3 и writer.4, можно выполнить команду: $ rm writer.[1-4] Метасимвол для любого числа символов * Для генерации произвольного числа символов в имени файла в нужной позиции этого имени следует поставить звездочку *. (Чтобы генерировать все имя файла, используйте одну звездочку.) Пусть в вашем рабочем каталоге находятся следую¬ щие файлы: info.a info.ab info.abc info.test info.b info.23 info.new info.old Если вы изменили родительский каталог, то чтобы переместить все эти фай¬ лы из каталога obsolete в подкаталог с именем information, выполните команду: $ $ mv obsolete/info.* information s-ui
34 Часть I Теперь предположим, что у вас в подкаталоге text есть следующие программы на языке Си: enter.memo fiLes.dept wide__col.c news.ltr F__327.c a__fUe.text new__compare.c get__number.c Чтобы скопировать все файлы, имена которых заканчиваются на .c в подкаталог с именем С programs, выполните команду: $ $ cp text/*.c C__programs Однако будьте очень внимательны при использовании звездочки, особенно с командой rm. Если вы введете неправильную команду, можете неумышленно уда¬ лить свои файлы. Работа с каталогами Ниже описаны шесть команд, которые позволяют работать с каталогами системы Юникс. Вывод содержимого каталога Is Для упорядочения и вывода на экран имен всех каталогов и файлов вашего теку¬ щего каталога используйте команду Is (list), например: *05] file.1 fi le.2 letters memos specs $ Такая форма вывода не позволяет определить, какие имена являются имена¬ ми файлов, а какие — именами каталогов. Но существует другая форма коман¬ ды, с помощью которой можно отличать файлы от каталогов и выводить о них дополнительную информацию. Для этого в команду добавляется опция1) -I, что¬ бы получить расширенный листинг каталога, например: $l ls -L totaL 501 -rw-r 1 robi n 108 Apr 5 14:33 file.1 -rw-r 1 гоЫ n 123 Apr 9 09:17 file.2 drwx—x 2 robi n 301 Mar 27 08:04 letters drwx—x 1 robi n 87 Mar 15 13:42 memos drwx—x $ _ 2 robin 428 Маг 11 15:31 specs 1) В отечественной литературе используются еще термины "необязательный параметр", ключ“, ”флаг“. — Прим, перев.
Основные сведения о системе Юникс 35 Более подробно этот листинг каталога мы рассмотрим в следующем разделе. Здесь же лишь приведем данные, которые выводятся для каждого файла или ка¬ талога: •Тип файла: обычный (-) или каталог (d). • Права доступа (рассмотрены в следующем разделе). • Число связей с другими пользователями файловой системы. • Владелец (или создатель) файла. • Размер файла в байтах (символах). • Дата и время последней модификации файла. • Имя файла. Изменение рабочего каталога cd Для изменения своего рабочего каталога (т. e. перехода в другой каталог) исполь¬ зуйте команду cd (change directory — изменить каталог), например: $ cd /usr/harold $ Если вы обладаете соответствующими правами доступа, после выполнения этой команды можете работать в начальном каталоге harold. Чтобы вернуться в свой начальный каталог из любого другого каталога, нужно выполнить команду cd, не содержащую имени: cd Определение имени рабочего каталога pwd Чтобы определить имя своего текущего рабочего каталога, выполните команду pwd (print working directory — печатать рабочий каталог), например: $ pwd /usr/robin $ Создание нового каталога mkdir Чтобы создать подкаталог в своем текущем рабочем каталоге, используйте ко¬ манду mkdir (make directory — составить каталог), например: mkdi г messages $ Эта команда образует новый подкаталог с именем messages. При создании свое¬ го начального каталога стремитесь определить подходящее число подкаталогов. При слишком малом их числе вы теряете преимущества структуры файловой си¬ стемы Юникс, а при слишком большом — создаете себе неудобства. Обычно опти¬ мальное число лежит в диапазоне 5—15, но возможны и исключения.
36 Часть I Удаление существующего каталога rmdir Чтобы удалить существующий каталог из рабочего каталога, перейдите в удаляе¬ мый каталог, уничтожьте все его файлы, вернитесь обратно в родительский ка¬ талог, а затем используйте команду rmdir (remove directory — удалить каталог). Пусть, например, вы хотите удалить каталог по имени useless. Для этого вы мо¬ жете выполнить следующую последовательность команд: $ $ /usr/useless $| rm * cd /usr/useless pwdf [Перейдите в каталог useless] [Убедитесь, что вы в нужном каталоге] [Удалите все файлы в каталоге useless] $ cd -. $ rmdir useLess $ [Вернитесь в родительский каталог] [Удалите каталог useless, который теперь пуст] [Каталог и его файлы исчезают] Во многих системах можно использовать более короткие последовательности команд, чем приведенная выше последовательность. Например: rm /usr/useless/* rmdir /usr/useLess [Удаление всех файлов в каталоге useless] [Удаление каталога useless] rm -r /usr/useLess [Удаление файлов в каталоге useless, а затем удаление самого каталога] Переименование каталога mv Для изменения имени каталога используйте команду mv (move). Например, изме¬ нить имя каталога old.name на имя new.name можно следующей командой: $ $ mv oLd.name new.name Права доступа к файлам и каталогам В гл. 2 отмечалось, что система Юникс позволяет вам обращаться к другим ката¬ логам и файлам только с разрешения их владельцев. В этом разделе обсуждают¬ ся права доступа к файлам в системе Юникс, которые применяются к трем кате¬ гориям пользователей: индивидуальным владельцам, группам пользователей и остальным пользователям. Определение прав доступа Is -I Для определения прав доступа, связанных с конкретным файлом или каталогом, служит команда Is -I, описанная в предыдущем разделе. Права доступа определя¬ ются девятью символами, следующими непосредственно за первым символом:
Основные сведения о системе Юникс 37 $ |ls -1 total 501 -rw-r 1 robin 108 Apr 5 14:33 file.1 -rw-r 1 robin 123 Apr 9 09:17 file.2 drwxr-x— 1 robin 87 Mar 15 13:42 memos drwxr-x 2 robin 301 Маг 27 08:04 letters drw-rw 1 robin 216 Mar 3 11:56 proposals drw-r 2 robin 428 Mar 11 15:31 specs Первый символ, как указано выше, определяет тип файла: обычный файл; b блокориентированный специальный файл; d каталог; с байториентированный специальный файл. Остальные девять символов представляют три набора по три символа: пер¬ вый — для индивидуального пользователя (или владельца), второй — для груп¬ пы пользователей, а третий — для всех остальных пользователей. Если взять со¬ держимое экрана и развернуть его символы для того, чтобы показать как группи¬ руются символы, то мы получим следующее: Tun - (файл) Пользователь r w - Группа r - - Остальные file.1 - (файл) r w x r - x — file.2 - (файл) r w x r - x - - - memos - (файл) r w - r - - r - - letters d (каталог) r w - r w - r w - proposals d (каталог) r w - r r specs В каждой из этих групп символов первый символ определяет право , для чтения, второй — для записи, третий — для выполнения файла. Чтение, за¬ пись и выполнение имеют различный смысл для обычных файлов и каталогов. Для обычного файла: • разрешение на чтение означает, что вы можете просмотреть содержимое файла; • разрешение на запись дает возможность изменять содержимое файла; • разрешение на выполнение означает, что вы можете ввести имя файла в ко¬ мандной строке так, как будто файл является командой системы Юникс. Для каталога: • разрешение на чтение означает, что вы можете просмотреть имена файлов, со¬ держащихся в каталоге; • разрешение на запись позволяет вам добавлять файлы в каталог и удалять фай¬ лы из каталога; • разрешение на выполнение означает для вас возможность заменять каталог, осуществлять в нем поиск и копировать из него файлы. Для обозначения этих прав доступа используются следующие символы: r разрешение на чтение; x разрешение на выполнение; w разрешение на запись; отсутствие разрешения.
38 Часть I Объединяя их вместе, получаем девять символов; например, для каталога с именем memos, который представлен выше при выводе на экран по команде Is -I, имеем Владелец Группа Остальные Файл г w x r - x - - — memos В этом примере владелец каталога memos имеет разрешение на чтение (r), за¬ пись (w) и выполнение (x); члены группы владельца — только на чтение (r) и ис¬ полнение (x), но не на запись (-); все остальные пользователи не имеют права до¬ ступа любого типа (- - -). Приведем девять символов режима доступа для файла с именем file.1: Владелец Группа Остальные Файл г w - г - - - - - fi le.1 Владелец файла file.1 имеет разрешение на чтение (r) и запись (w), но не на выполнение (-); члены рабочей группы файла имеют разрешение только на чтение (г), но не на запись (-) или выполнение (-), а остальные пользователи не обладают правом доступа любого типа (- - -). Изменение прав доступа chmod Изменить права -доступа можно с помощью команды chmod (change [access] mo¬ de — изменить способ доступа). Эта команда позволяет владельцу файла добав¬ лять (+) или отменять (-) любой из трех типов доступа для любой из трех катего¬ рий пользователей системы Юникс. Для этого используются символы в следую¬ щем порядке (слева направо): u владелец; + добавление права доступа; r читать; 9 группа; отмена права доступа; w писать; о остальные; = назначение права доступа; X выполнять. а все пользователи; Допустим, вы хотите предоставить право записывать в файл file.1 членам ва¬ шей группы и право читать этот файл и записывать в него для остальных поль¬ зователей системы. Вы могли бы сделать это следующими выражениями в ко¬ манде chmod: g + w добавление права (+) писать (w) членам вашей рабочей группы (g); о + rw добавление права (+) читать (r) и писать (w) всем остальным пользова¬ телям (о). Затем, используя команду Is -I для отображения на экране состояния ”до“ и ’’по¬ сле", вы можете объединить оба этих действия в команде chmod, как показано ниже. Замечание. Вы должны вводить командную строку для chmod так, как по¬ казано ниже, с запятой между g + w и o + rw и без пробелов вокруг запятой. $ Ls -L file.1 fi le.1 -rw-r 1 robin 108 Арг 5 14:33 $ chmod g+w,o+rw fi le.1 $ ls -1 fUe.1 -rw-rw-rw- 1 robi n 108 Арг 5 14:33 file.1 $
Основные сведения о системе Юникс 39 Для отмены действующих в текущий момент прав доступа используйте в ко¬ манде chmod вместо знака плюс (+) знак минус (-). Предположим, вы хотите от¬ менить право писать в файл file.1 членам вашей группы и право читать этот файл и записывать в него для остальных пользователей (т. e. отобрать права, предоставленные в предшествующем примере). Для этого вы можете использо¬ вать следующие выражения в команде chmod: g-w отмена права (-) писать (w) членам вашей рабочей группы (g); o-rw отмена права (-) читать (г) и писать (w) всем остальным пользователям (о). После этого, используя команду Is -I для отображения на экране состояния ”до“ и ”после“, вы можете включить эти выражения в KOMaHflychmod и выполнить ее: $ Ls -l file.1 -rw-rw- rw- 1 robin 108 Арг 5 14:33 file.1 $ chmod g-w,o-rw fi le.1 $ ls -1 fi le.1 -rw-r— — 1 robin 108 Apr 5 14:33 file.1 $ _ Предостережение. Командой chmod вы можете ликвидировать собственные права доступа к своему файлу. Будьте внимательны при использовании команды. Краткое изложение главы 3 После краткого введения в этой главе рассматриваются структура файловой си¬ стемы ОС Юникс, а затем основные процедуры для работы с файлами, каталога¬ ми и режимами доступа. Что ТАКОЕ ФАйловАЯ систЕМА? Файловую систему ЭВМ можно сравнить с систе¬ мой картотек, которую используют в библиотеке и в которой карточный каталог подобен каталогу файловой системы, а книги — файлам. В системе Юникс сам каталог является файлом. СТРУКТУРИРОВАННАЯ ФАйловАЯ систЕМА. ОС Юникс имеет структурированную файловую систему с основным каталогом (называемым корнем) в вершине и по крайней мере пятью большими каталогами, которые ответвляются от корневого каталога. Этими пятью каталогами являются следующие: usr — каталог пользователей; bin — каталог двоичных файлов; dev — каталог файлов устройств; tmp- каталог временных файлов; etc — каталог остальных файлов. Каждый пользователь системы Юникс имеет начальный каталог в каталоге usr (или в каталоге пользователей с другим именем). Имя начального каталога совпа¬ дает с идентификатором пользователя, с которым он входит в систему. Пользо¬ ватель может создавать столько подкаталогов в своем начальном каталоге, сколько ему необходимо. ИМЕНОВАНИЕ ФАйлов и КАТАЛогов. Полное составное имя каждого файла начина¬ ется со знака корневого каталога (косая черта / ), затем следует имя основного каталога, затем — имя подкаталога и так далее до собственно имени файла.
40 Часть I ПРАВИЛА имЕНОВАНия и доступА к ФАЙЛАМ. Косая черта / определяет корневой ка¬ талог. Кроме того, она используется для отделения имен каталогов и имени фай¬ ла друг от друга в составном имени файла. Имя файла содержит от 1 до 14 сим¬ волов, за исключением управляющих символов, а также символов / * ? “ ’ [] После входа в свой начальный каталог вы можете переходить из одного катало¬ га в другой, если имеете право доступа. Любой каталог, в котором вы работаете в конкретный момент времени, является вашим рабочим, или текущим, каталогом. Наряду с полным составным именем, которое может быть задано из любого каталога, можно использовать и относительное составное имя, т. e. составное имя относительно вашего текущего каталога. Работа с файлами СоздАНИЕ ФАйЛА. Для создания пустого файла используйте перед именем файла символ >. Вывод содЕРЖимого ФАйЛА. Для вывода содержимого файла используйте либо команду cat, либо команду more. ОБЪЕДИНЕНИЕ ФАйлов. Чтобы объединить (слить) файлы, используйте команду cat с адресацией вывода в результирующий файл (>). ПЕРЕИМЕНОВАНИЕ ФАЙЛА. Для переименования файла используйте команду mv, старое имя файла, а за ним — новое имя файла. ПЕРЕМЕЩЕНИЕ ФАЙЛА. Чтобы переместить файл (или файлы) из одного каталога в другой, используйте команду mv, имя (имена) файла (файлов), а за ним (ними) составное имя нового каталога. КопировАНИЕ ФАйЛА. Для получения копии файла в одном и том же каталоге используйте команду cp следующим образом: $ cp original сору Чтобы скопировать файл (или файлы) из одного каталога в другой, используйте команду cp в виде: $ cp file__1 file__2 file_3 /usr/directory УДАЛЕНИЕ ФАйЛА. Для удаления файла (или файлов) используйте команду rm, за которой следует имя (имена) файла (файлов). СоздАНИЕ связи с ФАйлом. Чтобы связаться с файлом (т. e. присоединить файл к различным каталогам), используйте команду ln, задавая в ней полное составное имя файла, с которым устанавливается связь, и имя файла в новом каталоге (но¬ вое имя не обязательно отличается от начального). Использование метасимволов МЕТАСИмвол для одного символА. Для подбора любого отдельного символа в име¬ ни файла используйте вопросительный знак (?) в требуемой позиции имени. МЕТАСИмвол для символА иззАДАНного НАБОРА. Чтобы подобрать в имени файла один символ из набора символов, следует заключить этот набор символов в ква¬ дратные скобки [] и установить в требуемой позиции имени. МЕТАСИмвол для ЛЮБОГО числА символов. Чтобы подобрать в имени файла лю¬ бое число символов, используйте звездочку * в требуемой позиции имени файла.
Основные сведения о системе Юникс 41 Работа с каталогами Вывод содЕРЖимого КАТАЛОГА. Для вывода упорядоченного списка имен всех ката¬ логов и файлов, содержащихся в вашем текущем каталоге, используйте команду Is (с опцией -I для вывода расширенного листинга). ИЗМЕНЕНИЕ РАБОЧЕГО КАТАЛОГА. Чтобы изменить свой рабочий каталог (т. e. пе¬ рейти из одного каталога в другой), используйте команду cd с именем нового ка¬ талога (при отсутствии имени осуществляется возврат в начальный каталог). ОПРЕДЕЛЕНИЕ ИМЕНИ РАБОЧЕГО КАТАЛОГА. Для определения имени своего текущего рабочего каталога выполните команду pwd. СоздАНИЕ нового КАТАЛОГА. Для создания нового подкаталога в вашем рабочем каталоге выполните команду mkdir. УДАЛЕНИЕ СУЩЕСТВУЮЩЕГО КАТАЛОГА. Для удаления существующего каталога из вашего рабочего каталога перейдите в удаляемый каталог, удалите все его фай¬ лы, вернитесь обратно в свой рабочий каталог, а затем выполните команду rmdir. (Вы можете использовать и команду rmdir -r.) Права доступа к файлам и каталогам ОПРЕДЕЛЕНИЕ ПРАВ доступА. Для определения прав доступа к файлу или каталогу используйте команду Is -I. Первый символ указывает, является ли файл обычным файлом (-) или каталогом (d). Последующие девять символов определяют права на чтение (r), запись (w) или выполнение (x), которые гарантируются владельцу, рабочей группе или остальным пользователям. ИЗМЕНЕНИЕ ПРАВ доступА. Чтобы изменить права доступа для каталога или фай¬ ла, используйте команду chmod, добавляя (+) или отменяя (-) права на чтение (r), запись (w) или выполнение (x) для владельца (u), для группы (g), для всех осталь¬ ных пользователей (о) или вообще для всех пользователей (а). Глава 4. Команды системы Юникс После ознакомления с файловой системой можно перейти к более глубокому изу¬ чению команд системы Юникс. Данная глава начинается с обсуждения команд¬ ных строк, затем рассматриваются методы взаимодействия процессов и, нако¬ нец, описываются команды вывода текста на экран дисплея, обработки тексто¬ вых файлов и использования печатающих устройств. Построение командной строки Общий формат командных строк В общем случае командная строка состоит из трех частей, хотя не каждая коман¬ да содержит одновременно все три части: Имя команды Опция Имя файла (имена файлов) Большинство команд системы Юникс имеет короткие имена. Опции обычно обозначаются дефисом (или знаком минус), за которым следует буква, называе¬ мая иногда ключом. В некоторых случаях в команде за знаком минус можно ука¬ зывать несколько букв, однако иногда это запрещено. Вместо знака минус в ряде
42 Часть I случаев опциям команд может предшествовать знак плюс. Многие команды си¬ стемы Юникс позволяют указывать одно или несколько имен входных файлов. (Выходные файлы в общем случае, но не всегда определяются ключом выходной опции, например о. Другой способ определения выходного файла рассмотрен ниже.) Опции и имена файлов, которые указываются за именем команды, служат аргументами команды. В качестве примера рассмотрим команду Is (вывод содержимого каталога), описанную в гл. 3. В Руководстве программиста системы Юникс (или Руководстве пользователя системы Юникс) указывается одиннадцать возможных опций для этой команды, которые описаны в разделе ”Синтаксис“ следующим образом (для удобства здесь добавлены заголовки): Имя Опции команды Фаип(ы) Is [-ltasdrucifg] name... Именем команды является Is (от слова list). В команде можно использовать одиннадцать различных опций: -I (длинный формат), -t (время последней модифи¬ кации), -а (все файлы, в том числе с именами, начинающимися с точки), -s (дать размер файла), -d (только имена каталогов), -r (инвертировать порядок вывода) и так далее (остальные опции для нас сейчас несущественны). Квадратные скобки, которые не указываются при вводе командной строки, означают, что все ключи являются необязательными. Сжатие одиннадцати букв-ключей в единое слово оз¬ начает, что несколько букв может следовать за одним знаком минус. (Только не пытайтесь заучивать произношение этого слова.) Для команды Is одни опции ис¬ ключают другие. Наконец, словолаше, за которым следует многоточие, означает, что после опций следует ввести хотя бы одно имя каталога. Ниже приводится ряд командных строк, которые могут быть образованы с командой Is: ls Вывод содержимого текущего каталога ls -1.. ls -als /usr/pau^J Вывод содержимого родительского каталога в длинном формате Вывод информации о всех файлах шталота/usr/paul в длинном формате с указанием размеров файлов ls -а /etc /bin Вывод списка всех файлов из каталога /etc, затем из каталога /bin В этой книге мы не пытаемся дать исчерпывающее описание каждой коман¬ ды. Это — задача Руководства программиста системы Юникс или Руководства пользователя системы Юникс. Цель данного раздела — ознакомить со структу¬ рой командной строки, а также указать, как следует интерпретировать синтаксис команд системы Юникс. Переадресация ввода и вывода Задача, решаемая на ЭВМ, может быть сведена к трем фазам: • Ввод — пользователь предоставляет программе информацию для обработки. • Обработка — программа совершает набор действий над информацией, получен¬ ной от пользователя. • Вывод — программа возвращает результаты обработки пользователю.
Основные сведения о системе Юникс 43 Хотя большинство этих действий выполняется электронными устройствами, по содержанию эти фазы подобны тому, что происходит, когда вы подходите к окошку в банке, чтобы сделать вклад. Вы вручаете кассиру подписанный чек с карточкой вклада (ввод); кассир делает запись о вкладе и ставит штамп на кви¬ танции (обработка); затем кассир отдает вам квитанцию для сохранения (вывод). Когда вы работаете на ЭВМ, оснащенной системой Юникс, для вас становит¬ ся привычным выполнять ввод через клавиатуру вашего терминала и получать результаты на его экране. В самом деле, ОС Юникс рассматривает вашу клавиа¬ туру как стандартное устройство ввода (standard input), а экран как стандартное устройство вывода (standard output). Например, она будет предполагать, что ко¬ манда date вводится с клавиатуры и что информация, запрашиваемая по этой ко¬ манде (дата, день недели, часы, минуты, секунды), должна отображаться на ва¬ шем экране. Однако для большинства команд системы Юникс вы всегда можете переадре¬ совать ввод или вывод. Например, можно сделать так, чтобы команда получала данные из файла, а не с клавиатуры или посылала результаты на другой терми¬ нал, а не на ваш. (Помните, что система Юникс рассматривает устройства типа терминалов как файлы.) Для обозначения переадресации ввода или вывода в командной строке используются знаки < и >. Вы можете рассматривать эти зна¬ ки как наконечник стрелы, нацеленный в направлении потока информации. Переадресация ввода В качестве примера рассмотрим команду mail (почта). Она принимает от вас неко¬ торый текст и передает его всем пользователям, имена которых вы указываете в командной строке mail. Так, чтобы послать почтовое сообщение пользователям с именами Mary, John, Sandy и Paul, после знака-подсказки интерпретатора shell можно ввести следующую команду, а затем набрать на клавиатуре само сообще¬ ние: mail mary john sandy paul Предположим, вы вводите письмо с помощью редактора ed и затем сохраня¬ ете его в файле с именем letter 5. Позже это почтовое сообщение вы могли бы послать тем же самым пользователям системы Юникс и с помощью команды mail с переадресацией ввода. Для этого нужно набрать следующую командную строку и нажать клавишу RETURN: mail mary john sandy paul < letter_5 Направление ’’наконечника стрелы“ говорит о том, что letter 5 является вход¬ ным файлом, который заменяет клавиатуру вашего терминала. Переадресация вывода Как знак < используется для переадресации ввода, так же знак > применяется для переадресации вывода. Например, командная строка ls выдаст список всех файлов вашего каталога на экран вашего терминала. В си¬ стеме Юникс вы можете видоизменить командную строку ls следующим образом: $ ls > fi les
44 Часть I чтобы переадресовать вывод с экрана на файл с именем files. Если files не су¬ ществует, когда выполняется команда Is, он будет создан интерпретатором shell; если же он уже существует, его содержимое будет изменено. Переадресация вывода часто используется при объединении, или конкатена¬ ции, нескольких файлов с помощью команды cat. Чтобы объединить вместе фай¬ лы file 1, file 2 и file 3 и сохранить результирующий текст в файле с именем combine, введите после знака-подсказки интерпретатора shell следующую команд¬ ную строку и нажмите клавишу RETURN: $ cat file 1 fiLe 2 file 3 > combine Затем, чтобы объединить еще три файла и добавить результирующий текст к файлу combine, а не заменять его содержимое, используйте символ переадреса¬ ции >>. Например, чтобы слить файлы file_4, fiie_5 и file_6 и присоединить результирующий текст к файлу combine, введите после знака-подсказки интер¬ претатора shell следующую командную строку и нажмите клавишу RETURN: $ cat file 4 file 5 file 6 » combine Если файл не существует, использование символа переадресации > >, как и в случае символа >, вызывает создание интерпретатором shell нового файла; если же файл уже существует, символ > > всегда присоединяет новый текст к концу этого файла, но не заменяет его полностью. Конвейеры Выше говорилось, что система Юникс рассматривает клавиатуру терминала как стандартное устройство ввода, а его экран как стандартное устройство вывода для большинства выполняемых команд, являющихся процессами. (В терминоло¬ гии системы Юникс команда, которая выполняется в текущий момент, называет¬ ся процессом1).) Кроме переадресации существует другой способ изменения стан¬ дартного выполнения ввода и вывода — это установление связи двух процессов через программный канал (pipe), или конвейер (pipeline), при котором выход одно¬ го процесса становится входом для другого. Символом для обозначения про¬ граммного канала является вертикальная черта I. Обычно, если вы хотите использовать выход одного процесса как вход для другого, нужно пройти через окольную процедуру. Пусть, например, у вас есть три небольших текстовых файлараг7_ф part_e upart f. Вы хотите их хранить в системе раздельно, но при выводе на печатающее устройство вам хотелось бы видеть их на одной странице, а не на трех разных страницах. Для этого сначала объедините файлы и сохраните их в некотором четвертом файле: cat part__d part_e part_f > temp file Затем используйте этот новый файл как входной для команды lpr (line print — пе¬ чать строк), которая распечатает его: $ lpr temp_file 1) Более точно, процесс — это выполнение одной или нескольких программ, которые вызываются для раскрытия функций выполняемых команд. Причем речь идет не о машин¬ ных, а о системных командах. Поэтому в литературе такие команды часто называют ма¬ крокомандами. — Прим. ред.
Основные сведения о системе Юникс 45 И наконец, удалите временный файл с помощью команды rm: $ rm temp_file С помощью конвейера вы можете непосредственно связать команды cat и lpr, исключая необходимость во временном файле, например, так: cat part d part_e part_f | lpr Символ программного канала (вертикальная черта) позволяет направить выход от команды cat к команде lpr в качестве ее входа. В противном случае вывод был бы осуществлен либо в файл, либо на экран. Использование программного кана¬ ла обеспечит желаемый результат с помощью одной командной строки, а не трех: три файла будут сначала объединены, а затем результирующий файл выдан на устройство печати. Команды, которые используются с программным каналом, могут содержать обычные опции и обозначения файлов. Например, команда pr (print — печать) вы¬ водит текст на экран. (Причина, по которой эта команда названа print, а не display (вывести на экран), заключается в том, что первоначально терминалами для системы Юникс служили телетайпы, а не видеотерминалы.) В модифициро¬ ванном виде с опцией -4 эта же команда фг -4) выводит текст в четыре колонки. Команда Is (list — список) выдает список файлов вашего каталога. Чтобы вы¬ вести этот список на экран в четыре колонки, вы могли бы связать команды Is и pr через программный канал с помощью вертикальной черты и включить в ко¬ мандную строку опцию -4. Чтобы выводить этот список по пять строк на стра¬ нице и не выдавать при этом заголовок списка и конечное сообщение, в нее сле¬ довало бы включить соответственно опции -15 и -t: Ls | рг -t -15 -4 .excr .profi le a.out asm__progs bin $ c__programs c_progs char.set_6 etc graphs grid z1051 Link.mod z1052 points z1053 termcap text files Это дает на экране хорошее, компактное изображение. В зависимости от чис¬ ла файлов в вашем каталоге вы должны изменять количество строк и столбцов (опции -I5 и -4 в предыдущем примере), но результат будет похожим. (Удосто¬ верьтесь, что произведение числа строк на число столбцов превышает число файлов.) Если добавить опцию -t, можно избавиться от лишней информации на экране. Вы можете образовать также составной конвейер. Например, чтобы распеча¬ тать список файлов на устройстве печати в три колонки, а также вывести его на экран (предполагая, что в вашем каталоге более 150 файлов), можно ввести ко¬ манду: ls | pr -3 | lpr В этой командной строке ls формирует список файлов, pr -3 преобразует его в три колонки, а lpr печатает вновь сформированный список. Имея все команды системы Юникс и возможность создавать конвейер, вы можете строить из них множество новых эффективных команд. Число комбина¬ ций практически бесконечно. Ниже приводится несколько примеров с использо¬
46 Часть I ванием некоторых команд: команды who, выводящей список всех текущих пользо¬ вателей системы; команды sort (сортировать), выполняющей упорядочение строк по алфавиту; команды Is, выводящей список ваших файлов, и команды wc (word count — счет слов), осуществляющей подсчет числа строк, слов и символов в файле. Командная строка $ who | sort $ who | wc $ ls | wc Цепь использования Просмотр списка в алфавитном порядке Подсчет числа текущих пользователей Подсчет числа файлов в вашем каталоге Отметим, что из-за различий в работе команд многие комбинации конвейера, которые можно придумать, невозможно использовать. Например, ни команда who, ни команда Is никогда не могут быть командой, которая получает на входе результат работы предшествующей команды программного канала, так как эти команды берут информацию из системы, а не от некоторого внешнего источника. С другой стороны, команду lpr нельзя использовать на входе программного кана¬ ла, поскольку для ее функционирования требуются входные данные, а сама она выходных данных для последующей команды не создает. Вывод текста на экран В гл. 3 вы узнали, что для вывода текста на экран можно использовать команду cat (concatenate — сцеплять). В этом разделе вы более подробно ознакомитесь с ней и узнаете о других командах, которые тоже можно применять для той же це¬ ли. К ним относятся команды more, head, tail и sp (space). Ввод текста в файп cat Используя концепцию переадресации вывода, с помощью команды cat можно вы¬ полнить ввод простого текста. Для этого надо просто переадресовать вывод в команде cat с экрана на файл. Затем ввести текст, нажав в конце последней его строки CTRL-D, чтобы указать команде cat о завершении ввода. В приведенном ниже примере мы вводим текст в файл с именем enter: _ cat > enter Неге is а short message to show what we can do with the cat command. [Нажмите CTRL-D] $ После этого мы можем вывести на экран только что введенный текст, выпол¬ нив ту же самую команду cat, но без переадресации: $ cat enter Неге is а short message to show what we can do with the cat command. $
Основные сведения о системе Юникс 47 Если в системе Юникс в качестве терминала вы используете микроЭВМ с со¬ ответствующим программным обеспечением связи, то команду cat можно приме¬ нять еще и таким образом, чтобы перехватить текст и запомнить его в одном из ваших собственных дисковых файлов, находящихся вне системы Юникс. (Это действие называется также выгрузкой данных (downloading data). Для этого запу¬ стите процедуру перехвата данных в программе связи, войдите в систему, а за¬ тем выполните команду cat, как для вывода текста на экран. Чтобы переслать текст из вашей микроЭВМ в систему Юникс (т. e. произвести загрузкуданных (uploading data)), войдите в систему, перейдите в нужный каталог и введите командную строку cat, которая переадресует вывод на требуемый файл: cat > micro.text Затем запустите процедуру программы связи, пересылающую содержимое диско¬ вого файла, который должен быть выведен на ваш экран. Когда весь текст пере¬ дан, не забудьте набрать CTRL-D, чтобы указать команде cat на конец передачи. Когда вы таким образом загружаете текст в систему Юникс, то можете завер¬ шить передачу нежелательными двумя пустыми строками. В этом случае не огор¬ чайтесь. Существует программа на языке Си, описанная в гл. 10, которая может помочь вам. Если ее незначительно изменить, она удалит нежелательные строки пробелов. (Эти "незначительные изменения“ состоят в замене 2 на 1 в строке 12.) Вывод текста на экран по частям more Команда more (больше), которая является одним из вариантов команды cat для версии системы Юникс, разработанной в Беркли, тоже выводит текст файла на экран, но не продвигает его непрерывно по экрану, а делает паузы после выдачи каждого полного экрана. При этом на нижней строке экрана она выводит сооб¬ щение типа: —Моте— (6%) В этом состоянии у вас есть несколько альтернатив, подобных следующим четы¬ рем: •для получения следующей строки нажмите клавишу RETURN; •для вывода следующего заполненного экрана нажмите клавишу пробела; •для поиска в файле некоторого текста text введите /texf; •для выхода введите Q. Вывод части файла head tail Пара команд head (заголовок) и tail (хвост) позволяет выводить только начальный или конечный сегмент файла (команда head принадлежит версии системы Юникс, разработанной в Беркли, а команда tail — принадлежит не только этой версии). Обычно будут выводиться десять строк, но с той и другой командой можно задать и другое их число; кроме того, в команде tail вы можете указать длину выводимой части файла в символах (с), строках (I) или блоках (b). (Влок (block) в системе Юникс обычно содержит 512 символов.) Например, чтобы вы-
48 Часть I дать на экран только последние 17 символов файла enter, вы можете ввести сле¬ дующую команду: $ tai 1 -17c enter the cat command. $ Развертывание изображения в строку sp Иногда у вас может быть файл, который содержит длинный список слов, чисел или каких-то других элементов. Если вы попытаетесь его вывести с помощью команды cat, то слова будут расположены только в левой части экрана. Чтобы одновременно видеть большее число элементов списка, вы, вероятно, захотите использовать пустую (правую) часть экрана. В системе Юникс имеется команда с именем sp (space — пространство), которая поможет вам в этом. Если вы переда¬ дите команде sp текст по конвейеру, получите текст развернутым на весь экран. Ниже приведем простой пример, в котором используется уже знакомый вам текст: $ cat enter Неге is а short message to show what we can do with the cat command. [Без команды sp] $ $ cat enter | sp [С командой sp] Here is a short message to show what we can do with the cat command. $ Команда sp располагает элементы в колонки по 8 позиций, как при табуляции, поэтому после слова do вставлен дополнительный пробел. Чтобы одновременно видеть имена всех своих файлов, вы можете совместно выполнить команды Is и sp: Ls | sp P_ current file.1 file.2 file. ..к late.items memo_jan.23 _ _ 3mo_mar.06 notes prep_d36a prep_d36b prep_d36c rep_36d quotes.wrap quotes.build quotes.dwgs »pair store 3 file.4 file.5 garage.saU memo_feb. 12 memo__feb. 17 Дополнительные сведения о работе с файлами Определение содержимого файла file Иногда мы забываем о своих файлах. Мы смотрим на каталог и спрашиваем: ”Что это за файл enter? Когда я его создал?" В большинстве систем Юникс име¬ ется команда с именем file (файл), которая определяет (или по крайней мере пы-
Основные сведения о системе Юникс 49 тается определить) общий тип файла, что позволяет вам очень быстро получить некоторые сведения о нем. Ниже представлены три простых примера: $ fi Le enter enter: English t $ — $ fi le ch.set 6 ch.set _6: ascii $ — $ fi le FOCUS FOCUS: commands $ _ Это совсем немного информации о вашем файле (и не всегда правильной), но по крайней мере это кое-что, чтобы начать работать. Сортировка файла sort Сортировка позволяет расположить строки текста по порядку. Вероятно, это наи¬ более общая форма обработки текста. Пусть, например, вы выполнили команду cat, чтобы ввести два файла с именами fruits^ и animals1 2* со следующим содер¬ жимым: f $Jcat > fruits $ cat > animals bananas horses oranges cats apples dogs cherries bi rds pears li zards [CTRL-D] [CTRL-D] $ Для сортировки файла fruits и вывода результата на экран используйте ко¬ манду sort (сортировать) с передачей упорядоченного файла через программный канал команде sp: $|sort fruits | sp appLes bananas cherries $ oranges pears Чтобы сделать то же самое с файлом animals, снова используйте те же коман¬ ды: sort animals | sp $ bi rds $ cats dogs horses h*zards 1)Файл ”плоды“ включает следующие названия: бананы, апельсины, яблоки, вишни, гру¬ ши. — Прим, перев. 2)Файл ”животные“ включает следующие названия: лошади, кошки, собаки, птицы, яще¬ рицы, позже в него добавляются еноты. — Прим, перев.
50 Часть I Как уже говорилось выше, вы можете таким же образом упорядочить список пользователей системы: $|who | sort dave tty11 Feb 2 15:56 elaine tty04 Feb 3 09:58 manny tty07 Feb 3 08:05 $ _ Более подробно команда sort описана в гл. 18. Работа с повторяющимися строками uniq Рассмотрим простую задачу, которую часто приходится решать после сортировки списка элементов. Допустим, вы хотите сохранить список различных животных, которые приходят к вам во двор, за какой-то отрезок времени. Вы храните этот список в системе Юникс в некотором файле. В конце одного из насыщенных со¬ бытиями дней вы садитесь за свой терминал и добавляете к вашему файлу animals следующее: $ |cat » animals bi rds raccoons dogs bi rds cats [Напомним, что два знака>>служат для добавления к тексту] $ [Нажмите CTRL-D] Теперь наступил момент, которого вы ждали: время сортировать список. Ис¬ пользуйте команду sort (но пока без команды sp), и вы получите список слева. Ес¬ ли вы не хотите оставлять в списке повторяющиеся названия, можете передать этот список через программный канал команде с именем uniq (unique — уникаль¬ ный), чтобы получить новый список, показанный справа: $[sort animals bi rds bi rds bi rds cats cats dogs dogs horses lizards raccoons $ $ sort animals | uniq bi rds cats dogs horses li zards raccoons $ Таким образом, команда uniq в своей простейшей форме сокращает сортируе¬ мый список за счет включения каждого элемента в результирующий список толь-
Основные сведения о системе Юникс 51 ко один раз независимо от того, сколько раз он встречается в первоначальном списке. Команда uniq имеет несколько опций, одна из которых (<) служит для указа¬ ния в результирующем списке перед каждым элементом числа его появлений в первоначальном списке. Вот пример команды uniq с опцией -с: $|sort animals | uniq -с bi rds cats dogs horses L i zards raccoons $ Подготовка текста дпя обработки prep Если у вас есть исходный текст из предложений и абзацев, а вы хотели бы рабо¬ тать с отдельными словами текста, то чтобы поместить каждое слово на отдель¬ ной строке, можете использовать команду prep (prepare — готовить), если она имеется в вашей системе. Ниже приведен пример, использующий новый файл words: $ cat > words The more you study, the more you learn. [CTRL-D]/ $ |prep words the more you study the more you Learn $ [Слова выводятся без знаков препинания строчными буквами] и набраны Сортировку этого списка можно провести также с помощью команды uniq, чтобы определить, сколько раз каждое слово встречается в файле. Для этого сначала поместите каждое слово на отдельную строку с помощью команды prep; упорядочите список командой sort; затем получите частоту появления слов с по¬ мощью команды uniq с опцией -с (count): $ prep words | sort | uniq -с 1 learn 2 more 1 study 2 the 2 you $
52 Часть I Подсчет строк, слов и символов в файле wc Иногда необходимо иметь некоторые статистические данные о файле. Если вы, например, написали программу и хотите узнать, сколько она содержит строк, или если написали статью и хотите узнать, сколько в ней слов, то такие сведения — о количестве строк, слов и символов в файле (именно в таком порядке) — дает команда wc (word count — счет слов). Предполагается, что слова отделяются друг от друга или знаками препинания, или пробелами, или знаками табуляции или расположены на разных строках. Например, чтобы получить все эти данные о файле enter, введите следующую команду: wc enter 15 69 enter Если вы хотите знать что-нибудь одно из трех (или число строк, или число слов, или число символов), можете использовать следующие опции команды wc: -I (только строки); -w (только слова); с (только символы). Ниже приводятся примеры команд для получения отдельно каждого из пара¬ метров: wc -1 enter 3 enter [3 строки в файле enter ] wc -w enter 15 enter [15 слов в файле enter] wc -с enter 69 enter [69 символов в файле enter] $ Поиск в файле по модели grep Если вы хотите найти в файле некоторое ключевое слово или фразу, используй¬ те команду grep. В системе Юникс любая последовательность символов, которую вы отыскиваете, называется "моделью поиска" или "регулярным выражением", (grep — сокращение, соответствующее выражению "globally find regular expres¬ sions and print" — глобальный поиск регулярных выражений и печать.) Авторы системы Юникс не захотели назвать эту командуд/геар, а ввели сокращение grep. Например, чтобы вывести все строки файла enter, которые содержат буквы cat, можете выполнить команду: $|grepcat enter with the cat command. [Тдлькооднастрока] $ Если вы хотите узнать, кто входит в систему с терминала tty15, можете ис¬ пользовать команду: $[who | grep tty15 manny $ tty15 Feb 3 10:05
Основные сведения о системе Юникс 53 Наконец, пусть у вас есть файл с именем phone.list, который содержит тыся¬ чи имен, адресов и номеров телефонов служащих вашей фирмы. Предположим, вы пытаетесь найти эти данные для некоего служащего по имени Ted, который работает в конторе в Лос-Анджелесе. Для этого используйте команду grep в сле¬ дующей командной строке: grepTed phone.list | grep *Los Angeles' Ted Peterson 1200 Fairfax Blvd.,Los Angeles, CA 90104 (213) 657-1000 $ Эта командная строка демонстрирует передачу результата по программному каналу между двумя одинаковыми командами. Заметим, что название города Los Angeles выделено в кавычках, так как оно состоит из двух отдельных слов. Более подробно команда grep рассматривается в гл. 18. Поиск слов с орфографическими ошибками spell С помощью команды spell (писать слова по буквам) вы можете проверить право¬ писание слов в файле путем их сравнения с образцами, записанными в большом непосредственно доступном машинном словаре. При этом вы можете проверить правильность и производных от слов, находящихся в этом словаре. Пусть, напри¬ мер, у вас есть файл с именем lines, который содержит следующий текст: $ cat > lines Now is the tyme for all good men to come to the ade of there country. [CTRL-D] $ Для проверки этого файла выполните строку: $ spell lines tyme ade $ Заметим, что слово there не печатается, хотя и неверно используется. Про- грамма spell в состоянии проверить только правописание слова, но не может ука¬ зать, правильно ли оно применяется. Построчное сравнение файлов diff Часто возможны случаи, когда исходная и модифицированная копии вашего файла входят в один каталог. Вы хотите, например, узнать: какая из них более поздняя и являются ли они одинаковыми? В этом случае вам может помочь ко¬ манда diff (differ — отличаться). Чтобы продемонстрировать, как она работает, создадим простой файл с именем wildlife.1^, затем модифицируем его, чтобы по- 11)Файл wildlife.1 содержит следующие названия: антилопа, медведь, койот, олень, лось. — Прим, перев.
54 Часть I лучить второй файл, названный wildlife.2^: 1 2 3 4 5 $ cat > wildlife.1 antelope bear coyote deer elk $ |cat > wi Ldlife.2 1 anteLope 2 buffalo 3 coyote 4 eLk 5 fox Сравнивая эти два файла с помощью команды diff, мы получаем результат, который указывает на отличия второго файла от первого: diff wildlife.1 wildlife.2 2c2 [Строка 2 изменена: < 2 bear • — Первый файл (<) содержит 2bear > 2 buffaLo • — Второй файл (>) содержит 2buffalo] 4,5 с 4,5 [Строки 4 и 5 изменены: < 4 deer • — Строка 4 первого файла — 4 < 5 e L k • — Строка 5 первого файла — 5 elk > 4 e L k • — Строка 4 второго файла — 4 elk > 5 fox • — Строка 5 второго файла — 5fox] $ Для указания отличия в файлах программа diff использует символ с, исключе¬ ния — символ d, добавления — символ а вместе со знаком < для определения строки в первом файле и знаком > для указания строки во втором файле. Дефи¬ сы (- - -) вставляются в том случае, когда строка первого файла совпадает со строкой второго файла. Команда diff имеет несколько опций, таких, как опция игнорирования пробе¬ лов в обоих файлах (-b) и опция (-e) вывода списка команд редактора ed для преобразования первого файла во второй. А теперь мы рассмотрим другую ко¬ манду сравнения файлов. Вывод общих строк двух файлов comm Чтобы получить другой тип сведений о различиях между двумя файлами, следу¬ ет выполнить команду comm (common — общий). Эта команда выводит на экран три колонки: в первой — строки первого файла, которых нет во втором; во вто¬ рой — строки второго файла, которых нет в первом; в третьей — строки, общие для обоих файлов. Ниже показан вывод для команды comm и файлов wildlife.1 и wildlife2: $|comm wildlife.1 wildMfe.2 1 antelope 2 bear 2 buffalo [Общая для обоих файлов] [Только для 1-го файла] [Только для 2-го файла] 1) Файл wildlife.2 содержит следующие названия: антилопа, буйвол, койот, лось, лиса. — Прим, перев.
Основные сведения о системе Юникс 55 4 deer 5 eLk $ 4 elk 5 fox 3 coyote [Общая для обоих файлов] [Только для 1-го файла] [Только для 2-го файла] [Только для 1-го файла] [Только для 2-го файла] Как вы можете заметить, вывод в три колонки очень нагляден. (Если вы при¬ смотритесь внимательнее, то обнаружите, что команда comm допустила ошибку: она сначала указала, что строка elk есть только в файле wi1dlife.1, а затем — что только в файле wildlife2.) Команда comm позволяет подавлять вывод одной (или двух) колонок. Для этого используются опции: -1 для подавления вывода пер¬ вой колонки, -2 — второй колонки и -3 — третьей. Допускаются комбинации опций типа -13 для подавления вывода двух колонок (здесь первой и третьей). Ниже показан пример того, как вы можете задать команду вывода только общих строк обоих файлов (третья колонка): $ comm -12 wildlife.1 wildlife.2 1 anteLope [Общая для обоих файлов] 3 coyote [Общая для обоих файлов] [Снова упущена строка elk] $ Для сравнения программных файлов используется также команда cmp (compare — сравнивать), которая выполняет посимвольное сравнение двух фай¬ лов (байт за байтом). Перевод символов tr Возможны случаи, когда вам необходимо заменить одни символы файла на дру¬ гие, в каком бы месте файла они не находились. Пусть, например, для нумерации шагов написанной вами процедуры вы использовали цифры. Затем вы решили (или вас попросили) вместо цифр использовать буквы алфавита. С помощью ко¬ манды tr (translate — переводить) это сделать достаточно просто. Пусть есть файл: _ cat > five, steps . Turn on the machine. . Start the program. . Request the P option. . End the program. . Turn off the machine. [CTRL-D] $ Чтобы выполнить описанный перевод, наберите имя команды, пробел, набор символов, который нужно перевести, опять пробел, а затем набор символов, в ко¬ торый переводятся символы из первого набора (в требуемом порядке). При этом используйте переадресацию ввода, чтобы ввести данные из файла five.steps:
56 Часть I $ |tr 12345 abcde < five.steps a. Turn on the machine. b. Start the program. c. Request the P option. d. End the program. e. Turn off the machine. $ _ Эта команда tr перевела 1 в а, 2 в b, 3 в с и т. д. Во многих системах, чтобы сделать то же самое, эта команда допускает перечисление не всех переводимых символов, а указание их диапазона: $ tr 1-5 a-e < five.steps a. b. c. d. e. $ Turn on the machine. Start the program. Request the P option. End the program. Turn off the machine. Используя эту же возможность для замены всех строчных букв на прописные, вы можете выполнить следующую командуТг: $ 1. 2. 3. 4. 5. $ tr a-z A-Z < five.steps TURN ON THE MACHINE. START THE PROGRAM. REQUEST THE P OPTION. END THE PROGRAM. TURN OFF THE MACHINE. Здесь команда tr переводит а в А, b в В, с в С и т. д. Если ваша система не по¬ зволяет указывать диапазон символов, вы можете записать диапазоны в квадрат¬ ных скобках, которые в свою очередь заключить в двойные кавычки, чтобы эти скобки не рассматривались как части наборов символов. Например: $ tr "[a-z] [A-Z]" < five.steps 1. 2. 3. 4. 5. $ TURN ON THE MACHINE. START THE PROGRAM. REQUEST THE P OPTION. END THE PROGRAM. TURN OFF THE MACHINE. Команду tr можно использовать для исключения символов, если включить в нее опцию <i (delete). Например, для исключения номеров шагов в тексте мы мо¬ гли бы использовать следующую команду: $ tr -d 12345 < five.steps Turn on the machine. Start the program.
Основные сведения о системе Юникс 57 . Request the P option. . End the program. . Turn off the machine. $ Если же мы хотим исключить пояснения, а оставить номера шагов, то можем включить и опцию -с (complement): tr -cd 12345 < five.steps 12345$ Здесь цифры и знак-подсказка вводятся на одной строке потому, что симво¬ лы, отделяющие строки друг от друга (называемые в системе Юникс newlines1*), удалены из текста вместе с обычными видимыми символами. Ниже показана ана¬ логичная командная строка. Объясните, что происходит при ее выполнении: 12345$ [tr -cd A-Z < five.steps TSRPET$ В обоих последних примерах две опции с и d помещены за одним и тем же знаком минус. В системе Юникс такие опции называются связанными опциями (bundling options). Не все команды системы Юникс допускают связки опций. Ко¬ манда tr имеет также опцию squeeze, с помощью которой можно сжать символы. Использование печатающих устройств Для распечатки содержимого файла на системном печатающем устройстве мож¬ но использовать команду lpr (line print — печать строк). В действительности файл помещается в очередь и не обязательно будет немедленно распечатан, что зави¬ сит от системного запроса на печать. Например, для распечатки файла section 4 можно использовать команду: $ $ lpr section 4 Разновидности команды lpr С помощью ряда средств, с которыми вы ознакомились в этой главе, можно сде¬ лать большее, чем просто вывод файла на печать. Вы можете, например, распе¬ чатать последовательность файлов: $ $ Если передать текст файла по программному каналу от команды pr команде lpr, можно выполнить средствами команды pr форматирование файла перед его печатью. Например, чтобы разбить текст на страницы и поместить в две колонки до печати, можно использовать командную строку: $ $ pr -2 text_5 | lpr lpr section__1 section_2 section__3 1)Символ newlines или NL эквивалентен знаку "перевод строки“ (ПС) и имеет восЬме- ричный код 012. — Прим, перев.
58 Часть I Если использовать два программных канала — один от команды sort к коман¬ де pr, а другой от pr к lpr, — можно перед печатью файла сначала упорядочить его, а потом разделить на страницы: $ $ sort data__15 | pr | Lpr Опции команды lpr В команде lpr из имеющихся опций особенно полезными могут быть две. Опция -с (сору) создает копию подлежащего распечатке файла (для предотвращения поте¬ ри файла в очереди): $ $ Опция -m (mail) (если допустима на вашей системе) извещает вас сообщением о завершении обработки вашего запроса на печать: $ $ Lpr -m section 5 Lpr -с section_5 Определение содержимого очереди на печать Is -I В многопользовательских системах типа Юникс системные ресурсы (типа печата¬ ющего устройства или накопителя на магнитных дисках) распределяются между пользователями. Поэтому система должна иметь процедуры для организации та¬ кого разделения. Например, всякий раз, когда вы выполняете команду lpr для распечатки файла, система помещает имя этого файла в очередь. Это аналогич¬ но ожиданию в очереди в банке. Имена файлов продвигаются в очереди по мере распечатки файлов. Когда файл напечатан, его имя удаляется из очереди. Оче¬ редь хранится в каталоге, который обычно имеет имя /usr/spool/lpd. Чтобы опре¬ делить, какой файл из очереди в текущий момент распечатывается, достаточно вывести содержимое этого каталога на экран, используя команду Is (list) с опци¬ ей -I (long) для получения более подробной информации: $ Ls -L /usr/spooL/Lpd totaL 40 -rw-rw-r— 1 robin 19658 JuL -rw-rw-r— 1 robin 50 JuL 1 robin 0 JuL 3 09:39 cfA25956 3 09:39 dfA25956 3 09:39 Lock Возможно, в вашей системе можно использовать и более короткую команду. Проверьте это с администратором системы. Краткое изложение главы 4 В этой главе вы ознакомились с командными строками, переадресацией ввода- вывода, конвейерами, командами для отображения текста, работы с файлами и использования печатающих устройств.
Основные сведения о системе Юникс 59 ПОСТРОЕНИЕ комАндных строк. Чтобы запустить процесс в системе Юникс, набе¬ рите командную строку и нажмите клавишу RETURN. Команда может содержать или только саму команду, или команду, снабженную модификаторами. Переадресация ввода-вывода и конвейеры ПЕРЕАДРЕСАЦИЯ, ОБЩИЕ положЕния. Система Юникс (если вы не установили по- другому характеристики системы) рассматривает клавиатуру вашего терминала как свое стандартное устройство ввода, а его экран как свое стандартное уст¬ ройство вывода. Но вы можете переадресовать ввод или вывод куда-нибудь в другое место. ПЕРЕАДРЕСАЦия вводА. Чтобы команда системы Юникс вводила данные из фай¬ ла, а не с вашей клавиатуры, поставьте перед именем файла знак <. ПЕРЕАДРЕСАЦия выводА. Чтобы команда системы Юникс записывала выход¬ ные данные в файл, а не выдавала их на экран, поставьте перед именем файла знак >. Если файл не существует, он будет создан; если существует, его содержи¬ мое будет изменено. Чтобы дополнить содержимое выходного файла, а не заменять его полнос¬ тью на новое, поставьте перед именем файла пару знаков >>. КонвЕйЕРы. Для связи двух процессов, когда выход одного процесса становит¬ ся входом второго, используйте между командами вертикальную черту (можно в сочетании с пробелами). Вывод текста на экран ПРИМЕНЕНИЕ комАнды cat. Команду cat можно использовать для ввода текста в файл, выгрузки файла на микроЭВМ вне системы Юникс или его загрузки в си¬ стему Юникс. ДругиЕ ПРОГРАММЫ отоБРАЖЕния. Если вы работаете на системе Юникс версии Беркли, то для вывода текста с задержкой после каждого вывода каждого экра¬ на используйте команду more, для вывода только первых строк файла — коман¬ ду head, а только последних строк — команду tail. Дополнительные сведения о работе с файлами ОПРЕДЕЛЕНИЕ содЕРЖимого ФАЙЛА. Для определения рода символов, находящихся в вашем файле, выполните команду file. СортировкА ФАЙЛА. Для упорядочения файла по строкам используйте команду sort с указанием имени файла. Как и для многих других команд, результирующий файл команды sort может быть переадресован на новый файл. Кроме того, команда sort может получать данные со стандартного устройства ввода (клавиатуры) или от другой команды через программный канал. РАБОТА с повторяющимися строкАМИ. Для устранения повторяющихся строк в сортируемом списке используйте команду uniq. Опция с в этой команде дает число повторений элемента в исходном списке. ПодготовкА ТЕКСТА для ОБРАБОТКИ. Чтобы поместить каждое слово текста файла для последующей обработки на отдельную строку, используйте команду prep. Оп¬ ция <1 в этой команде устанавливает перед каждым словом его номер. ПОДСЧЕТ СТРОК, СЛОВ И СИМВОЛОВ В ФАЙЛЕ. Чтобы получить общее число строк, слов и символов в файле, используйте команду wc либо без опций для вывода
60 Часть I всех трех характеристик, либо с одной из трех опций -/, -w, -с, если необходимо вывести только одну из характеристик. (Допускаются комбинации опций типа -lw и -wc.) Поиск в ФАйЛЕ по модЕли. Для поиска в файле по модели используйте команду grep, за которой следует модель поиска, а затем имя файла. Команда grep может получать данные через программный канал от другой команды. В этом случае имя файла становится ненужным. Поиск слов с оРФОГРАФИЧЕСкими ошиБКАМИ. Чтобы получить список слов файла, содержащих орфографические ошибки, используйте команду spell, за которой следует имя файла. СРАВНЕНИЕ двух ФАйлов. Для построчного сравнения двух файлов используйте команду diff. (Существуют еще программа с именем diff3, которая сравнивает од¬ новременно три файла, и программа, называемая cmp, которая выполняет посим¬ вольное сравнение двух файлов.) ОПРЕДЕЛЕНИЕ ОБщих строк. Чтобы определить, какие строки являются одинако¬ выми в двух файлах, а какие содержатся только в каждом из них, используйте команду comm (common). ПЕРЕВОД символов. Для перевода одного набора символов в другой, используй¬ те команду tr, которую можно применять также для исключения символов. Использование печатающих устройств ОсновнАЯ комАндА. Чтобы послать файл на системное устройство печати, ис¬ пользуйте команду lpr с именем файла (или именами файлов). РАЗНовидности комАнды. Для форматирования файла перед печатью исполь¬ зуйте некоторые другие команды и программный канал между ними и командой lpr. Опции комАнды. Опция с (сору) требует от команды lpr создать копию файла перед его распечаткой; опция -m (mail) требует от команды lpr известить вас, ког¬ да печать завершится. ОПРЕДЕЛЕНИЕ содЕРЖимого очЕРЕДи нА ПЕЧАТЬ. Чтобы определить, какие файлы находятся в очереди на печать, проверяйте каталог /usr/spool/lpd с помощью ко¬ манды Is -I. Глава 5. Связь с системой Юникс В этой главе мы познакомимся с тем, как осуществляется взаимодействие поль¬ зователей между собой в рамках одной системы Юникс и в различных системах. Сначала мы рассмотрим общение с пользователями вашей системы, а затем обсу¬ дим взаимодействие с другими системами Юникс. Общение с другими пользователями Система Юникс предоставляет три возможности для организации различных форм общения пользователей внутри одной системы: электронная почта, автома¬ тическая служба напоминания и прямые сообщения.
Основные сведения о системе Юникс 61 Посылка почты mail Чтобы переслать электронную почту другому пользователю вашей системы, ис¬ пользуйте команду mail. Наберитета/7, пробел, идентификатор другого пользова¬ теля и нажмите RETURN. Например, чтобы послать сообщение пользователю с идентификатором Janice, выполните команду: mail janice После того как вы нажали клавишу RETURN, система Юникс (для версий Беркли) может ответить подсказкой Subject на следующей строке. Если это так, наберите заголовок вашего сообщения, нажмите RETURN и начинайте вводить текст. После последней строки текста поставьте точку и нажмите клавишу RETURN, чтобы за¬ кончить сообщение и вернуться к знаку-подсказке интерпретатора shell. Если подсказки Subject нет, сразу же начинайте ввод вашего сообщения. Например: $ mail ralph laura peter sara Subject:| Design Review Meeting [Эта строка может не появляться] There will be a meeting at 2:0i of the Rattlesnake. Bring the D pm today to review the design specifications you received from Engineering last week. $ Каждый получатель будет уведомлен при входе в систему о наличии этого со¬ общения. Получение почты mail Если какой-то пользователь отправил вам сообщение по почте, то сразу же после входа в систему вы увидите сообщение You have mai 1 Оно означает, что вы получили почтовое сообщение. Чтобы определить содержа¬ ние сообщения, введите команду mail без каких-либо аргументов: mai 1 По этой команде будут выведены заголовки каждого из сообщений, которые вы получили. Если вы нажмете клавишу RETURN, то на экране увидите текст перво¬ го сообщения. Затем, когда вы готовы читать следующее сообщение, каждый раз нажимайте клавишу RETURN (или нажмитесУ, чтобы удалить уже прочитанное ва¬ ми сообщение, или p, чтобы повторить вывод сообщения). Существует много и других опций (даже слишком много, чтобы рассматривать их здесь). Поэтому за информацией об этих опциях отсылаем к Руководству пользователя системы Юникс. Одним из способов реализации механизма напоминания является посылка со¬ общения самому себе с помощью команды mail. Например: $ mai1 robin Subject: Self-Improvement [Эта строка может не появляться] Avoid falling asleep when Wally starts talking about his pet frog, avoid talking in a loud, boisterous voice, and avoid arguments. [Завершает сообщение точка].
62 Часть I Автоматическая служба напоминания calendar Другой способ напомнить себе о некоторых вещах — использовать автоматиче¬ скую службу напоминания, которую система Юникс предоставляет через команду calendar (календарь). Периодически (обычно ежедневно) система Юникс с по¬ мощью этой команды проверяет все начальные каталоги пользователей на нали¬ чие в них файла с именем calendar, содержимое которого может быть примерно таким: Маг 21 Planning meeting at 9:30 in the conference room Apr 17 Jennifer's wedding in Hendersonville Apr 28 Awards dinner at the Blackjack Inn May 3 Presidential primary Допустимы и другие формы дат, например March 21 и 3/21. Команда calendar вы¬ бирает из этого файла каждую строку, которая содержит сегодняшнее или завт¬ рашнее число, и пересылает ее вам. Вы и сами можете вызвать команду calendar: i calendar Система Юникс отыщет ваш начальный каталог для файла с именем calendar и выберет из него любые подходящие элементы, чтобы вывести их вам. Прямая связь с пользователем write Команда write (писать) позволяет вам посылать сообщение непосредственно на терминал другого пользователя, где оно сразу же появляется на экране. Ниже по¬ казан пример выполнения команды write: $ [write paul | fHow are you doing on your project? -о- [CTRL—D — на экране не отображается] $ Ниже приведен текст, который увидит пользователь с именем Paul на экране сразу же после выполнения этой команды: Message from robin tty07 How are you doing on your project? -o- EOF В этом месте Paul сам может ответить командой write и начать диалог ”терминал—терминал“: $Jwrite robin It's about two-thirds completed. How about yours? -o- [CTRL—D — на экране не отображается] Чтобы избежать путаницы во время диалога, вы должны установить простой протокол, чтобы другая сторона Знала, когда вы завершили ввод своего текущего сообщения. Например, каждый пользователь мог бы вводить символы -о- после каждого сообщения и -oo- при окончании диалога. Если вы относитесь к людям, любящим и понимающим шутку, вы включите в свой актив команду write. Однако существует команда с именем mesg (message —
Основные сведения о системе Юникс 63 сообщение), которая позволяет тем, кто не особенно любит шутки, не пропускать на свой терминал сообщения, посланные по команде write. Им достаточно только добавить опцию n (no), и шутка исчезает: $| mesg n $ _ Чтобы вновь разрешить поступление сообщений от команды write, добавьте опцию у (yes) в команде mesg: mesg у Наконец, чтобы определить, разрешено ли в данный момент поступление на ваш терминал сообщений от других пользователей по команде write или запреще¬ но, введите команду mesg без аргументов: $ mesg 0 yes 1 no 2 еггог [Возможны три ответа] Общение с пользователями вне системы Юникс Связь с абонентом вне вашей системы Юникс вы можете установить с помощью одной из двух команд: cu (call up) (вызвать по телефону) и uucp (UNIX-to-UNIX сору — копирование из системы Юникс в систему Юникс). До того как эти коман¬ ды можно будет использовать, администратор вашей системы должен сформиро¬ вать некоторые системные файлы и выполнить физическое соединение систем необходимыми линиями связи. Мы рассмотрим обе эти команды. Вызов абонента вне вашей системы Юникс cu Команда cu (call up) позволяет устанавливать связь по телефонной линии путем набора номера или прямо по проводной линии и общаться с другой системой Юникс, с терминалом и с ЭВМ, на которой используется другая операционная си¬ стема. Если связь установлена, вы можете вести диалог так, как будто ваш терминал соединен непосредственно с другой системой, и передавать файлы в обоих на¬ правлениях. Если, например, некоторая система имеет телефонный номер 345- 6000 и с обеих сторон установлена скорость передачи 1200 бит/с, то для органи¬ зации связи с этой системой вы можете ввести такую команду: cu 3456000 -s 1200 При установлении связи вы, возможно, увидите у себя на экране следующее сообщение: Login: Теперь вы можете войти в другую систему таким же образом, как и в свою собственную. Проделав это, с помощью команды cu вы можете послать в нее
64 Часть I файл, например, с именем message: -<message Если вы связываетесь с другой системой Юникс, в обеих системах команда ssty (set teletype [terminal]) определяет одни и те же символы для удаления (erase) и уничтожения (kill), а команда cat работоспособна. Другим способом пересылки файла message другой системе является ввод следующей команды: -%put message Если вы связаны с другой системой Юникс и команды echo (эхо) и tee (трой¬ ник) имеются в обеих системах, вы можете скопировать файл из другой системы в свой рабочий каталог с помощью команды: -%take reply Чтобы завершить свой диалог с другой системой, введите что-нибудь одно: ED -CTRL-D Копирование из одной системы Юникс в другую uucp В гл. 3 была рассмотрена команда cp, которую можно использовать для копиро¬ вания файла из вашего рабочего или какого-либо другого каталога. Подобная команда с именем uucp (UNIX-to-UNIX сору) существует и для копирования фай¬ ла из одной системы Юникс в другую. Так, если две микроЭВМ, называемые CATFISH и MOONDOG, входят в одну и ту же сеть, то пользователь на микроЭВМ CATFISH может выполнить, например, следующую команду: $ $ uucp Latest MOONDOG!/usr/robin/news Эта команда возьмет файл с именем /usr/leslie/latest на микроЭВМ CATFISH (предполагая, что /usr/leslie является текущим каталогом) и создаст его копию под именем /usr/robin/news на MOONDOG. Восклицательный знак ! используется для отделения имени микроЭВМ от имени файла. В других отношениях команда uucp идентична команде cp. Отметим, что если вы используете интерпретатор C-shell, то необходимо вводить знак \ перед каждым восклицательным знаком, напри¬ мер: % % uucp Latest M00ND0GX!/usr/robin/news Если вы не знаете точного имени каталога получателя, перед его именем мо¬ жете использовать знак~, чтобы указать команде uucp на необходимость поиска каталога: $ uucp latest MOONDOG!-robin/news
Основные сведения о системе Юникс 65 Для того чтобы команда uucp после копирования файла послала сообщение пользователю-отправителю, включите в командную строку uucp опцию -m: $ $ Чтобы эта команда извещала еще и пользователя-получателя о завершении ко¬ пирования, добавьте опцию -n вместе с именем этого пользователя (если эта оп¬ ция допустима на вашей системе): uucp -m Latest MOONDOG!-robin/news $ $ В приведенном ниже примере пользователь, который вошел в систему на мик- роЭВМ MOONDOG, передает все файлы с именами, содержащими на конце суф¬ фикс .c, в каталог под именем /usr/leslie на микроЭВМ CATFISH. (Поскольку ис¬ ходные программы на языке СИ имеют имена типа list.c, post.c, enter.c и т. д., этот пользователь пересылает в рабочий каталог пользователя на CATFISH все такие программы.) S $ $ Так как пользователь, выполнявший эту команду, вошел в систему на микро¬ ЭВМ MOONDOG до запуска команды, ему не надо было набирать в этой команде MOONDOG! Однако использование MOONDOG\*.c вместо *.с тоже правильно. (По¬ казанная здесь конструкция с метасимволом возможна не на всех системах Юникс.) Команда uucp является только одной из семейства команд системы Юникс. Другим представителем этого семейства служит команда uux (UNIX-to-UNIX execu¬ te — выполнение из системы Юникс в систему Юникс), с помощью которой мож¬ но выполнять команды на другой ЭВМ сети. Например, чтобы выполнить форма¬ тирование содержимого файла с именем raw.text и затем его распечатку на мик¬ роЭВМ MOONDOG, можно выполнить на другой ЭВМ сети следующую команду: uucp *.с CATFISH!/usr/LesLie uucp -m -nrobin Latest MOONDOG!-robin/news $ $ Эта командная строка очень похожа на командную строку, которая выполня¬ ет эту же функцию на вашей собственной системе. Отличие заключается в нали¬ чии в ней команды uux, дефиса, имени другой ЭВМ и восклицательного знака. (Дефис указывает команде uux, что необходимо получить данные по программно¬ му каналу и переслать их на другую систему.) Выполнение таких команд довольно просто при наличии сети, но задача со¬ здания такой сети намного сложнее. К сожалению, в данной книге мы не можем останавливаться на этом вопросе. Мы дали лишь представление о сетевых ко¬ мандах и некоторых их возможностях. Отметим, что сеть, допускающая выполне¬ ние команды uucp и объединяющая более 3000 городов, связана с другими сетя¬ ми, такими, как Ethernet и ARPANET. рг -2 raw.text | uux - MOONDOG!Lpr 3-771
66 Часть I Шифрование информации crypt Если у вас есть информация, которую вы хотели бы сохранить в секрете, можете ее зашифровать с помощью команды crypt (cryptic — сокровенный). В общем слу¬ чае программа шифровки берет ваш первоначальный текст (чистый текст), преоб¬ разует его совместно с последовательностью символов (ключом, или паролем) и формирует зашифрованную версию первоначального текста (шифрованный текст). Для восстановления первоначального текста вы должны запомнить ключ (или записать его). Шифрование файла Прежде всего необходим текстовый файл. С помощью команды cat введем сле¬ дующий текст: $| cat > remark 11I wouLd not like to make а value judgment on that other than to say that I have no comment.1' $ [CTRL-D для завершения текста] Чтобы действительно зашифровать текст, введем команду crypt, на которую система Юникс немедленно запросит ключ. Пусть ключом будет слово convolution: p crypt < remark > remark.crypt Enter key:| convolution [Вы не увидите ключ на экране] В этой командной строке используется переадресация и ввода и вывода. Ко¬ манда crypt берет исходный текст из файла, который вы только что сформирова¬ ли {emark), и пересылает зашифрованный текст в файл с именем remark.crypt. Следующим логичным шагом является удаление первоначального файла гетагк\ в противном случае не имеет смысла его зашифровывать: $ rm remark $ Не поддавайтесь любопытству и не пытайтесь взглянуть на файл remark.crypt. Вы "приведете в замешательство“ свой терминал, который, возможно, будет из¬ давать звуковой сигнал и выводить бессмысленность, пытаясь прочитать содер¬ жимое файла. Чтобы позднее увидеть чистый текст на экране, снова выполните команду crypt с тем же ключом: crypt < remark.crypt $ Enter key^convolution '' I would not other than to [Ключ не появится на экране] TTke to make а value judgment on that say that I have no comment.'' $
Основные сведения о системе Юникс 67 Для последующейраспечатки чистого текста выполните команду crypt с тем же ключом, что и ранее, посылая текст через конвейер от команды pr к команде lpr crypt < remark.crypt | рг | Lpr $_ Enter key:|convolution f $ [Ключ не появится на экране] Замечания по шифрованию файпов Секретность зашифрованного файла в большой степени зависит от неуязвимости выбранного вами ключа. В нашем простом примере мы сделали действительно не лучший выбор. Если вы на самом деле хотите, чтобы ваши зашифрованные фай¬ лы были надежно защищены, вам нужно в качестве ключа выбрать сложную строку символов, которая не может быть легко определена. Ниже приведены два хороших варианта: H7u_%3Sa:Ym5-x#p ,6gU*W1+ce5Q'')TNv;Kz Хотя это и так понятно, но мы все же заметим следующее: если вы беспокои¬ тесь о своих зашифрованных файлах, не храните свой ключ где-нибудь в систе¬ ме Юникс. Запомните его или запишите на листке бумаги. Оба основных редактора системы Юникс (ed и vi) имеют средства для работы с зашифрованными файлами. Некоторые основные понятия теории связи Если вы водите автоМЬбиль, вам трудно обойтись без таких терминов, как диско¬ вые тормоза, коробка передач, генератор и т. д. Аналогично, если вы собираетесь использовать ЭВМ, то можете столкнуться с тем, что испытываете затруднения при использовании новых терминов. Большинство таких терминов относится к области связи. Ниже рассмотрены некоторые основные понятия. Единицы информации Наименьшей единицей информации, с которой работает ЭВМ, является двоичная цифра (или бит), принимающая одно из двух значений: 1 или 0 на языке програм¬ мистов, высокий или низкий уровень на языке схемотехников. В любом случае 8бит образуют байт, который является обычно единицей хранения информации в ЭВМ. Байт соответствует одному символу (текста, данных или программы). Внутри машины информация пересылается группами бит, зависящими от раз¬ рядности ЭВМ. Для большинства микроЭВМ эти группы составляют 8, 16 или 32бит. Из ЭВМ информация может пересылаться либо группами бит (параллель¬ ная передача), либо бит за битом (последовательная передача). Связь с логическими устройствами ЭВМ постоянно что-либо передает. В любой машине значительная часть времени работы тратится на передачу сообщений между различными устройствами. По отношению к ЭВМ связанные с ней накопители на магнитных дисках, печатаю- з*
68 Часть I щие устройства и терминалы являются внешними, или периферийными, устройст¬ вами. Поэтому должно быть такое устройство, которое объединяло бы их вместе, и должен быть единый способ обмена сообщениями между ними. Любое устройство, находящееся на небольшом расстоянии от ЭВМ, обычно может быть связано с ней кабелем (параллельной или последовательной переда¬ чи). Большинство ЭВМ и периферийных устройств предусматривают соединение с линией связи с помощью кабельных разъемов (коннекторов). Один из типов обычно используемых последовательных коннекторов называется RS-232C. RS означает "recommended standardw (рекомендуемый стандарт), а 232C — при¬ своенный ему номер. Через этот кабельный коннектор могут быть подключены и ваше печатающее устройство и ваш терминал. С середины 1980-х годов при последовательной передаче на смену стандарту RS-232C пришел более новый стандарт RS-422/423. Связь с удаленными устройствами ЭВМ может быть соединена и с удаленной ЭВМ (или терминалом). Для этого ис¬ пользуется обширная сеть телефонных линий. Но при этом возникает следующая проблема: ЭВМ и телефонные линии используют разные типы сигналов. Для ЭВМ нужны цифровые сигналы, а для телефонов — аналоговые. Чтобы пояс¬ нить это различие, сравним часы с числовой индикацией с часами с движущими¬ ся стрелками. Первые из них для указания времени используют цифровые сигна¬ лы, вторые показывают время непрерывно (аналоговые сигналы). В качестве дру¬ гого примера можно привести термометр с числовой индикацией (цифровой) и ртутный термометр (аналоговый). Для решения данной проблемы используют электронное устройство, которое преобразует цифровые сигналы в аналоговые (модулятор), и устройство, осущест¬ вляющее обратное преобразование (демодулятор). Этот модулятор-демодулятор обычно называется для краткости модемом. По прогнозам в начале следующего века ббльшая часть телефонной сети будет переведена на цифровой принцип функционирования и необходимость в модемах отпадет. Совместимость Независимо от того, что (кабель или телефонная линия) используется для связи ЭВМ и устройства, прежде чем они начнут пересылать друг другу сообщения, должно быть принято соглашение по некоторым вопросам. Так, они должны по¬ сылать и принимать сообщения с одним и тем же методом синхронизации, с од¬ ной и той же скоростью, с одним и тем же протоколом, одним и тем жедуплекс- ным режимом работы и в одной и той же системе кодирования. Рассмотрим вкратце каждый из этих вопросов. Метод синхронизации Одна из проблем, которая должна быть решена ЭВМ при передаче информации, состоит в том, как определить, где символ (или байт) при передаче начинается и где кончается. Одно из решений, обычно используемых на больших ЭВМ, заклю¬ чается в том, чтобы послать в обе стороны сообщения, синхронизирующие пере¬ дачу, а затем передавать непрерывный поток информации. Этот метод называет¬ ся синхронным. Другой метод, который обычно применяется на малых ЭВМ и печатающих уст¬ ройствах, заключается в обрамлении парой бит каждого отдельного байта (стар¬ товым битом и стоповым битом). Этот метод используется, когда символы пере¬
Основные сведения о системе Юникс 69 сылаются спорадически и через нерегулярные интервалы времени, и называется асинхронной (или стартстопной) связью. Другой используемый термин относится к контролю ошибок при передаче. Ча¬ сто к символу, стартовому и стоповому битам добавляется дополнительный бит (бит паритета), чтобы иметь общее число единиц либо четным (четный паритет), либо нечетным (нечетный паритет). Скорость передачи данных Скорость передачи данных является скоростью передачи или приема информа¬ ции ЭВМ. Эта скорость измеряется в битах в секунду (бит/с) и иногда классифи¬ цируется как медленная (110, 150, 300 или 600 бит/с), средняя (1200, 1800, 2400, 3600 и 4800 бит/с) и высокая скорость (9600 и 19200 бит/с). Для микроЭВМ в насто¬ ящее время наиболее широко используется скорость передачи 1200 бит/с. Протокол Для связи требуется набор правил, чтобы определять, какая сторона будет пере¬ давать информацию и когда. На больших ЭВМ такой набор правил называется протоколом (или дисциплиной линии) и основан на синхронности передачи. Та¬ кие протоколы бывают байт-синхронными или бит-синхронными. Один из байт- синхронных протоколов BSC (binary synchronous communication — двоичная син¬ хронная связь) фирмы IBM для синхронизации групп подлежащих передаче сим¬ волов использует синхронизирующие сигналы от передающей и принимающей сторон. Бит-синхронный протокол SDLC (synchronous data link control — управле¬ ние синхронной информационной связью) той же фирмы основан при синхрони¬ зации на стандартных форматах данных. На малых ЭВМ протокол часто реализуется в прикладных программах. Один из наиболее общих протоколов называется XON/XOFF. В этом методе передающая сторона продолжает посылать информацию до тех пор, пока не заполнится вре¬ менная область памяти (или буфер) на принимающей стороне. Чтобы прекратить передачу, получатель посылает сигнал XOFF передающей стороне. Затем, когда буфер получателя освобождается, он посылает передающей стороне сигнал XON, извещая о возможности продолжения передачи. Способ передачи Возможная направленность передачи для линии, соединяющей два абонента, классифицируется следующим образом: •симплексная, допускающая передачу только в одном направлении (подобно ули¬ це с односторонним движением); •полудуплексная, которая означает, что обе стороны могут посылать друг другу информацию, но эта передача происходит в любой момент только в одном на¬ правлении (подобно улице, по которой разрешается ехать только в направлении, указываемом регулировщиком); •дуплексная, допускающая передачу одновременно в обоих направлениях (подоб¬ но улице с двусторонним движением). При работе терминалов с дуплексным способом связи возникает вопрос: что делать с символами, которые вы вводите с клавиатуры? У терминала есть только две возможности: обрабатывать символ на месте (в терминале) или пересылать его для обработки в ЭВМ. Когда терминал только обрабатывает, то говорят о блочном способе передачи; когда же он только передает символы в ЭВМ, то это дуплексный способ. Когда терминал делает и то и другое, то говорят о полудуп¬
70 Часть I лексном способе передачи. Если не делается ни то, ни другое, то терминал забло¬ кирован. В системе Юникс связь с терминалами обычно осуществляется дуплекс¬ ным способом. Система кодирования Рассмотрим в заключение способы кодирования информации в ЭВМ. Возможно, вы знаете азбуку Морзе — систему кодирования, в которой каждой букве соот¬ ветствует свой код. Операции внутри ЭВМ и связанных с ней устройств, включая передачу данных между ними, выполняются в кодах. Каждая буква алфавита, каждая цифра, каждая команда известна машине своим кодом. Большие ЭВМ используют код EBCDIC (extended binary-coded decimal interchange code) фирмы IBM, содержащий 256 8-разрядных кодов. В малых ЭВМ применя¬ ется 7-разрядный код ASCII (American Standard Code for Information Interchange), содержащий 128 кодов. Внутренняя система кодирования ЭВМ содержит печата¬ емые символы, которые есть на клавиатуре, подобной клавиатуре пишущей ма¬ шинки (буквы, цифры, знаки), и набор управляющих символов. Ниже приведен пример двоичного представления обычного кода ASCII: 1101001 Поскольку такой код не очень легко читать, обычно подобные числа пред¬ ставляют в другой системе счисления. Привычная десятичная система (с основа¬ нием 10) затрудняет перевод в двоичную систему счисления (с основанием 2), по¬ этому для представления кодов ASCII обычно используется либо восьмеричная (с основанием 8), либо шестнадцатеричная (с основанием 16) система. Ниже приве¬ ден вид кода символа / в этих четырех системах: Двоичная Восьмеричная Шестнадцатеричная Десятичная Символ 1101001 151 69 105 i Эти пять колонок отражают различные способы толкования одного и того же символа. В системе Юникс коды обычно записываются в восьмеричной системе счисления. Если вы введете символ / с клавиатуры, то в ЭВМ всегда будет пере¬ даваться 1101001, хотя мы могли записать этот код в любой из указанных систем счисления. Таблица кодов ASCII Отдельные символы, подобные/, в таблице обычно распределяются в четыре ко¬ лонки по 32 символа в каждой (или в восемь колонок по 16 символов). Для приме¬ ра возьмем целую строку таблицы кодов ASCII, ту строку, которая содержит сим¬ вол /. Будем считать, что эта таблица содержит четыре колонки. HT 011 ) 051 I 111 i 151 Мы видим четыре элемента, за каждым из которых следует восьмеричное представление: HT (горизонтальная табуляция) восьмеричный код 011 (обычно известна как TAB1') ) (правая скобка) восьмеричный код 051 I (прописная буква I) восьмеричный код 111 i (строчная буква i) восьмеричный код 151 1)На клавиатуре отечественных терминалов эта клавиша маркируется как <ГТ). — Прим, перев.
Основные сведения о системе Юникс 71 О таком распределении символов следует заметить следующее: — прописная I и строчная i находятся рядом в одной строке; — I, i и ) представляют собой видимые символы (символы, которые появляют¬ ся на экране, когда вы нажимаете на соответствующие клавиши); — HT ОГАВ) является управляющим символом, т. e. символом, который вызыва¬ ет некоторое действие. Если говорить о клавиатуре, то имеются еще две особенности, касающиеся распределения символов клавиатуры в таблице кодов ASCII: • нажатие только клавиши, помеченной как I, дает строчную i; •одновременное нажатие клавиши I и SHIFT дает прописную I; • совместное нажатие клавиши I и CTRL дает HT fTAB), что вызывает перемещение курсора в следующую зону табуляции. HT fTAB) называется управляющим символом, поскольку он вызывает дейст¬ вие, которое влияет на работу терминала. Можно сказать, что он является управ¬ ляющим еще и потому, что его код есть результат одновременного нажатия кла¬ виш CTRL и I. Совместное нажатие CTRL и I (иногда называется как нажатие CTRL-I) эквивалентно нажатию клавиши TAB. Чтобы посмотреть таблицу кодов ASCII в системе Юникс, можно вывести со¬ держимое файла /usr/pub/ascii командой cat: cat /usr/pub/ascii Таблица 5.1. Таблица кодов ASCII Символ Восьме¬ ричный код Шестнад¬ цатерич¬ ный^ код Символ Восьме¬ ричный код Шестнад¬ цатерич¬ ный^ код NUL 000 0 ETB 027 17 SOH 001 1 CAN 030 18 STX 002 2 ЕМ 031 i9 ETX 003 3 SUB 032 lA EOT 004 4 ESC 033 lB ENQ 005 5 NP 034 lC ACK 006 6 GS 035 lD BEL 007 7 RS 036 lE BS 010 8 US 037 lF HT 011 9 [sp] 040 20 NL 012 А ! 041 21 VT 013 В <« 042 22 FF 014 С # 043 23 CR 015 D $ 044 24 SO 016 E % 045 25 SI 017 F & 046 26 DLE 020 10 f 047 27 DC1 021 11 ( 050 28 DC2 022 12 ) 051 29 DC3 023 13 * 052 2A DC4 024 14 + 053 2B NAK 025 15 f 054 2C SYN 026 16 - 055 2D
< С н СО 50,0 ЧЭ о 2! g ^ 72 Часть I Символ 1 0 1 2 3 4 5 6 7 8 9 < > ? @ А В С D E F G H I J К Восьме- ричцый код Шестнад¬ цатерич¬ ный код Символ Восьме¬ ричный к Шестнад¬ цатерич¬ ный код 056 2E W 127 57 057 2F X 130 58 060 30 Y 131 59 061 31 Z 132 5A 062 32 [ 133 5B 063 33 \ 134 5C 064 34 ] 135 5D 065 35 * 136 5E 066 36 137 5F 067 37 ч 140 60 070 38 а 141 61 071 39 b 142 62 072 ЗА с 143 63 073 ЗВ d 144 64 074 ЗС e 145 65 075 3D f 146 66 076 ЗЕ g 147 67 077 3F h 150 68 100 40 i 151 69 101 41 j 152 6A 102 42 к 153 6B 103 43 1 154 6C 104 44 m 155 6D 105 45 n 156 6E 106 46 о 157 6F 107 47 P 160 70 110 48 Q 161 71 111 49 r 162 72 112 4A s 163 73 113 4B 't 164 74 114 4C u 165 75 115 4D V 166 76 116 4E w 167 77 117 4F X 170 78 120 50 У 171 79 121 51 z 172 7A 122 52 { 173 7B 123 53 I 174 7C 124 54 } 175 7D 125 55 ~ 176 7E 126 56 DEL 177 7F
Основные сведения о системе Юникс 73 К сожалению, изображение будет профильным, т. e. с управляющими символа¬ ми в верхней части таблицы и с видимыми символами в нижней. На экране будут показаны 16 строк по восемь символов в каждой. Лучше выводить таблицу ASCII с управляющими символами слева и видимыми символами справа, как показано в табл. 5.1. Управляющие и видимые символы Рассмотрим управляющие и видимые символы. Предположим, на ваш экран выве¬ ден следующий текстовый файл: Type this: 85 Then wait. Возникает вопрос: если вы нажали клавишу TAB перед вводом 85 и клавишу RETURN в конце каждой строки, то сколько символов в этом файле? • Если вы совсем неопытный пользователь, то, вероятно, скажете 20 символов. • Если хоть немного работали на ЭВМ, то можете сказать 22. • Правильный ответ — 25 символов. Почему? Объяснение. В тексте только 20 видимых символов. Кроме того, в нем два пробела (т. e. плюс еще два символа) и три управляющих символа: один символ горизонтальной табуляции TAB и два символа перевода строки (newline), что вместе с остальными дает 25 символов. Символ TAB, известный еще как CTRL-I, является знаком HT (восьмеричный код 011), а символ перевода строки, или CTRL-J, это знак NL (восьмеричный код 012). Отметим, что такое соглашение о символе перевода строки свойственно только системе Юникс. Обычно в коде ASCII для перехода на новую строку используется CTRL-M (возврат каретки — CR) и следующий за ним CTRL-J (перевод строки — LF). Ниже приведен вид файла в системе Юникс в восьмеричном представлении (деление строки здесь связано только с ограниченностью ширины строки): 124 171 160 145 040 164 150 151 163 072 011 070 065 012 124 150 145 156 040 167 141 151 164 056 012 Или, если перевести в символьный вид: T у p e Csp] t h i s : HT 8 5 NL T h e n Csp] w а i t . NL Для пользователей видимые символы появляются на экране, а управляющие нет. Но для системы Юникс все они являются символами. Это похоже на обыч¬ ное телевидение: тут тоже есть символы, которые вы видите на экране (актеры), и символы, которых вы не видите (это те люди, кто занимается камерами, костю¬ мами, гримом, декорациями и т. д.). Другие методы управления терминалом Управляющие символы — не единственное средство управления терминалом. Многие более новые терминалы управляются последовательностями символов, которые начинаются с символа ESC (escape, восьмеричный код 033) и известны как последовательности переключения (escape sequences). Примерами таких по¬ следовательностей являются ESC L и ESC ] 12. Предпринимаются попытки увели¬ чить число доступных управляющих символов, и некоторые производители тер¬ миналов расширяют базовый набор символов со 128 (7-разрядный код ASCII) до 256 символов (8-разрядный код).
74 Часть I Краткое изложение главы 5 В этой главе мы рассмотрели принципы взаимодействия с другими пользовате¬ лями системы и нашей системы с другими системами Юникс. Общение с другими пользователями ПосылкА почты. Чтобы послать сообщение по электронной почте другому пользователю вашей системы, используйте команду mail, за которой укажите идентификатор пользователя. После этого введите свое сообщение, а затем CTRL-D на строке, следующей после вашего сообщения (или точку с последующим нажатием клавиши RETURN). ПолучЕниЕ почты. Если какой-нибудь пользователь послал вам сообщение по электронной почте, сразу же после входа в систему вы увидите на экране следу¬ ющее сообщение: You have mail (для вас есть почта). Чтобы узнать содержание со¬ общения, используйте команду mail без аргумента, а затем для вывода каждого отдельного сообщения нажимайте клавишу RETURN. Для удаления текущего сооб¬ щения нажимайте d, а для его повторения — p. НАПОминдниЕ САМому СЕБЕ. Чтобы напомнить себе о чем-либо, вы можете по¬ слать себе с помощью команды mail почтовое сообщение или заслать сообщения, перед которыми указаны даты, в специальный файл напоминания, называемый календарем (calendar), который автоматически проверяется системой. ПРЯМАЯ связь с другим пользовАТЕЛЕМ. Чтобы послать сообщение на терминал другого пользователя, используйте команду write, за которой следует ваше сооб¬ щение, начинающееся со следующей строки и завершающееся CTRL-D. Общение с пользователями вне системы Юникс Вызов АБОНЕНТА внЕ ВАШЕЙ систЕмы Юникс. Для установления связи с другой си¬ стемой Юникс или системой, не использующей ОС Юникс, выполните команду cu (call up), включающую телефонный номер вызываемого абонента и скорость пере¬ дачи данных друг другу. Если вы установили связь, можете вводить сообщения друг для друга с клавиатуры или пересылать файлы в обоих направлениях. КОПИРОВАНИЕ ИЗ ОДНОЙ СИСТЕМЫ ЮНИКС В ДРУГУЮ. Для копирования файлов из одной системы Юникс сети в другую используйте команду uucp (UNIX-to-UNIX сору), содержащую имена обеих систем Юникс вместе с именами файлов. Чтобы выполнить команды Юникс на другой системе в сети, используйте команду uux (UNIX-to-UNIX execute), получающую команды через конвейер. Все это, конечно, предполагает наличие такой сети, в которой используются эти команды. ШИФРОВАНИЕ инФОРМАЦии. Чтобы зашифровать файл, используйте команду crypt с ключом, входом которой является исходный файл, а выходом — зашифро¬ ванный файл. Для того чтобы позже просмотреть (или распечатать) исходный текст, используйте снова команду crypt с тем же ключом, указывая в ней в ка¬ честве входного зашифрованный файл. Для обеспечения секретности вашего зашифрованного файла выбирайте длинный и сложный ключ. Не храните этот ключ где-либо в системе Юникс. НЕКОТОРЫЕ основныЕ понятия ТЕОРИИ связи. ЭВМ связываются друг с другом и другим оборудованием с помощью проводной связи (иногда с помощью модемов), используя один из нескольких методов синхронизации, скоростей передачи, про¬ токолов и способов передачи. МикроЭВМ осуществляют связь (внутреннюю и внешнюю) в кодах ASCII.
Часть II. Редактирование текста с помощью редактора ed Глава 6. Введение в строковый редактор ed В главах 1—5 мы ознакомились с операционной системой Юникс и изучили неко¬ торые ее свойства. В последующих главах мы рассмотрим текстовые редакторы, которые поставляются в составе системы Юникс. Их можно использовать для ввода и коррекции документов, командных файлов, программ и записей данных. Поставщики программного обеспечения в настоящее время предлагают тексто¬ вые редакторы и системы обработки слов для операционной системы Юникс. В этой книге мы рассмотрим следующие редакторы: •ed — примитивный интерактивный редактор, первоначально спроектированный для телетайпов и выполняющий в основном операции над полными строками, •vi — визуальный редактор содержимого экрана, основанный на редакторе ed и позволяющий выполнять операции над текстовыми файлами построчно. Главы 6 и 7 представляют собой введение в редактор ed, а более подробные сведения о нем изложены в гл. 8—10. Так как визуальный редактор vi намного проще и более удобен в использовании, вы можете его применять вместо редак¬ тора ed. Однако, если у вас есть только редактор ed или нет интеллектуального терминала с адресуемым курсором, тогда вы вынуждены пользоваться редакто¬ ром ed. Если в вашей системе есть редактор vi, тогда автоматически вы имеете и редактор ex — строкоориентированное дополнение vi (фактически vi является разновидностью ex). Редактор ed Начало работы с новым каталогом Выше было сказано о том, что одним из способов использования всех преиму¬ ществ файловой системы Юникс является организация своего начального ката¬ лога в форме подкаталогов, содержащих различные виды файлов. Ниже показа¬ но, как создать новый подкаталог в вашем начальном каталоге, содержащем файлы редактора ed. 1. Создайте новый подкаталог. а) Создайте каталог, называемый text files, с помощью команды mkdir: $ $ б)mkdi г text fi Les б) Каталог создан, но вы все еще находитесь в своем начальном каталоге.
76 Часть II 2. Перейдите из вашего начального каталога в каталог text_files. а) Войдите в подкаталог text files с помощью команды cd: $ $ cd text files б) Убедитесь, что вы перешли в подкаталог text_files: $| pwd /usr/robin/text fiLes $ в) Теперь каталог text files находится в вашем рабочем каталоге; любые файлы, которые вы создадите, будут храниться в этом каталоге. В книге мы будем использовать для подкаталогов имена, подобные именам text_files и c_progs. Эти имена очень удобны для изучения системы; однако, когда вы начнете работать с системой Юникс, должны использовать имена, опи¬ сывающие содержимое файлов в ваших подкаталогах (например, atc.acctg, atc.invoices). Короткий сеанс работы Проведем короткий сеанс работы с редактором ed, чтобы узнать несколько ос¬ новных правил: как начать сеанс, ввести текст и окончить сеанс. 1. Начните сеанс редактирования. а) Наберите на клавиатуре ed (но не ED) непосредственно за приглашением ин¬ терпретатора shell системы Юникс и нажмите клавишу RETURN. На экране должно появиться следующее: $ ed или ed б) На этот раз перед курсором отсутствует приглашение shell. Таким способом редактор ed сообщает, что вы вошли в редактор и он ожидает от вас ввода команды. 2. Попытайтесь ввести некоторые команды редактора ed. а) Сначала введите команду, которая неизвестна редактору; наберите z и нажми¬ те RETURN: m ? б)б) Вопросительный знак — это ответ редактора ed, который можно трактовать так: ”Я никогда не слышал об этой команде. Пожалуйста, попытайтесь сде¬ лать что-нибудь еще“.
Редактирование текста с помощью редактора ed 77 в) Теперь введите реальную команду редактора; наберите а (но не А) и нажмите г) На этот раз знака вопроса (?) не возникает, а это означает, что вы ввели пра¬ вильную команду редактора. Кроме того, трактовка ответа может быть такой: ”Вы только что запросили добавить строку к тексту, которую редактор готов принять". 3. Введите несколько строк текста. а) Начиная с позиции под символом ”а“, наберите следующий текст, нажимая в конце каждой строки клавишу RETURN: If you're tired of getting scaLped by someone else, б) Теперь содержимое экрана должно быть следующим: If you're tired of getting scalped by someone else, 4. Сообщите редактору, что вы не хотите больше ничего набирать. а) Не выйдет ничего хорошего, если набрать текст: "Это все, что я хотел сказать, редактор". Достаточно набрать только точку (.) в строке непосредственно за последней строкой и нажать RETURN: б) В результате ничего не произойдет. Чтобы убедиться, что редактор выполнил ваше указание, наберите еще одну точку на следующей строке и нажмите RETURN: scalped by someone else, в) На этот раз редактор ed откликнется повторением последней строки, которую вы набрали. Этим способом редактор сообщает вам: ”Я готов теперь к воспри¬ ятию следующей вашей команды". 5. Запишите текст в файл, называемый barbershop. а) На следующей строке, непосредственно под второй точкой (.), наберите w bar¬ bershop и нажмите RETURN: w barbershop б)RETURN: 52 б) Буква w — первая буква слова write (записать) означает: "записать этот текст в файл, называемый barbershopu.
78 Часть II На этот раз редактор сообщает вам число (52). Его ответ означает: ”Я записал для вас 52 символа в файл, называемый barbershop“. 6. Завершите сеанс работы с редактором ed. а) Наступило время сказать редактору "до свидания". Наберите q, означающее quit (выйти), и нажмите RETURN: m $ б) Теперь на экране появится приглашение интерпретатора shell системы Юникс. Таким способом Юникс сообщает о том, что вы вышли из редактора ed и вернулись в интерпретатор shell. На этом заканчивается ваш первый сеанс работы с редактором ed. Ниже при¬ веден итоговый пример по изучению редактора. Запомните, что вы должны на¬ жимать клавишу RETURN после каждой набранной строки: $ ed ? rti Начать сеанс работы с редактором Попытка набрать строчную букву z Что означает z? Начать добавлять здесь новый текст If you're tired of getting scaLped by someone else, ш Прекратить добавлять новый текст Просить редактора проверить конец текста "scalped by someone else,PenaKTop проверяет конец текста | w barbershop | Запишите текст в файл, называемый 52 barbershop (52 символа) ^P| Закончите сеанс работы с редактором ed $ Теперь вы снова вернулись в интерпре¬ татор shell системы Юникс Набор следующего документа Вы только что получили возможность провести полный сеанс редактирования с использованием редактора ed. Теперь вы дополнительно можете попрактико¬ ваться в наборе текста, используя процедуры, которые только что изучили. В первом примере мы вызывали редактор ed, набирая только две буквы (ed). Затем после набора текста мы указали имя файла в команде w (w barbershop). На¬ чиная с этого примера, мы будем открывать сеанс работы с редактором, указы¬ вая имя файла сразу же за командой ed, что, вероятно, является лучшим спосо¬ бом. Когда редактор ed отвечает вопросительным знаком перед именем файла, это означает, что файл еще не существует. 1. Приготовьтесь вводить текст в файл, называемый rates. а) Наберите ed rates после приглашения интерпретатора shell системы Юникс и нажмите RETURN: ed rates 7rates [ed не узнал это имя]
Редактирование текста с помощью редактора ed 79 6) Наберите а, чтобы начать добавление текста: н 2. Введите текст. а) Наберите показанные строки, используя клавишу TAB для размещения и закан¬ чивая каждую строку нажатием клавиши RETURN: [Одно нажатие TAB перед Rates] [Одно нажатие TAB перед $5] [Одно нажатие TAB перед $10] Rates Self service $5 Full servi се $10 б) Наберите точку (.) и нажмите клавишу RETURN, чтобы закончить текст: Ш в) Наберите еще раз точку (.) и нажмите снова RETURN, чтобы получить под¬ тверждение: пз Full service $10 3. Сохраните текст, записав его в файл rates. а) Наберите w и нажмите RETURN: и 40 б) Редактор ed в ответ сообщит число (40 символов). 4. Вернитесь в интерпретатор shell системы Юникс. а) Наберите q и нажмите RETURN: И $ _ б) На экране появится вновь приглашение интерпретатора shell системы Юникс, показывающее, что вы вышли из редактора ed. Набор третьего документа Вы уже имели возможность провести два полных сеанса редактирования средст¬ вами редактора ed. Теперь вы можете дополнительно попрактиковаться в наборе текста, снова используя те же процедуры. И снова мы укажем имя нового файла сразу же после команды ed. 1. Подготовьтесь к вводу текста в файл с именем hours. а) Наберите ed hours после приглашения интерпретатора shell и нажмите клави¬ шу RETURN:
80 Часть II $ |ed hours 7hours [ed не узнал это имя] б) Наберите а, чтобы начать ввод текста: И 2. Введите текст. а) Оставьте одну пустую строку, затем наберите показанные строки, используя клавишу TAB для размещения их на экране и заканчивая каждую строку нажа¬ тием клавиши RETURN: [Здесь пустая строка] [Одно нажатие клавиши TAB перед Hours] [Одно нажатие клавиши TAB перед 10—6] Hours Monday-Friday 10-6 б) Наберите точку (.) и нажмите RETURN, чтобы закончить текст: m В) Наберите еще раз точку (.) и нажмите снова RETURN, чтобы получить под¬ тверждение: ш Monday-Friday 10-6 3. Сохраните текст, записав его в файл hours. а) Наберите w и нажмите RETURN: ГмЛ 27 в) Редактор ed в ответ сообщит число (27 символов). 4. Возвратитесь в интерпретатор shell системы Юникс. а) Наберите q и нажмите RETURN: ш $ _ б) На экран будет выведено приглашение интерпретатора shell системы Юникс, показывающее, что вы вышли из редактора ed. Вывод текста на экран дисплея Использование существующего файла Ниже мы будем выводить на экран некоторый текст. До того как мы сможем сде¬ лать это, мы должны набрать этот текст. 11. Начните очередной сеанс редактирования файла barbershop.
Редактирование текста с помощью редактора ed 81 а) Наберите ed barbershop и нажмите RETURN: $ ed barbershop 52 б) Редактор ed в ответ сообщит число символов (52), считанных из файла barber¬ shop. 2. Добавьте к файлу barbershop еще несколько строк текста. а) Наберите а и нажмите RETURN, чтобы добавить текст: и б) Наберите еще две строки текста, за которыми наберите пустую строку: come to the Scissor's Edge and do it yourseLf. [Здесь оставьте пустую строку] в) Наберите точку (.), чтобы закончить добавление: □ Использование команды print (Вывести на печать) p Процесс вывода текста на экран в системе Юникс отождествляют с процессом вывода на печать, так как система Юникс была создана для терминалов типа те¬ летайп, которые не имели видеомониторов. И входные, и выходные данные печа¬ тались на бумаге, а не выводились на экран дисплея. К сожалению, пользовате¬ ли системы Юникс все еще применяют термин ”вывод на печать“ даже тогда, когда никакой печати нет, так как используется видеотерминал. 1. Выведите на экран несколько строк текста. а) Выведите на экран строки 1 и 2, набрав 1,2p с запятой между цифрами 1 и 2 и нажав RETURN: 1,2pl If you're tired of getting scalped by someone else, б) Выведите на экран строки 3 и 4, набрав 3,4p и нажав RETURN: 3,4p come to the Scissor's Edge and do it yourself.
82 Часть II 2. Выведите на экран строки текста с символом "последняя строка“1). а) Выведите на экран строки, начиная с третьей и до последней строки текста, набрав 3,$p и нажав RETURN: 3,$p come to and do [Вывести на экран строки, начиная с третьей Edge the Scissor's it yourself. и до конца] б) Выведите на экран весь текст, набрав 7,$p и нажав RETURN: 1,$P If you're tired of getting scaLped by someone else, come to the Scissor's Edge and do it yourself. 3. Выведите на экран отдельную строку текста, а) Выведите на экран строку 3, набрав и нажав RETURN: Гзр] come to the Scissor's Edge б) Выведите на экран последнюю строку, набрав $p и нажав RETURN: $p 4. Сохраните текст и завершите сеанс редактирования, а) Сохраните этот текст, записав его снова в файл barbershop: w barbershop 100 б) Наберите q и нажмите RETURN, чтобы завершить сеанс: Ш $ _ в) На экране появляется приглашение интерпретатора shell системы Юникс, по¬ казывающее, что вы вышли из редактора ed. 1) В качестве символа "последняя строка" используется ”$“. — Прим, перев.
Редактирование текста с помощью редактора ed 83 Считывание существующих файлов Считывание одного файла r Вы можете считать содержимое любого существующего текстового файла в рабо¬ чее пространство (или в буфер редактора) в любой момент с помощью команды r. Этот текст затем добавляется к текущему содержимому рабочего пространства. 1. Начните следующий сеанс редактирования файла barbershop. а) Наберите ed barbershop и нажмите RETURN: $|ed barbershop 100 б) Редактор ed в ответ сообщит число символов (100), считанных из barbershop. 2. Считайте файл rates в рабочую область и посмотрите на результаты. а) Считайте файл rates, набрав r rates и нажав RETURN: г rates 40 б) Теперь выведите на экран весь буфер, чтобы просмотреть его содержимое: ±Ж If you're tired of getting scalped by someone else, come to the Scissor's Edge and do it yourself. Rates [Здесь был добавлен файл rates] Self service $5 Full service $10 Считывание следующего файла Мы только что считали в рабочую область один файл. Почему бы не считать еще один? 1. Считайте файл hours в рабочую область и посмотрите на результаты, а) Считайте файл hours в рабочую область, набрав r hours и нажав RETURN: [Вы говорите: «Редактор,считай файл hours»] [Редактор отвечает:«Я считал 27 символов»] б)г hours 27 б) Теперь выведите на экран последние семь строк рабочей области: 6,$p [Вывести на экран строки,начиная Rates Self service $5 Full service $10 с шестой и до конца]
84 Часть II Hours [Здесь добавлен файл hours] Monday-Fn' day 10-6 Чтобы вывести на экран последние семь строк рабочей области, вы могли бы также использовать команду $-6,$p вместо 7,$p. Команда $-6,$p означает: "Выве¬ сти на экран рабочую область, начиная с шестой строки, отсчитанной от послед¬ ней строки и кончая последней строкой". 2. Снова сохраните рабочую область. а) Используйте команду w, чтобы записать содержимое рабочей области в файл barbershop: w barbershop 167 б) Снова редактор ed в ответ сообщает число записанных символов (167). Используя принятую в вычислительной технике терминологию, можно ска¬ зать, что старое содержимое файла barbershop теперь переписано новым текс¬ том. Обычно, если вы возьмете лист бумаги с некоторым текстом и запишете на нем новый текст, в результате получите некоторый испорченный текст. В систе¬ ме Юникс (и в других операционных системах) текст, записываемый в некоторый файл, замещает то, что ранее хранилось в этом файле. Номера строк Текущая строка Как вы уже знаете из этой главы, на экран можно вывести третью строку текста из буфера редактора, набрав Зр Come to the Scissor's Edge Когда вы это сделали, редактор ed принимает к сведению данный номер (3), идентифицирующий самую последнюю строку, к которой было обращение(так на¬ зываемую текущую строку). Каждый раз, когда вы выполняете команду, использу¬ ющую номера строк, вы можете обращаться к текущей строке, используя точку (.). Ниже приведено несколько примеров использования команд p и d. 1. Выведите на экран различные строки текста. а) Выведите снова третью строку, набрав .p и нажав RETURN: .p Come to the Scissor's Edge б) Выведите на экран четвертую строку, набрав .+ 7p (перейти к строке, следую¬ щей за текущей строкой, и вывести ее на экран дисплея) и нажмите RETURN:
Редактирование текста с помощью редактора ed 85 1-+1р| and do it yourself. в) Выведите на экран снова третью строку, набрав .-1p (перейти к строке перед текущей строкой и вывести ее на экран) и нажмите RETURN: .-ip Come to the Scissor's Edge После того как вы вывели на экран четвертую строку, точка (.) стала означать 4; после того как вы вывели на экран третью строку во второй раз, точка снова стала означать 3. Использование номеров строк в других командах До сих пор вы использовали номера строк только с командой p (print). Но вы мо¬ жете использовать их также и с командами а (append — присоединить), r (read — считать) и w (write — записать). Используйте единственный номер строки перед командой а для добавления текста после указанной строки. 1. Наберите новый текст после текущего текста и выведите на экран результаты, а) Добавьте текст к существующему тексту, набрав $a и нажав RETURN: $a б) Наберите строку, используя клавишу TAB для размещения на экране, и точку, чтобы указать конец текста: $a Weekends 10-4 [Одно нажатие TAB перед 10—4] в) Выведите на экран результаты командой $-2, $p: $-2,$p Hours Monday-Friday 10-6 Weekends 10-4 Чтобы записать в файл только часть рабочей области, используйте пару номеров строк перед командой w (write). 2. Запишите последние четыре строки рабочей области обратно в файл hours и всю рабочую область — в файл barbershop. а) Вы можете записать последние четыре строки, набрав $-3, $w hours и нажав RETURN (отсчитать три строки назад от последней строки):
86 Часть II $-3,$w hours 41 [Записан 41 символ] б) Запишите содержимое всей рабочей области, используя w без номеров строк: w barbershop] 181 [Записан 181 символ] в) Теперь считайте файл hours обратно в рабочую область, перезаписывая теку¬ щий текст с помощью команды e (edit — редактировать): e hours 41 г) Проверьте, что теперь в рабочей области ровно 4 строки: Tsp" Hours Monday-Friday 10-6 Weekends 10-4 Чтобы считать файл и вставить его после строки, указанной перед r, используй¬ те единственный номер строки перед командой r (read). 3. Вставьте rates между строками 1 и 2 и покажите результаты. а) Выведите на экран строку 1, чтобы сделать ее текущей. оа [На экран выведена пустая строка] б) Считайте файл rates, набрав .r rates и нажав RETURN: .r rates 40 в) Проверьте результаты с помощью команды 1,$p: 1,$ P Rates Self service $5 Full service $10 Hours Monday-Friday 10-6 Weekends 10-4
Редактирование текста с помощью редактора ed 87 4. Закончите сеанс редактирования. а) Выйдите из редактора ed, набрав q и дважды последовательно нажав RE¬ TURN. б) На экране появится приглашение интерпретатора shell. Краткое изложение главы 6 В этой главе вы изучили основные операции интерактивного строкового редак¬ тора ed: начало сеанса редактирования, ввод текста, запись текста в файл, за¬ вершение сеанса, редактирование существующего файла, печать (вывод на экран) текста, считывание существующего файла и использование номеров строк. Вы также узнали, что редактор ed использует номера строк и команды из одной буквы. НАЧАЛОСЕАНСА. При появлении на экране символа $, являющегося приглашени¬ ем интерпретатора shell, наберите ed и нажмите RETURN. Если вы планируете ра¬ ботать с файлом, который вы уже создали в предыдущий сеанс, можете набрать имя этого файла после ed. ЗАПРЕЩЕННЫЕСИмволы. Избегайте использования следующих символов в имени файла: \ . * [ ] $ & Эти символы рассматриваются в гл. 8. Ввод ТЕКСТА. Наберите а (append) и нажмите RETURN, наберите желаемый текст, нажимая RETURN в конце каждой строки; затем наберите точку в строке, следующей за последней строкой текста, и снова нажмите RETURN. Здпись ТЕКСТА в ФАйл. Чтобы сохранить текст, который вы набрали, наберите w (write), пробел, имя файла и нажмите RETURN. Если вы набрали имя файла при вызове редактора, набирать это имя здесь уже не обязательно. Вывод ТЕкстА нА экРАН. Чтобы вывести текст на экран дисплея, наберите один или два номера строк p farint) и нажмите RETURN. Если вы набрали один номер строки, будет выведена на экран одна строка; если вы набрали два номера строк, разделенные запятой, будут выведены на экран все строки между указан¬ ными, включая и эти строки. СчитывАНИЕ ФАйЛА. Чтобы считать содержимое файла в буфер редактора и до¬ бавить его к тексту, уже находящемуся в буфере, наберите r (read), пробел и имя файла. Вы можете также набрать перед r номер строки, чтобы указать строку, за которой должен следовать файл. ИспользовАНИЕ номЕРОВ строк. Вы можете набрать номера строк перед коман¬ дами редактора, используя реальные номера, знак доллара $, для указания на по¬ следнюю строку текста или точку для указания текущей строки текста. Команды а (append) и r (read) допускают только один номер; команда p (print), w (write) и e (edit) допускают один номер или пару номеров, разделенных запятой. Вы можете также составлять выражения вида: .+ 1 (следующая строка); $-1 предпоследняя строка. ПровЕлы в ЗАПИСИ комАнд. Редактор ed позволяет набирать пробелы между символами в команде, а это означает, что эквивалентны следующие записи ко¬ манды p: 1,5p 1,5 p 1, 5 p
88 Часть II Глава 7. Манипулирование полными строками с помощью редактора ed В главе 6 мы рассмотрели основы использования редактора ed: начало и оконча¬ ние сеанса редактирования, ввод текста, вывод текста на экран, считывание су¬ ществующего файла и использование номеров строк. В этой главе мы рассмот¬ рим методы вставки, удаления, изменения и перемещения текста, а также мето¬ ды отмены команд редактора, восстановления существующего файла и вывода на экран текста с невидимыми управляющими символами. Внесение изменений в текст Возврат к начальному каталогу Если вы изменили текущий каталог, который использовали в гл. 6, то чтобы вер¬ нуться к подкаталогу, который мы используем для редактируемых файлов, вос¬ пользуйтесь приведенными ниже командами. (Если вы все еще находитесь в ва¬ шем начальном каталоге, используйте более короткую команду, приведенную сле¬ ва.) $ $ cd text fi Les или $ $ cd /usr/robin/text files Теперь text files есть ваш текущий каталог. Вы можете использовать команду Is, чтобы вывести на экран файлы, которые вы уже хранили в этом каталоге: $LsJsp barbershop $ hours rates Вставка текста i Вы использовали команду а несколько раз: иногда чтобы добавить текст к пусто¬ му текстовому буферу, иногда чтобы присоединить новый текст к существующе¬ му тексту. На команду а очень похожа по свойствам команда i (insert — вставить). Основное отличие состоит в том, что I вставляет новый текст перед указанной строкой, а команда а — после указанной строки. Введем некоторый текст, чтобы выяснить, как эта команда работает. 1. Начните новый файл, называемый sections, и введите восемь строк показан¬ ного текста. Используйте клавишу TAB, а не клавишу пробела, чтобы распреде¬ лить текст по колонкам. Текст представляет собой названия разделов в Руко¬ водстве по ОС Юникс с указанием справа номеров страниц. $led sections 7sections [Редактор еще не узнает это имя]
Редактирование текста с помощью редактора ed 89 а 1 Commands [Здесь пять раз нажать TAB] 182 2 System Calls 58 3 Subroutines 62 4 Special Fi les 22 5 File Formats and Conventions 26 6 Games 18 7 Macro Packages and Language Conventions 14 8 Maintenance 12 w Ш 2. Вставьте новую строку текста между строками 4 и 5 (иногда бывает удобно начинать каждую строку с ее собственного номера). а) Наберите 5/, чтобы запросить вставку перед пятой строкой: б) Введите показанную строку (шесть звездочек; каждая звездочка набрана по¬ сле нажатия клавиши TAB): [tabl * * * * * * в) Наберите точку, чтобы закончить ввод нового текста: ш r) Наберите 1,$p и нажмите RETURN, чтобы вывести на экран результаты: 1.Sp| 1 Commands 2 System Calls 58 3 Subroutines 62 4 Special Files 22 * * * * * * 5 File Formats and Conventions 26 6 Games 18 7 Macro Packages and Language Conventions 14 8 Maintenance 12 д) Редактор вставил в существующий текст новую строку.
90 Часть II 3. Введите для тренировки следующие четыре строки между 6-й и 7-й строками (после вставки новой строки номера рассматриваемых строк будут 7 и 8). а) Выполните команду i (insert): 8 i Games: arithmetic, backgammon, banner, bcd/ppt, bj (blackjack), checkers, chess, ching, fortune, maze, moo, quiz, reversi (Othello), tic-tac-toe, cubic tic-tac-toe, hangman, words, and wump 6)' Выведите на экран результаты: 61 $P 5 File Formats and Conventions 6 Games Games: arithmetic, backgammon, banner, bcd/ppt, bj (blackjack), checkers, chess, ching, fortune, maze, moo, quiz, reversi (Othello), tic-tac-toe, cubic tic-tac-toe, hangman, words, and wump 7 Macro Packages and Language Conventions 8 Maintenance 26 18 14 12 Удаление текста d Удаление текста выполняется легче, чем вставка. Для удаления отдельной стро¬ ки или нескольких строк применяйте команду d, используя номера строк так же, как и в случае применения команды p. 1. Удалите четыре строки, которые вы только что вставили между номерами 6 и 7 (строки 8, 9, 10, 11). а) Сначала наберите 8,11p и нажмите RETURN, чтобы вывести на экран эти стро¬ ки (и убедиться, что вы удаляете правильные строки): 8,11 p Games: arithmetic, backgammon, banner, bcd/ppt, bj (blackjack), checkers, chess, ching, fortune maze, moo, quiz, reversi (Othello), tic-tac-toe cubic tic-tac-toe, hangman, words, and wump 69 9 6) Наберите 8,11d и нажмите RETURN, чтобы удалить строки: 8,11 d
Редактирование текста с помощью редактора ed 91 в) Выведите на экран результаты: $-3,$ p 5 File Formats and Conventions 26 6 Games 18 7 Macro Packages and Language Conventions 14 8 Maintenance 12 Так как команда d на экран ничего не выводит (и так как нет способа восста¬ новить удаленные строки), всегда выполняйте три приведенные выше шага: вы¬ ведите на экран строку (строки), удалите строку (строки) и выведите результаты на экран. 2. Удалите строку звездочек, которую вы ранее вставили. а) Сначала для вывода на экран используйте команду 4,5p (плюс предыдущая строка как точка отсчета): JJrj 4 Special Files 22 ★ ★ ★ ★ ★ ★ б) Используйте команду 5d для удаления строки: ГГТ| в) Выведите на экран результаты: 4,5p 4 SpeciaL Fi les 22 5 File Formats and Conventions 26 г) Теперь текст принял свою исходную форму. Команда, которую вы использовали для удаления строки (5d), содержала кон¬ кретное значение номера строки (5). Это не очень удобно, так как вы не всегда знаете точно номер конкретной строки. Ниже в этой книге рассмотрено, как идентифицировать строки по их содержанию. Внесение изменений в текст с Редактор ed позволяет заменить целую строку текста (или группу последователь¬ ных строк) другой строкой (или группой строк). Команда с (change — изменить), которая реализует эту возможность, во многом аналогична команде i (insert). 1. Замените строку 6 на две строки звездочек. а) Наберите 6c и нажмите RETURN:
92 Часть II б) Введите две строки звездочек, используя клавишу TAB, чтобы сделать отступ, и наберите точку на следующей строке: ★ ★ . ★ ★ ★ ★ ★ ★ ★ <★ * * в) Теперь выведите на экран результаты: ~зТ^~ 5 File Formats and Conventions 26 ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ 7 Macro Packages and Language Conventions 14 8 Maintenance 12 г) Как и следовало ожидать, вы заменили строку 6 (Games) двумя строками звез¬ дочек. 2. Замените две строки звездочек (строки 6 и 7) строкой 6. а) Наберите 6,7c, нажмите RETURN и введите исходную строку, за которой сле¬ дует точка и RETURN на следующей строке: 6,7 с 6 Games 18 б) Выведите на экран результаты: 5,$P 5 File Formats and Conventions 26 6 Games 18 7 Macro Packages and Language Conventions 14 8 Maintenance 12 Теперь вы восстановили исходный текст. Команду с (change) вы можете ис¬ пользовать для замены одной строки двумя, двух строк одной, трех строк пятью или одной (или другими комбинациями). Отметим, что выполнение команды с с точкой без набора текста приведет к удалению текущей строки. Перемещение текста m Если вам нужно переместить строку (или группу строк) из одного места рабочей области в другое, воспользуйтесь командой m (move — переместить). Мы продол¬ жим работу с тем же примером текста.
Редактирование текста с помощью редактора ed 93 1. Переместите строки 1 и 2 в конец рабочей области. а) Сначала наберите 1,2p и нажмите RETURN, чтобы вывести эти строки на экран: T7T^ 1 Commands 182 2 System Calls 58 б) Затем наберите 1,2m$ и нажмите RETURN, чтобы переместить строки: 1,2 m $~ в) Наберите 1,$p, чтобы вывести на экран результаты: тж 3 Subroutines 62 4 Special Fi les 22 5 File Formats and Conventions 26 6 Games 18 7 Macro Packages and Language Conventions 14 8 Maintenance 12 1 Commands 182 2 System Calls 58 2. Переместите эти две строки снова в начало текста. а) Используйте команду 7,8p, чтобы вывести строки на экран: 7.8 p 1 Commands 182 2 System Calls 58 б) Так как строки пересылаются командой m на место строки, которая следует за указанной, мы должны в качестве номера строки использовать 0: 7.8 m 0 в) Воспользуйтесь командой 1,3p, чтобы вывести на экран результаты: T^P 1 Commands 182 2 System Calls 58 3 Subroutines 62 33. Сохраните текст и закончите сеанс редактирования. а) Наберите w и нажмите RETURN, чтобы записать текст в файл sections:
94 Часть II И 204 6) Наберите q и нажмите RETURN, чтобы закончить этот сеанс редактирования и вернуться к приглашению интерпретатора shell: Ш $ Копирование текста t Если вам нужно скопировать строку (или группу строк) из одного места рабочей области в другое, используйте команду t (transfer — передать), которая подобна команде m (move). Различие заключается в том, что команда t оставляет оригинал текста на месте, а команда m — нет. Вернемся к файлу sections. 1. Начните следующий сеанс редактирования файла sections. а) После приглашения интерпретатора shell наберите ed sections и нажмите RE¬ TURN: ed sections 204 б) Выведите на экран командой 1,4p первую половину рабочей области: H.4p| 1 Commands 182 2 System Call 58 3 Subroutines 62 4 Special Files 22 2. Скопируйте строки 1 и 2 на место строк, следующих за пометкой 4. а) Наберите 1,2f4 и нажмите RETURN, чтобы скопировать строки: 1,2 t 4 б) Наберите 1,6p, чтобы вывести на экран результаты: fWI 1 Commands 182 2 System Calls 58 3 Subrouti nes 62 4 Special Files 22 1 Commands 182 2 System Calls 58
Редактирование текста с помощью редактора ed 95 Маркировка строк k Чтобы пометить строку текста, используйте команду k, за которой следует строч¬ ная буква (от а — до z). Затем используйте это имя перед командой m (move) или командой t (transfer), чтобы переместить или скопировать данную строку. Чтобы переместить или скопировать часть текста, а не только одну строку, вы можете заключить в скобки блок, пометив первую и последнюю строки. Затем наберите два имени, разделенных запятой, перед одной из команд m или t. Рассмотрим не¬ сколько примеров. Сначала скопируем строки 4, 5 и 6 в конец текста. 1. Пометьте строку 4. а) Выведите на экран строку 4: га 4 Special Files 22 б) Пометьте строку 4, которая теперь является текущей строкой: | ka | [Присвоить строке 4 имя a] 2. Пометьте строку 6. а) Выведите на экран строку 6: 6p 2 System Calls 58 б) Пометьте строку 6, которая теперь является kb [Присвоить текущей строкой: строке 6 имя b] Имея пару помеченных,строк (а и а), мы можете сформировать команду t (tran¬ sfer), чтобы скопировать три строки в конец текста. В команде t вы должны пе¬ ред каждым именем поставить апостроф, чтобы отличить ее от команд редакто¬ ра ed. 3. Скопируйте строки 4—6 в конец текста, а) Наберите ’а, *bt$ и нажмите RETURN: 'a,*b t $ [Скопировать строки от a до b в конец ($)] б) Выведите на экран текст командой 9,$p, чтобы увидеть результаты: гяга 7 Macro Packages and Language Conventions 14 8 Maintenance 12 4 Special Fi les 22 1 Commands 182 2 System Calls 58
96 Часть II Теперь вы скопировали три строки в конец рабочей области. Вы могли бы также выбрать часть текста и переместить ее на новое место, используя этот же метод, но другую команду — команду m (вместо команды t). Попытайтесь для практики переместить блок. 4. Оставьте текст в рабочей области. а) Наберите q и нажмите RETURN, чтобы выйти из текста: ш ? [Редактор в первый раз не воспринимает указание] б) Снова наберите q и нажмите RETURN, чтобы прекратить работу с текстом: 9_ Вывод на экран текста с управляющими символами I Вы уже научились выводить текст на экран дисплея командой p. Другая команда редактора ed, называемая I (list — внести в список), выводит на экран не только текст, но также признаки конца печати строки, возврата каретки, подачи бланков и другие управляющие символы. Ниже мы используем текст, с которым уже рабо¬ тали. 1. Внесите в список шесть строк текста в буфере редактирования. а) Начните очередной сеанс редактирования файла sections: $ ed sections 204 б) Наберите 1,$l (единица, запятая, знак доллара, ”эль“) и нажмите RETURN: 1,$ 1 1>Commands>>>>>182 2>System CaLLs>>>>>58 3>Subrout i nes>>>>>62 4>SpeciaL Files>>>>>22 5>FiLe Formats and Conventions>>>26 6>Games>>>>>>18 7>Macro Packages and Language Conventions>>14 8>Maintenance>>>>>12 в) Здесь редактор ed показывает позицию каждого признака конца печати стро¬ ки знаком >, причем все пробелы выброшены. (Если у вас имеется телетайп, вы увидите -> вместо >.) 2. Теперь добавьте к тексту несколько управляющих символов после последней строки.
Редактирование текста с помощью редактора ed 97 а) Наберите а и нажмите RETURN, чтобы добавить текст: И б) Проделайте следующие действия пять раз: нажмите клавишу TAB, затем, удер¬ живая нажатой клавишу CTRL, нажмите G (т. e. CTRL G). Затем нажмите RE¬ TURN. в) Строка, которую вы только что набрали, будет невидимой. Вы можете услы¬ шать короткий звуковой сигнал вашего терминала каждый раз, когда нажима¬ ете CTRL-G. г) Теперь наберите точку и нажмите RETURN, чтобы показать конец вашей до¬ бавки к тексту: 3. Чтобы наблюдать невидимые управляющие символы, которые вы набрали в этой строке, используйте команду I. а) Наберите $-1, $1 (знак доллара, минус, единица, запятая, знак доллара, ”эль“) и нажмите RETURN, чтобы вывести на экран последние две строки текста: $-1,$ L 8>Mai ntenance>>>>>12 >\07>\07>\07>\07>\07 б) Здесь, как и раньше, каждый знак > представляет конец строки. в) Каждая группа символов \07 представляет одну команду CTRL-G (седьмой управляющий символ). 4. Подготовьтесь к возобновлению сеанса редактирования, а) Сохраните текст: w sections 215 б) Заметьте, что этот сеанс редактирования будет очень кратковременным. Управляющие коды, которые обычно не появляются на экране при их наборе на клавиатуре, используются для реализации таких функций, как перемещение курсора, описание экрана и вывод пробелов на терминалы (а также таких функ¬ ций, как установка позиции на ленте, установка интервала и управление печата¬ ющими механизмами). Полный список этих кодов можно найти в специальной таблице ASCII (табл. 5.1). С помощью команды I (list) каждый управляющий символ, за исключением TAB, изображается как группа символов. Она начинается знаком \, за которым следует двузначное число. В приведенном примере \07 означает команду CTRL-G, также известную как BEL (код ASCIIx07) — код, используемый для включения зву¬ кового сигнала терминала. (Для получения полного списка управляющих кодов, 4-771
98 Часть II используемых системой Юникс, выведите командой cat (объединить) на экран файл /usr/pub/ascii — в заключение этого сеанса редактирования.) Почему было бы полезно увидеть на экране дисплея эти коды? Потому, что редактор ed и система Юникс рассматривают их как и другие символы, которые вы набираете, хотя они и не появляются на экране, как уже говорилось в гл. 5. Если вы случайно набрали один из этих управляющих символов в середине ко¬ манды, занесенной в файл, система не сможет распознать команду 1). Следова¬ тельно, команда не будет выполнена, и без команды I вы не узнаете, почему. Редактирование существующего файла e В главе 6 вы узнали, как использовать команду r (read) для считывания текста из файла в буфер редактирования и присоединения его к существующему тексту. Команда e (edit — редактировать) также выполняет подобную функцию. Если вы работаете последовательно с несколькими различными файлами, можете запом¬ нить текст для одного файла и затем вызвать второй файл в буфер редактирова¬ ния, не выходя из редактора ed. В качестве примера используйте файл, который вы создали. 1. Вернитесь к файлу barbershop. а) Наберите e barbershop и нажмите RETURN: |e barbershop 181 б) Единственное, что вы увидите после числа 181 — курсор на следующей стро¬ ке. Этим способом редактор ed сообщает вам, что он вернулся к файлу barber¬ shop (содержащему 181 символ) и готов начать редактирование. 2. Вставьте несколько строк текста в файл barbershop и сохраните их. а) Наберите 1i и нажмите RETURN, чтобы сообщить редактору ed, что вы намере¬ ны вставить несколько строк перед первой строкой текста: 11 i l [Вставить текст перед строкой 1] б) Ничего не произошло. Это означает, что все правильно, поэтому начинайте на¬ бирать текст, сопровождая каждую строку нажатием клавиши RETURN. По¬ следняя строка текста состоит из точки и RETURN. [Набрать 24 черточки] [Одно нажатиеТАВперед Notice] [Набрать 24 черточки] Noti се 1) Предполагается, что в файле находится текст некоторой программы. Если системе предложено выполнить эту программу, естественно, она проверяет каждый элемент фай¬ ла — команда это или нет. — Прим. ред.
Редактирование текста с помощью редактора ed 99 в) Сохраните этот текст, записав его снова в файл barbershop. fwl 239 г) Ответ редактора ed означает: ”В файле barbershop 239 символов“. 3. Теперь, когда файл barbershop записан, снова вернитесь к файлу sections. а) Наберите e sections и нажмите RETURN: e sections 215 [Начать редактирование файла sections] б) Файл sections — снова в буфере редактирования, а файл barbershop из него удален. Чтобы увидеть это, наберите 1,3/ (единица, запятая, три, ”эль“) и на¬ жмите RETURN: TTT| 1>Commands>>>>>182 2>System Calls>>>>>58 3>Subrout1nes>>>>>62 4. Выйдите из редактора ed и закончите сеанс редактирования. а) Наберите q и нажмите RETURN, чтобы выйти из редактора: ш $ _ б) Появляется приглашение интерпретатора shell системы Юникс, показываю¬ щее, что вы вышли из редактора. Команда e (edit) позволяет вам работать над одним файлом, записать его в па- * мять и затем перейти к другому файлу, не выходя из редактора ed. Если вам не удалось записать в память первый файл, редактор ed не обратится ко второму. Таким образом защищается текст в рабочей области. В гл. 8 вы узнаете, как про¬ изводить некоторые другие действия, не выходя из редактора ed. Краткое изложение главы 7 В этой главе вы узнали, как работать с помощью редактора ed с полными строка¬ ми: как вставить и удалить текст, внести в него изменения, переместить, скопи¬ ровать, вывести текст на экран вместе с невидимыми управляющими символами и отредактировать существующие файлы. ВстАВКА ТЕКСТА, чтобы вставить некоторый текст перед строкой уже существу¬ ющего текста, наберите номер строки и /, нажмите RETURN, наберите текст, кото¬ 4*
100 Часть II рый должен быть вставлен, затем в строке, следующей за последней строкой текста, точку и еще раз RETURN. УДАЛЕНИЕ тЕкстА. Чтобы удалить текст из буфера редактирования, наберите или один номер строки, или пару номеров строк, d (delete) и нажмите RETURN. Ес¬ ли вы набрали один номер строки, будет удалена одна строка; если вы набрали два номера строк, то удаляются все строки с номерами от первого из указанных до второго включительно. ВНЕСЕНИЕ измЕНЕний в ТЕКСТ. Чтобы заменить один текст на другой, набери¬ те номер строки (или пару номеров строк, разделенных запятыми) и с, нажмите RETURN, наберите текст, затем точку непосредственно за последней строкой текста и снова RETURN. ПЕРЕМЕЩЕНИЕТЕКСТА. Чтобы переместить текст из одного места в другое, набе¬ рите номер строки (или пару номеров строк, разделенных запятой), m, номер строки, куда перемещается текст, и нажмите RETURN. МдркировкА строк. Чтобы пометить строку, которую нужно переместить или скопировать, выведите ее на экран (чтобы она стала текущей строкой), затем на¬ берите kx, где x может быть любой строчной буквой алфавита. Чтобы сослаться на эту строку в команде m (move) или t (transfer), наберите 'x. Вывод НА экРАН ТЕКСТА с НЕВИдимыми символАми. Чтобы занести в список текст из текущего буфера редактирования, т. e. вывести его на экран дисплея наряду с признаками конца строки, возврата каретки и другими управляющими симво¬ лами, наберите один номер строки или пару номеров строк, l(list) и нажмите RETURN. Если вы наберете один номер строки, в список будет внесена (выведена на экран) одна строка; если вы набрали два номера строк, будут внесены в спи¬ сок (выведены на экран) все строки, заключенные между указанными. РЕДАКТИРОВАНИЕ ФАЙЛА. Чтобы вернуть существующий файл и переписать текст, находящийся в данный момент в буфере редактирования, наберите e (edit), про¬ бел, имя требуемого файла и нажмите RETURN. Глава 8. Внесение изменений в строку с использованием редактора ed В главах 6 и 7 вы узнали, как пользоваться редактором для изменений, вставок, копирования и перемещения полных строк текста. В этой главе мы рассмотрим команды поиска и подстановки для внесения изменений внутри строки. Если вы перешли к каталогу, отличающемуся от каталога, с которым работали в гл. 7, вы можете вернуться к подкаталогу, используемому для редактируемых файлов, с помощью приведенных ниже команд. (Если вы еще находитесь в своем начальном каталоге, можете использовать более короткую команду, приведенную слева.) или $ $ cd text fi les cd /usr/robin/text fiLes
Редактирование текста с помощью редактора ed 101 Теперь text files будет вашим текущим каталогом. Вы можете использовать команду Is, чтобы вывести на экран файлы, которые вы уже занесли в каталог: $|ls | sp barbershop $ hours rates sections Поиск и простые замены Поиск текста Чтобы иллюстрировать поиск текста по команде ed, воспользуемся файлом, ко¬ торый вы уже создали ( barbershop). 1. Откройте файл. а) Начиная с позиции, следующей за приглашением интерпретатора shell, набери¬ те ed barbershop и нажмите RETURN: $ |ed barbershop 239 б) Редактор ed в ответ сообщит размер файла в символах (239). 2. Найдите в строке 4 слово you're, измените его на you are и выведите на экран измененную строку. а) Выведите строку на экран командой 4p: И If you1 re tired of де^тпд[Подчеркиваниесделанодля __ усиления выразительности] б) Наберите .s/you’re/you are/p и нажмите RETURN: .s/you're/you are/p If you are tired of getting Из этой команды видно, что мы просим редактор ed выполнить следующее: .s Отыскать в текущей строке (строке 4) текста /уои’ге/ одну последовательность символов (you’re), you are/ заменить ее на другую последовательность (you are) p и затем вывести на экран строку 4 после замены. Точка перед командой s (substitute — заменить) для указания на текущую стро¬ ку не требуется. С этого момента мы отказываемся от точки. 3. Аналогично замените последовательность someone else в строке 5 на а profes¬ sional: а) Сначала выведите строку на экран: ® scalped by someone eLse,
102 Часть II б) Затем произведите изменения: s/someone eLse/a professional/p scaLped by а professional, Удаление текста Вы можете использовать команду s также для удаления текста внутри строки. Наберите текст, который надо удалить, между первой парой косых черточек; за¬ тем наберите косые черты друг за другом, т. e. ничего не набирайте между ними. 1. Удалим слова by а из строки 5. а) Сначала строку выведите на экран: 5p| scalped by а professional, б) Затем наберите s/by a//p и нажмите RETURN: s/by а //p scaLped professional, [После а надо оставить пробел] 2. Удалим также the из строки 6. а) Сначала выведите эту строку на экран: l +P | [Точка здесь также опущена] come to the Scissor's Edge б) Удалите слово the: [После the необходим пробел] issor's Edge Команда p (print), которую мы использовали в конце командных строк, требу¬ ется в одних случаях и не требуется в других. Однако во избежание недоразуме¬ ний мы будем продолжать использовать ее во всех наших примерах. 3. Подумайте о способе замены professional на professionally в строке 5. а) Сначала выведите строку на экран: ~5р~| scalped professional, б) Наберите s/nal/nally/p и нажмите RETURN: s/nal/nally/p scalped professionally, s/the //p come to Sc
Редактирование текста с помощью редактора ed 103 4. Теперь подумаем о том, как восстановить слово the в строке 6. а) Сначала выведите строку на экран: | +p | [Знак «плюс» эквивалентен +/] come to Scissor*s Edge б) Вставьте слово the: s/to/to the/ come to the Scissor’s Edge Контекстный способ поиска1) До сих пор мы пользовались или абсолютными номерами (1,3) или относительны¬ ми выражениями (+2, -2) для указания строк. Редактор ed предлагает третий путь: использование текста, заключенного между косыми чертами. Например, так как строка 6 содержит слово Edge, можно использовать это слово для определе¬ ния местонахождения желаемой строки и легко находить затем любой текст, ко¬ торый содержит эта строка. 1. В качестве простого примера заменим come to в строке 6 на enter. а) Сначала выведите на экран с помощью знака равенства номер строки: [Удобный способ определить номер любой строки] б) Выведите текст на экран: /Edge/p come to the Scissor's Edge /Edge/= 6 в) Наберите s/come to/enter/ и нажмите RETURN: s/come to/enter/p enter the Scissor's Edge Из этой команды s (substitute — заменить) видно, что мы просим редактор ed вы¬ полнить следующее: s Найти в текущей строке /come to/ одну цепочку символов (come to), enter/ заменить ее на другую (enter) p и затем вывести на экран строку с внесенными изменениями. 1)Способ поиска информации по содержанию (контексту) некоторого признака (клю¬ ча), находящегося в составе искомой информации. Ключ представляет собой некоторую последовательность (цепочку) символов, далее называемую цепочкой. — Прим. ред.
104 Часть II В этом примере запись IEdge/ представляет собой другой способ указания но¬ мера строки 6, — той самой строки текста, в составе которой находится указан¬ ная цепочка IEdgel^. 2. Используйте подобную команду для замены do на try в строке 7. а) Сначала выведите на экран номер строки с помощью знака равенства: /and/= 7 б) Затем выведите текст на экран: /and/p and do it yourself. в) Затем наберите s/do/try/p и нажмите RETURN: s/do/try/p and try it yourself. В этом примере мы используем and не как номер строки, а как задаваемую це¬ почку для определения местонахождения строки. Затем может быть выполнена замена в пределах строки (отыскать do, затем заменить do на try). Запись landl ис¬ пользуется здесь вместо номера строки 7. Так как мы можем не знать точный но¬ мер отыскиваемой строки, то приведенный способ поиска удобнее. Возможны случаи, когда требуется заменить то самое слово, которым мы пользовались для нахождения строки. Например, вам надо заменить and на then. Вы могли бы набрать /and/s/and/thenl, но редактор ed предоставляет вам более простой способ. 1. Замените в строке 7 and на then. а) Перейдите к одной из ранее рассмотренных строк (годится любая строка): Ш If you are tired of getting б) Наберите land/sl/thenlp и нажмите RETURN: /and/s//then/p then try it yourself. Из этой команды видно, что мы просим редактор ed выполнить следующее: /and/s Отыскать первую строку, которая содержит and, П чтобы ту же последовательность (цепочку) символов (and) 11) Запись IEdgel представляет цепочку Edge для поиска строки в тексте, которая эту цепочку содержит. — Прим. ред.
Редактирование текста с помощью редактора ed 105 then/ заменить на другую (then) p и затем вывести на экран строку с внесенными изменениями. В этом примере отсутствие последовательности (цепочки) символов после ко¬ сой черты, следующей за s, предписывает редактору ed отыскать ту же самую строку, которая была использована для определения местонахождения строки текста (and). Этот способ известен под названием remembered pattern (запомнен¬ ный образец). 2. Удалите professionally из строки 5. а) Выведите строку на экран: Г/sca Lped/p scalped professionally, б) Наберите /professionally/s///p (с пробелом перед professionally) и нажмите RETURN: [Если вы не набрали пробел перед professionally, оставить пробел между scalped и запятой] Из этой команды видно, что мы предписываем редактору ed выполнить следую¬ щее: /professionally/s Отыскать первую строку текста, которая содержит эту цепочку (professionally), II чтобы ту же самую цепочку заменить на другую цепочку, / в которой отсутствуют символы, p и затем вывести на экран строку текста с внесенными изменениями. / professionally/s///p scalped, В этом примере соседние косые черты использовались в двух различных зна¬ чениях. Первая и вторая косая черта после s сообщает редактору ed: "Используй запомненный образец". Вторая и третья косые черточки — это способ сообщить редактору ed: "Замени эти символы запомненного образца символами, которые я набрал между этими косыми чертами (символы отсутствуют)"1>. 3. Используя ту же методику поиска строки и удаления из нее цепочки, удалите yourself из строки 7. а) Выведите на экран номер строки: /try/= 7 1) В результате текст искомой цепочки, используемый для поиска строки, будет из этой строки удален. — Прим. ред.
106 Часть II б) Выведите на экран текст в строке: /try/p then try it yourself. в) Наберите s/yourself//p (с пробелом после s/) и нажмите RETURN: s/ yourseLf//p then try it. На этом мы закончим рассмотрение единичных замен. Далее речь пойдет о множественных заменахб) 1>. Но сначала оставим буфер редактора, так чтобы иметь возможность перейти к исходному тексту в файле barbershop. Наберите q и нажмите RETURN последовательно дважды (на отдельных строках). Приглаше¬ ние интерпретатора shell появится на экране, причем файл barbershop остался без изменений. Множественные замены Выполнение более одной замены До сих пор с помощью команды s вы производили только единичные замены. Од¬ нако редактор ed позволяет производить и множественные замены. Для иллюст¬ рации этого выполним следующие действия. 1. Снова войдите в редактор и начните новый сеанс редактирования с файлом multiple. а) После приглашения интерпретатора shell наберите ed и нажмите RETURN: $[ed multiple 7multiple б) Используя а для начала набора текста и точку для его завершения, наберите следующее: а Down the trail they rode, one by one, one by one, through the canyon, one by one, one by one, into the clearing, one by one, one by one, across the desert, one by one, one by one. в) Сохраните текст: и 128 1) Множественные замены предполагают замену не одного, а нескольких слов. — Прим. ред.
Редактирование текста с помощью редактора ed 107 2. Начните с выполнения единичной замены в первой строке текста, а) Сначала выведите на экран строку текста: Down the trail they rode, one by one, one by one, б) Замените one на two один раз: s/one/two/p Down the trail they rode, two by one, one by one, в) Редактор ed заменит первую цепочку (слово one) в первой строке. В этой форме команда заменяет только первый экземпляр цепочки в первой из строк текста. На следующем шаге используйте команду, которая замещает це¬ почку столько раз, сколько она встретится в строке текста. Это достигается до¬ бавлением служебного символа g (global) в конец командной строки. 3. Сделайте множественные замены в первой строке, а) Снова выведите на экран первую строку: Down the trail they rode, two by one, one by one, б) Воспользуйтесь на этот раз модификатором g (global): s/one/two/gp Down the trail they rode, two Ьу two, two by two, в) Теперь наберите 1, $, чтобы вывести на экран все строки вместе. Down the trail they rode, two by two, two by two, through the canyon, one by one, one by one, into the clearing, one by one, one by one, across the desert, one by one, one by one. Слово global означает здесь "применимый ко всему тексту“. Редактор ed заме¬ нит каждый экземпляр цепочки one на two только в первой строке. Добавленный к концу командной строки символ g вызывает множественную замену в одной строке. Теперь вы знаете, как делать множественные замены в горизонтальном на¬ правлении в пределах строки текста. Следующий шаг — множественные замены в вертикальном направлении (в пределах всей рабочей области). Этот шаг вклю¬ чает набор номеров строк перед командной строкой замены. ffiD
108 Часть II 4. Выполните замены во всех строках, а) Выведите на экран снова первую строку: И Down the trail they rode, two by two, two by _two, б) Сделайте замены и выведите на экран первые шесть строк текста: 1,$s/one/two/ 1,$P Down the trai 1 they rode, two by two, two by _two, through the canyon, two by one, one by one, into the clearing, two by one, one by one, across the desert, two by one, one by one. в) На это раз редактор ed заменит первый экземпляр цепочки one на two в каж¬ дой строке текста. Добавление к началу командной строки номеров строк при¬ водит к заменам во всех строках, но только первого экземпляра в каждой строке. Это обеспечивает множественные замены в вертикальном направле¬ нии (вниз по рабочей области). Теперь, когда вы узнали, как производить множественные замены в горизон¬ тальном и вертикальном направлениях, следующим шагом будет выполнение мно¬ жественных замен в обоих направлениях (т. e. выполнение замены всех экземпля¬ ров цепочки во всех строках текста). Эта процедура включает набор номеров строк перед командной строкой и символа g в конце строки. 5. Выполните замены во всех строках. а) Снова выведите на экран первую строку: 03 Down the trail they rode, ^wo by two, two by two, б) Выполните замену и выведите на экран первые шесть строк: 1,$s/one/two/g l,$P Down the trai 1 they rode, two by two, two by two, through the canyon, two by two,•two by two, into the clearing, two by two, two by two, across the desert, two by two, two by two. в) На этот раз редактор ed заменяет все оставшиеся экземпляры one на two в каждой строке. Таким образом, указывая номера строк перед командной строкой и g — в кон¬ це этой строки, вы можете заставить редактор ed сделать замены во всей рабо¬ чей области.
Редактирование текста с помощью редактора ed 109 Повторный поиск //p Контекстный способ поиска не всегда обеспечивает нахождение искомой строки с первой попытки. Иногда приходится повторять поиск несколько раз. Для ил¬ люстрации используем текст, который мы уже редактировали. 1. Вернитесь к первой строке текста. а) Используйте команду 1p, чтобы вывести на экран первую строку: И Down t’he trail they rode, two by two, two by two, б) В соответствии с первой строкой, выведенной на экран, текущая строка те¬ перь имеет номер 1. 2. Начните поиск цепочки, которая встречается в тексте более одного раза. а) Используйте контекстный способ поиска, чтобы определить место очередной строки, которая содержит цепочку two: /two/p through the canyon, two by two, two by two, 6) Допустим, что это не та строка, которую вы искали. 3. Продолжайте поиск. а) Используйте две косые черты, чтобы указать "запомненный образец“, т. e. two UjB into the clearing, two by two, two by two, б) Теперь вы нашли еще одну строку с цепочкой two. 4. Снова продолжайте поиск. а) Используйте опять две косые черты //, чтобы указать "запомненный образец“: I //p | across the desert, two by two, two by two. б) Теперь вы нашли еще одну строку с цепочкой two. Если это необходимо, вы могли бы продолжать пользоваться запомненным образцом много раз, чтобы вести расширенный поиск в буфере редактирования. Закончите сеанс редактирования и выйдите из текста, набрав q и дважды на¬ жав RETURN (в отдельных строках). Другие средства поддержки при поиске Начало строки Л Символ Л используется редактором ed и другими программами системы Юникс для обозначения начала строки текста.
110 Часть II 1. Начните сеанс редактирования. а) Откройте сеанс редактора ed с файлом barbershop: $ [ed barbershop 239 б) Редактор ed в ответ сообщит число прочитанных символов (239). 2. Используйте знак Л для вставки пробела перед строкой 1. а) Сначала выведите строку на экран дисплея: QE б) Затем используйте Л для вставки пяти пробелов перед строкой: s/A/ /p [Заменить символ начала строки на пробелы] 3. Используйте факт наличия пробелов в начале для различения строк 1 и 3. а) Выведите на экран строки 1—3, и обратите внимание на их различия ТТзр] Notice б) Снова выведите на экран строку 1, чтобы она стала текущей строкой: Qpj в) Используйте знак Л для выбора строки 3 (вместо строки 1), чтобы произвести в ней изменения (только строка 3 начинается с минуса, а не с пробела): /А_/$/ /+++++/ +++++ [Пять минусов и пять плюсов] г) Выведите на экран результаты командой 1,Зр\ ГйЗр] Noti се +++++ Редактор ed пропускает строку 1 и выбирает строку 3 потому, что знак ми¬ нус — это самый первый знак в строке 3. Знак Л говорит о том, что при поиске надо выбрать строку только в случае, если знак минус обнаружен в начале этой строки. Строка 1 также содержит много минусов, но не в начале.
Редактирование текста с помощью редактора ed 111 Конец строки $ Если знак доллара $ используется в качестве номера строки перед командой ре¬ дактора, он указывает на последнюю строку буфера редактирования. Если же он используется между косыми чертами в цепочке при организации поиска, имеет другое значение — конец строки. Знак доллара $ используется часто так же, как и знак \ Например, вы могли бы использовать $ для добавления пропущенного слова в конец строки. 1. Добавьте символы к концу строки 3. а) Выведите строку на экран: ^_ +++++ б) Используйте знак $, чтобы добавить + + + + + (пять плюсов) к концу строки: s/$/+++++/p +++++ +++++ Можно использовать знак $ в составе цепочки, чтобы различать, например, две последовательности, которые без этого знака являются одинаковыми. Так, в строке 3 мы имеем две последовательности знаков плюс: одну — в начале стро¬ ки и другую — в конце. С помощью знака $ мы можем обратить внимание редак¬ тора ed на цепочку знаков плюс (в конце строки). По терминологии системы Юникс знаки Л и $ называются якорями текста. 2. Замените плюсы в конце строки 3 знаками равенства. а) Выведите строку на экран: Зр +++++ +++++ б) Замените плюсы в конце строки знаками равенства: [Обратите внимание на знак доллара] s/+++++$/=====/p +++++ Если бы вы выбросили из команды знак конца строки $, редактор ed заменил бы плюсы в начале строки и результат был бы такой: s/+++++/=====/p ===== +++++ Так как цепочка + + + + + встречается впервые в начале строки, то запись + + + + + эквивалентна в этом случае записи + + + + +.
112 Часть II Начало и конец строки л$ Комбинируя символы начала строки Л и конца строки $ внутри одной и той же пары косых черт, вы можете указать требуемую цепочку. Например, если бы вы захотели определить местоположение строки, которая не содержит символов (т. e. отыскивается пустая строка), то могли бы использовать в качестве ключа поиска /Л$/. Используем такого рода цепочку для замены двух пустых строк в бу¬ фере редактирования. 1. Приготовьтесь заменить пустые строки. а) Выведите на экран из буфера редактирования строки 8—15: 8,15p Rates Self service $5 Full service $10 Hours Monday-Friday 10-6 Weekends 10-4 б) Сделайте строку 8 текущей строкой: ~8р 2. Замените пустые строки строками, содержащими плюсы, а) Сделайте следующие замены (8 пробелов, затем 3 знака плюс)1>: g/A$/s// + + +/ б) Выведите результаты на экран: 8,15p + + + Rates Self service $5 Full service $10 + + + Hours Monday-Friday 10-6 Weekends 10-4 1) В данном примере содержится две ошибки, допущенные автором. В цепочке для за¬ мены всего 4 пробела вместо восьми, а в изображении на экране (результата замены) — 7 пробелов вместо 8. — Прим. ред.
Редактирование текста с помощью редактора ed 113 Особенности повторения цепочки при организации поиска и замещения & Существует специальный символ амперсанд &, который позволяет делать заме¬ щение в строке без обязательного набора всего текста замещения (цепочки заме¬ щения) на экране дисплея. Ниже приведено несколько примеров. 1. Вставьте слово в середину строки. а) Сначала выведите на экран строку 4: га If you're tired of getting б) Используйте знак &, чтобы вставить really перед tired: s/ti red/reaLly &/p If you're really ti.red of getting В этом примере знак & указывает на то, что на месте изображения знака & дол¬ жен стоять текст цепочки, которая заменяется (цепочка tired). 2. Поставьте перед словом Notice и после него некоторые символы. а) Сначала выведите на экран дисплея строку 2: "2p" Notice б) Затем используйте символ повторения &, чтобы вставить перед Notice и после знаки плюс (и пробелы). s/Notice/+ & +/p + Notice + Ниже приводятся подробные комментарии s Найти в текущей строке (строке 2) /Notice/ цепочку Notice, + & + / поместить один плюс перед Notice и один плюс после Notice p и затем вывести на экран модифицированную строку. Теперь оставьте текст в буфере редактирования, набирая q и дважды после¬ довательно нажимая RETURN (на отдельных строках). Выключение специального значения \ Приведенные ниже символы применяются в редакторе ed для специальных це¬ лей и их нельзя использовать обычным образом при контекстном способе поиска и в командах замены: / л $ & . * [ ]
114 Часть II Символ \ используется для выключения значения любого специального символа в команде s, давая возможность отыскивать один из этих символов, как и любой другой обычный символ. Отметим, однако, что символ \ нельзя использовать в командах а (append), i (insert) или с (change). Вернемся к файлу barbershop и про¬ иллюстрируем работу этого средства. 1. Начните сеанс редактирования. а) Выполните команду ed для файла barbershop: $| ed barbershop 239 б) Выведите на экран строки 10 и 11: 10,11p SeLf service $5 Full service $10 Мы бы хотели заменить $5 на $7 и $10 на $15, но здесь есть одна трудность: знак доллара означает в редакторе ed конец строки. Однако эту трудность мож¬ но устранить. Если мы наберем знак \ перед знаком доллара $, редактор будет игнорировать специальное значение $ и рассматривать его как обычный символ. 2. Измените количество долларов. а) Используйте знак \, чтобы рассматривать знак доллара в его прямом значе¬ нии (как денежный знак) A$5/s//$7/p Self service $7 Ниже приведен подробный комментарий: /N$5/s Найти строку, которая содержит $5 (вам потребуется здесь знак \), // заменить $5 $71 на $7 (знак \ отсутствует, так как это не цепочка для поиска), p затем вывести на экран скорректированную строку. б) Выполните подобные изменения в строке 11: /\S10/s//$15/р Full service $15 В каждом из этих случаев мы использовали знак \ только в цепочке для орга¬ низации поиска. Цепочка, которая замещает текст, не отыскивается в строке, по¬ этому для нее не надо указывать знак \.
Редактирование текста с помощью редактора ed 115 Подбор символа • Точка, расположенная перед такими командами редактора ed, как s или i, означа¬ ет текущую строку. Но в цепочке для организации поиска точка может использо¬ ваться, чтобы подобрать любой отыскиваемый символ. Например, вы могли бы использовать A.E в цепочке для организации поиска, чтобы отыскать сочетания ABE, АСЕ, АРЕ, АТЕ и т.д. Это может быть полезно при поиске специальных и управляющих символов. Чтобы проиллюстрировать сказанное выше, добавим несколько строк текста. Первая строка нового текста будет содержать три символа CTRL-G (иногда ис¬ пользуется сокращение AG), которые не появляются при наборе на экране; места набора показаны ниже указанием знака AG. 1. Наберите строку вместе с упомянутыми управляющими символами, а) Чтобы сделать добавление, используйте команду $a: Sa ) ThAGis iAGs the plAGace. * б)Эта строка (строка 16 в буфере редактирования) содержит управляющие сим¬ волы CTRL-G (AG) в середине трех различных слов. б) Сохраните текст и запомните число символов в нем: 2. Выведите на экран строку 16 и удалите вставленные в нее управляющие сим¬ волы. а) Выведите на экран строку 16 с помощью команды p (print): ТбТ This is the pLace. [Возможно, вы услышите 3 раза звуковой сигнал] б) Теперь выведите на экран строку 16 с помощью команды I (list): [Шестнадцать эль ] 16 L Thv07is i\07s the р1\07асе.[Наэтотраззвуковой сигнал отсутствует] в) Нам потребуется для каждой коррекции отдельная команда s: s/Th.is/This/l This i\07s the plN07ace. [Заменить77*\07/$ на This] s/i .s/i s7T~| This is the pLX07ace. [Заменить i\07s на is] s/pl.ace/place/Г| This is the pLace. [Заменить pl\07ace на place]
116 Часть II Точка в каждой цепочке для организации поиска предназначена для опреде¬ ления места управляющего символа, чтобы его можно было удалить из текста. Повторение символа 0 Используйте звездочку в цепочке для организации поиска для обозначения ’’лю¬ бого числа повторений предыдущего символа“. Например, вы могли бы использо¬ вать s/a*/B/, чтобы заменить а, aaa, aaaaa и т. д. на 8. Ниже рассмотрен пример та¬ кого использования звездочки в строке 1 файла barbershop. 1. Выведите на экран строку 1 и удалите минусы. а) Выведите на экран командой p строку 1: И б) Используйте команду s, чтобы произвести замену: s/-*/No more hyphens/p No more hyphens [Минусы удалены] В этой команде цепочка -* означает: ’’любое число последовательно располо¬ женных минусов“. Следовательно, вы не должны знать точное число символов, которое требуется отыскать. Выражение .* (объединение точки и звездочки) озна¬ чает: ’’любое число произвольных символов“. Например, вы могли бы использо¬ вать s/.*//, чтобы удалить строку любой длины, или использовать s/.*:/_/, чтобы заменить весь текст, предшествующий двоеточию, пятью пробелами. Рассмотрите комбинацию .* на примере вашего текста в файле barbershop. 2. Выведите на экран строку 5 и удалите весь текст после слова scalped. а) Выведите на экран командой p строку 5: 23 scalped by someone else, б) Используйте s и .*, чтобы удалить текст после слова scalped: s/ped.*/ped,/p scalped, Ниже приведен подробный комментарий: s Найти в текущей строке (строке 5) /ped.* цепочку by someone else, ped,/ заменить ее на запятую, p затем вывести на экран скорректированную строку. Точка в записи ped.* означает любой символ. Отметим, что интерпретация звездочки как ”любого числа символов“ включа¬ ет и "отсутствие символов”. Например, редактор ed мог бы воспринять n* как од¬
Редактирование текста с помощью редактора ed 117 ну из следующих последовательностей: пппппппппп(Щ, nnnnn(5), nn(2), n( 1) или (0). Однако если есть некоторый выбор, то выбирается самая длинная последова¬ тельность из тех, которые могут быть заменены. Чтобы убедиться в том, что редактор ed будет интерпретировать цепочку для организации поиска как ”по крайней мере один символ", наберите этот символ дважды перед звездочкой (например, nn*). Если вы хотите убедиться, что сущест¬ вуют по крайней мере два символа, вы должны набрать символы перед звездоч¬ кой трижды (например, nnn*). Подбор одного символа из множества П Чтобы сузить понятие любой символ, введенное выше до определенного набора символов, заключим этот набор в квадратные скобки. Например, вы могли бы ис¬ пользовать любой из следующих способов отыскания любой отдельной цифры и замены ее знаком #: /[0123456789D/s//#/p или /СО—9]/s//#/p Вы можете перечислить все варианты в скобках или указать диапазон символов, используя черточку (тире) между двумя крайними значениями. Ниже приведены три примера: [A-Z] Все заглавные буквы [a-z] Все строчные буквы [A-Za-z] Все буквы алфавита Для иллюстрации использования этих методов выведем на экран строки под строкой Hours в файле barbershop. 1. Прочитайте две строки под строкой Hours. а) Используйте /Hours/, /Hours/+2p (или 13, 15p), чтобы вывести строки на экран: /Hours/,/Hours/+2p Hours Self service 10-6 Full service 10-4 б) Заметьте, в каком порядке последние две строки содержат некоторые буквы и некоторые числа. 2. Замените каждую группу времени на Closed. а) Выведите на экран строку Hours снова (чтобы переместить текущую строку обратно): ^f3"T Hours б) Измените часы: 14,15s/1[0—9] — E0—9]$/ Closed/ H,15 p Self service Closed Full service Closed
118 Часть II Ниже приведен подробный комментарий: 14, 15s /1 [0 — 9] — — [0 - 9]$/ Closed Отыскать строки 14 и 15 по образцу 1n-m в конце строки (где n и m — цифры) и заменить на Closed. Вы можете также попросить редактор ed отыскать ”любые символы, кроме перечисленных". Для этого начните список со знака л, непосредственно стоящего за левой скобкой. Например, можно использовать .l[*ijklmn]lsllreallp или .l[*i-n]lsllreallp, чтобы отыскать любые символы, кроме i, j, k, I, m, n. Завершите сеанс, набрав q и последовательно дважды нажав RETURN. В этой главе вы узнали, как искать в буфере данную строку по цепочке симво¬ лов, заменять одну цепочку на другую, использовать цепочку для определения местонахождения строки (контекстный способ поиска), осуществлять поиск в об¬ ратном направлении, производить множественные замены и повторять поиск. Вы также узнали как использовать символы, выполняющие специальные функции при поиске или в команде s (substitute): начало строки (Л), конец строки ($), повто¬ рение строки (&), выключение специального значения (\), подбор символа (.), по¬ вторение символа (*) и подбор одного символа из множества ([ ]). Эти символы иногда называются метасимволами. Поиск и ЗАМЕЩЕНИЕ. Чтобы отыскать строку текста, содержащую некоторую цепоч¬ ку символов и заменить ее на другую, введите командную строку, которая содер¬ жит номер строки, команду s и две цепочки между косыми чертами. Вы можете также добавить p в конце команды, чтобы вывести результирующую строку на экран. УддлЕниЕ цЕПОчки. Чтобы удалить цепочку из строки текста, введите командную строку, в которой цепочка, предназначенная для замещения, не содержит симво¬ лов. Поиск контЕкстА. Если вы не знаете точный номер строки, которая содержит ис¬ комую цепочку, вы можете использовать эту цепочку (или другую цепочку) для поиска строки, затем введите остальную часть командной строки. ИСПОЛЬЗОВАНИЕ ЦЕПОЧКИ ДЛЯ ОРГАНИЗАЦИИ ПОИСКА В КАЧЕСТВЕ СТАРОЙ ЦЕПОЧКИ. ЕСЛИ Це- почка для организации поиска является также и цепочкой, которую вы хотите за¬ менить, редактор ed дает вам возможность оставить цепочку для замещения пу¬ стой и, таким образом, сократить команду. ИспользовАНИЕ другого РАЗДЕЛИТЕЛЯ. Если необходимо, вы можете использовать вместо косой черты другой символ (например, двоеточие (:)), чтобы разделить элементы в команде s. ВыполнЕниЕ волЕЕ одной ЗАМЕНЫ в строкЕ. Чтобы заменить в строке все экземпля¬ ры цепочки, а не только первый, добавьте g к концу командной строки. ВыполнЕниЕ ЗАМЕН во всЕХ строкАХ. Чтобы заменить первый экземпляр цепочки во всех строках, а не только в первой строке, наберите перед командной строкой номера строк. Краткое изложение главы 8 Поиск и простые замены Множественные замены
Редактирование текста с помощью редактора ed 119 ВыполнЕНИЕ всЕХ ЗАМЕН. Чтобы выполнить замены всех экземпляров цепочек во всех строках, наберите номера строк перед командной строкой и в ее конце. ПовтоРЕниЕ поискА. Чтобы повторить поиск, вы можете только набрать пару ко¬ сых черточек II для прямого поиска, вместо набора всей команды. Другие средства поиска НАЧАЛО строки. Чтобы указать начало строки текста, наберите знак л в начале це¬ почки для организации поиска (не в скобках). КонЕЦ строки. Чтобы обозначить конец строки текста, наберите знак доллара $ в конце цепочки для организации поиска. ПовтоРЕниЕ ЦЕПОЧки поискА. Чтобы не переписывать всю цепочку для организа¬ ции поиска, используйте знак амперсанд & в цепочке, предназначенной для заме¬ щения. ВыключЕНИЕ спЕЦИАЛЬного ЗНАЧЕНИЯ. Чтобы выключить специальное значение символа для редактора ed (т. e. чтобы вводить его как обычный символ текста), наберите перед этим символом знак \. ПодворсимволА. Чтобы редактор ed производил поиск отдельного символа, набе¬ рите точку в цепочке для организации поиска. ПовтоРЕниЕ символА. Чтобы редактор ed производил поиск любого числа симво¬ лов (включая отсутствие символов), наберите звездочку непосредственно после символа. Комбинация .* в цепочке для организации поиска означает любой. Подвор одного символА из множЕСТвА. Заключив символь^в квадратные скобки, вы можете перечислить те символы, поиск которых должен производить редак¬ тор ed. Введите знак л как первый символ после левой скобки, чтобы указать от¬ рицание (т.е. редактор ищет все символы, кроме перечисленных). Глава 9. Техника редактирования с использованием редактора ed В гл. 8 вы узнали, как использовать специальные символы при поиске и заменах. В этой главе показано, как использовать эти символы для решения разнообраз¬ ных задач редактирования: разбиения строки, объединения строк, восстановле¬ ния строки и использования редактирующего текста. Операции над строками Разбиение строки В гл. 8, чтобы отменить специальное значение некоторого символа, вы ставили перед ним знак \. Используя этот же знак непосредственно перед нажатием кла¬ виши RETURN, вы можете разбить отдельную строку текста на две строки. Пре¬ жде всего для работы нам потребуется новый файл и некоторый текст. 1. Начните сеанс редактирования. а) Войдите в каталог text files, если это необходимо: $ $ cd text files
120 Часть II б) Начните редактирование файла pfl.deal: $ ed pfl.deal 7pfl.deal в) Добавьте некоторый текст (в конце каждой строки оставьте пробел, не наби¬ райте номера строк и используйте клавишу TAB для табулирования информа¬ ции): 1 2 3 4 5 6 7 8 9 10 11 12 а Dear Mr. Hadison: The purpose of this tetter is to confirm Monday's agreement. Tupeto gets "Porkchop" Peterson, you get "Earthquake" Emerson, and we get "Rotunda" Robinson. Here are the players' names, heights, weights, and new teams: Emerson, Ezekiel R. 6'5" 273 Rochester Robinson, Charles F. 6'3" 287 Des Moines Peterson, Paul N. 5'9" 178 Tupelo You will be getting one of the finest players in the People's Football League. Your Friend and Mine, Chuck w 467 2. Разбейте строку 11 на две строки, а) Сначала выведите эту строку на экран: fW| You will be getting one of the finest players in the People's Football League. [Этот текст будет представлен одной стокой] б) Наберите командную строку, в которой знак \ набирают непосредственно пе¬ ред нажатием клавиши RETURN, чтобы разбить строку после слова finest (ис¬ пользуя est): [Haa<MHTeRETURNcpa3y после набора знака \] [Наберите в этой строке косую черту /] [Выведите на экран эти две строки] You will be getting one of the finest players in the People's Football League. s/est /est \ / 11,12p
Редактирование текста с помощью редактора ed 121 Ниже приводится подробный комментарий: s Отыскать в текущей строке (строке 11) /est/ цепочку est с пробелом, следующим за t, est\ и заменить ее на est, за которой следует RETURN, / 11, 12p затем вывести на экран строку с изменениями. Нажатием клавиши RETURN после набора знака \ вы сообщили редактору ed, что хотите поместить RETURN на это место в тексте (т.е. хотите, чтобы новая строка начиналась с указанной позиции). Объединение строк j Вы можете объединить отдельные строки (сформировать из них единую строку), используя команду j (join — объединить). Если использована изолированная ко¬ манда j (т. e. без пары номеров строк перед ней), то происходит объединение те¬ кущей строки со следующей строкой, что эквивалентно .,. + 1/. В любом другом случае вы должны снабдить эту команду номерами строк, используя или дейст¬ вительные номера, или последовательности контекста. В качестве первого упражнения объединим строки 4 и 5 в буфере редактирования. 1. Объедините строки 4 и 5, чтобы образовать одну строку. а) Выведите на экран объединяемые строки: ЕЖ TupeLo gets "Porkchop" Peterson, you get "Earthquake" Emerson, б) Объедините их командой j: 4,5jp TupeLo gets "Porkchop" Peterson, you get "Earthquake" Emerson, 2. Объедините строки 2 и 3 в одну строку, а) Выведите на экран объединяемые строки: 2,3p^ The purpose of this Letter is to confirm Monday's agreement. 6) Используйте команду j для объединения строк. ТГзТр~ The purpose of this letter is to confirm Monday's agreement. Успех выполнения этой операции основан на предположении, что после в строке 2 имеется пробел. Если вы забыли оставить пробел, строка будет выгля¬
122 Часть II деть следующим образом: The purpose of this letter isto confirm Monday’s agreement. Далее вы можете вставить пробел с помощью команды s/ is/8Jp. Если это необходимо, вы можете использовать команду j (join) для объедине¬ ния трех и более строк в одну строку. Чтобы указать первую и последнюю из объ¬ единяемых строк, поместите эти номера строк перед j. Изменение порядка расположения текста в строках \(\) Если вам нужно изменить расположение некоторого текста подстрок в каждой из группы строк по одному и тому же формату, вы можете каждую переставля¬ емую подстроку выделить символами \(и \) при составлении цепочки для органи¬ зации поиска. Эти подстроки можно пронумеровать и использовать не текст под¬ строк, а только их номера при составлении замещаемой цепочки в команде заме¬ щения s. Пусть вы имеете список имен в одном формате (фамилия вначале) Emerson, Ezekiel R. 6'5" 273 Rochester Robinson. Charles F. 6'3'' 287 Des Moines Peterson, Paul N. 5'9" 178 Tupelo вам хотелось бы иметь его в другом формате (имя вначале) Ezekiel R. Emerson 6'5'' 273 Rochester Charles F. Robinson 6'3'' 287 Des Moines Paul N. Peterson 5'9" 178 Tupelo Другими словами, вы хотели бы удалить запятые и поставить имена и отчест¬ ва перед фамилиями. Для этого сгруппируем содержимое каждой строки в под¬ строки: 1) фамилия; 2) имя и отчество; 3) рост; 4) вес; 5) команда. Ниже мы будем работать с подстроками 1 и 2, оставляя подстроки 3—5 неизменными. Для этого записываем подстроки в цепочке для организации поиска команды s (substitute), заключив их в "ссылочные скобки“. Эти "ссылочные скобки“ выгля¬ дят следующим образом: \(подстрока 1\) \(подстрока 2\) \(подстрока 3\) и т.д. Не сделайте здесь ошибок. Эти записи трудны для чтения. В вашем распоряже¬ нии уже достаточно способов использования знаков \ и других наборов симво¬ лов при составлении цепочки для организации поиска. Эти "ссылочные скобки“ (также известные как этикетки, или теги) не облегчают восприятия текста. При наличии подстрок (также известных под названием теговые регулярные выражения) в составе цепочки для организации поиска мы можем ссылаться на них по номеру при составлении замещающей цепочки, используя следующую за¬ пись: \1 \2 \3 и т. д. Эти средства очень похожи по действию на амперсанд &, который вы можете ис¬ пользовать для ссылки на текст всей цепочки. Отличие заключается в том, что вы можете ссылаться не на всю цепочку сразу, а на отдельные ее части. Редак¬ тор ed нумерует подстроки слева направо в тексте цепочки для организации по¬ иска.
Редактирование текста с помощью редактора ed 123 1. Измените порядок расположения текста в первых трех строках в соответст¬ вии с планом. а) Сначала выведите на экран три строки так, как они показаны ниже: sf6Te^l Emerson, EzekieL R. 6'5'' 273 Rochester Robinson, Charles F. 63" 287 Des Moines Peterson, Paul N. 5'9" 178 Tupelo Составьте команду для реализации плана изменения: 6,8s/A\([A,]*\), *\(CA\ . ]*\ ,\)/\2 vTT 6,8p EzekieL R. Emerson 6'5" 273 Rochester Charles F. Robinson 63" 287 Des Moines Paul N. Peterson 5'9" 178 Tupelo в) Изучите внимательно указания: 6,8s/A\([A,]*\), *\([А\.]*\.\)/\2\1/ 6,8s Отыскать строки 6, 7 и 8 и произвести во всех строках замены / Начало цепочки для организации поиска А Отыскать в начале каждой строки \( Начало первой подстроки [А,]* Любое число знаков, отличных от запятой (все до запятой, кото¬ рая следует за фамилией, не включая эту запятую) \) Конец первой подстроки ,* Затем отыскать запятую, за которой следуют несколько пробелов \( Начало второй подстроки Отыскать любое число символов, отличных от точки (все символы до точки, не включая точку), \. затем точку, следующую за средним инициалом \) Конец второй подстроки / Конец цепочки для организации поиска и начало замещающей це¬ почки \2 На новой строке сначала начинается вторая подстрока, \1 за ней следует пробел и затем — первая подстрока / Конец замещающей цепочки 6,8p Напечатать измененные строки В команде использован тот факт, что фамилии отделялись запятой и каждое имя заканчивалось точкой после отчества. Для простоты остальные три подстро¬ ки (рост, вес и команда) игнорировались в замещающей цепочке. Чтобы манипу¬ лировать также и ими, мы должны были бы ссылаться на них следующим обра¬ зом: \3, \4 и \5. 2. Поэкспериментируйте с этой полученной (трудной для восприятия) командой. а) Подумайте, чтб дает возможность составлять и выполнять такие команды. б) Попытайтесь придумать другие команды, подобные рассмотренной. в) Выйдите из текста и закончите сеанс редактирования:
124 Часть II Использование редактирующего текста Создание файлов Предположим, что вы имеете длинную последовательность команд ed и вам нуж¬ но использовать эти команды для редактирования более чем одного файла. Вы могли бы вызвать для редактирования первый файл, набрать все команды и вы¬ полнить их, вызвать второй файл, снова набрать команды и т. д. Редактор ed обеспечивает более легкий путь для выполнения этой работы: только один раз ввести команды редактирования в отдельный файл, затем вызывать этот файл каждый раз, когда вам нужно обработать очередной текстовый файл. Файл, ко¬ торый содержит только команды редактирования, называется командным фай¬ лом или редактирующим текстом. В рассмотренном ниже примере вы будете вво¬ дить некоторые команды в редактирующий текст, затем обращаться к редактиру¬ ющему тексту, чтобы обработать несколько текстовых файлов. 1. Начните сеанс редактирования файла и введите команды редактирования как текст. а) Начните сеанс редактирования файла switch: $ ? б) Введите команду редактирования ’’изменить расположение44, которую вы уже изучили в данной главе (с номерами строк 1, $), а также три дополнительные команды редактора ed (1, $p, w и q): __ 1,$s/A\(C\]*\), *\([A\.]*\.\)/\2 \1/ i,$p [Убедитесь, что у вас есть эти три строки] в) Сохраните этот текст и завершите сеанс редактирования: га 47 2. Начните следующий сеанс редактирования и выпишите имена игроков. а) Начните сеанс редактирования с файлом pfl.deal и выведите на экран строки с именами игроков: $|ed pfl.deal 467 8,10 p Emerson, Ezekiel R. 6'5" 273 Rochester Robinson, Charles F. 63" 287 Des Moines Peterson, Paul N. 5'9" 178 Tupelo ed switch switch
Редактирование текста с помощью редактора ed 125 б) Запишите эти строки в новый файл, называемый players.in: 8,10 w players.in 113 $ _ в) Выйдите из текста и закончите сеанс редактирования: ш $ 3. Начните следующий сеанс редактирования и введите несколько новых имен. а) Начните сеанс редактирования файла owners.in и введите пять строк: $ ed owners.in 7owners.in а Wi lliams, Kenneth L. Emerson, Patrick R. Lanier, Benjamin 6. Barton, Rudolph W. Peterson, Michael E. 6) Сохраните этот текст и закончите сеанс редактирования: И 101 И $ _ Итак, вы имеете набор команд редактирования, записанных в один файл (switch), и списки, занесенные в два других файла (players.in и owners.in). Теперь вы можете выдать команду для обработки каждого из текстовых файлов, ис¬ пользуя команды в редактирующем тексте. Так как обработка редактором ed из¬ менит входные файлы, мы будем работать с копиями первоначальных файлов. 4. Сначала сделайте копии файлов. а) Скопируйте players.in в players.out $ $ cp players.in players.out 6) Скопируйте owners.in в owners.out: $ $ cp owners.in owners.out 5. Обработайте каждый текстовый файл с помощью командного файла, а) Включите имена в players.out, используя файл switch как входной: $ ed players.out < switch 113 [113 символов на входе]
126 Часть II Ezekiel R. Emerson 6'5" 273 Rochester Charles F. Robinson 63" 287 Des Moines Paul N. Peterson 5'9" 178 Tupelo 110 [H0 символов на выходе] $ 6) Включите имена в owners.out, используя файл switch как входной: $ led owners.out < switch 101 [Ввод 101 символа] Kenneth L. Williams Patrick R. Emerson Benjamin G. Lanier Rudolph. W. Barton Michael E. Peterson 96 [Вывод 96 символов] $ Что произошло? В каждом случае вы набирали обычную командную строку ре¬ дактора ed с одним дополнительным элементом, добавленным в конце (< switch). Этим вы предписывали редактору ed принять в качестве входной информацию из файла, называемого switch, вместо стандартного ввода с клавиатуры. Редак¬ тор ed затем отсылал результаты в стандартный выходной файл (выводил их на экран). Так как стрелка направлена от имени switch, это означает, что информа¬ ция поступает из этого файла (т. e. вы переадресуете ввод). Упорядочение списка по алфавиту sort Предположим, что кроме включения фамилий с инициалами вы бы хотели упоря¬ дочить каждый из этих списков по алфавиту. Хотя редактор ed не имеет средств для обеспечения такой функции, система Юникс имеет такие средства — коман¬ ду sort (сортировать). Используем эту команду, чтобы упорядочить списки по ал¬ фавиту и ознакомиться еще с одним средством системы Юникс. 1. Так как список должен быть упорядочен по алфавиту до того, как его вклю¬ чать в файл, начните с команды sort, затем продолжайте работу с редакто¬ ром ed. а) Упорядочите файл owners.in, поместив результаты в файл, называемый temp: $ $ sort owners.in >temp б) Выведите на экран содержимое файла temp: cat temp $ | Barton, Rudolph. W. Emerson, Patrick R. Lanier, Benjamin G. Peterson, Michael E. Williams, Kenneth L. $
Редактирование текста с помощью редактора ed 127 в) Включите имена, поместив результаты в файл owners.sort: ed temp < switch > owners.sort $ г) Выведите на экран содержимое файла owners.sort: $ |cat owners.sort 101 RudoLph. W. Barton Patrick R. Emerson Benjamin G. Lanier Michael E. Peterson Kenneth L. Williams 96 $ д) Удалите первую и последнюю строки (цифры 101 и 96): owners.sort [Удалить первую строку] [Удалить последнюю строку] Rudolph. W. Barton Patrick R. Emerson Benjamin G. Lanier Michael E. Peterson Kenneth L. Williams 0 96 0 $ _ e) Удалите временный файл temp: $ ed 103 1d $d 1,$P rm temp Краткое изложение главы 9 В этой главе вы узнали, как разбить строку, как объединить строки, как переста¬ вить строку, как переместить текст из одного файла в другой и как использовать редактирующий текст. Операции над строками РАЗБИЕНИЕ строки. Чтобы разбить строку, используйте знак \, за которым следует RETURN при составлении замещающей цепочки команды s (substitute).
128 Часть II ОБЪЕДИНЕНИЕ строк. Чтобы объединить строки, используйте команду j, перед ко¬ торой наберите пару номеров строк (указывающих первую и последнюю строки, которые нужно объединить). ИзмЕНЕниЕ РАСПоложЕния ТЕКСТА в строкАХ. Используйте символы \( и \), чтобы от¬ метить подстроки каждой строки в цепочке для организации поиска команды s, затем используйте номера подстрок в замещающей цепочке, чтобы изменить по¬ рядок расположения этих подстрок. Использование редактирующего текста Введите желаемую команду (команды) в специальный файл; затем, когда вы вве¬ ли команду ed, переадресуйте ввод из специального файла, используя символ < перед именем файла. Глава 10. Выполнение команд системы Юникс при использовании редактора ed Пребывание в сеансе редактирования Предположим, что вы находитесь в середине сеанса редактирования редактором ed (или другим редактором) и вам надо выполнить команду date, чтобы опреде¬ лить время, или команду wc, чтобы определить длину файла. Обычно вы должны закончить сеанс редактирования, инициировать команду Юникс после приглаше¬ ния интерпретатора shell, затем вернуться к редактированию. Система Юникс имеет средство, которое позволяет временно переключиться на другую работу, не заканчивая сеанс редактирования: для этого надо начать команду Юникса с восклицательного знака !. Команда будет передана интерпретатору shell для вы¬ полнения без выхода из редактора ed. Это средство известно как ’’переключение в интерпретатор shelT. Проверка времени Предположим, например, что вы находитесь в середине сеанса редактирования и хотели бы проверить время. Попытаемся сделать это. 1. Начните сеанс редактирования с новым файлом. а) Начните редактирование файла spaces: $|ed spaces 7spaces б) Наберите текст с пустыми строками внутри: m
Редактирование текста с помощью редактора ed 129 This is line 1 This is Line 2 This is line 3 [Две пустые строки] [Три пустые строки] 2. Теперь проверьте время. а) Наберите восклицательный знак перед командой date: !date Tue Маг 23 11:36:43 PST 1985 ! б) Теперь вы можете завершить редактирование (или выполнять другие команды системы Юникс). Проверка длины файла В качестве другого примера вы могли бы использовать переключение (!), чтобы определить длину файла. Продолжая шаги, только что приведенные выше, вы¬ полните команду wc (подсчет слов). 1. Выведите на экран статистику по файлу barbershop: !wc barbershop 16 37 265 barbershop ! Итак, файл barbershop содержит 16 строк, 37 слов и 259 символов. 2. Запомните текст и вернитесь к приглашению интерпретатора shell системы Юникс: Выполнение программы на языке Си Пример компиляции В предыдущем разделе вы узнали, как выполнить команду системы Юникс, не выходя из редактора ed. В этом разделе мы рассмотрим эту возможность приме¬ нительно к программе на языке Си. Мы введем программу на языке Си и осущест¬ вим ее компиляцию. Предметом данной книги не является программирование на языке Си, поэтому в этой главе мы будем пользоваться только простыми про- 5—771
130 Часть II граммами на этом языке. Основное для нас — не как писать программы на Си, а как выполнить команду системы Юникс во время сеанса редактирования редак¬ тором ed. Некоторые из команд системы Юникс, которые мы используем, пред¬ ставляют собой команды компилятора Си: cc, chmod, Is и sort. Начапо работы с новым каталогом Создадим новый подкаталог в нашем начальном каталоге, чтобы хранить про¬ граммы на Си, затем переместимся в этот каталог для выполнения упражнений данной главы. 1. Создайте новый каталог. а) Из вашего начального каталога создайте командой mkdir каталог, называемый c_progs: $ mkdir c_progs $ б) Каталог создан, но вы еще находитесь в вашем начальном каталоге. 2. Перейдите из начального каталога в с progs: а) Перейдите в подкаталог c_progs командой cd: cd c_progs б) Теперь файл c_progs — ваш рабочий каталог. Любые файлы, которые вы со¬ здаете, будут заноситься в этот каталог. Ввод первой программы В этом разделе вы будете использовать редактор ed, чтобы ввести короткую про¬ грамму на языке Си, компилировать ее, внести коррекцию редактором ed, снова компилировать и затем запустить программу. Чтобы запустить Си-компилятор во время сеанса редактирования, перед командой cc наберите восклицательный знак. После завершения компиляции появится еще один восклицательный знак, и управление возвратится к редактору ed. Программа на языке Си, которую вы далее будете вводить, переводит галло¬ ны в литры для шести определенных объемов (10, 12, 14, 16, 18 и 20 гал). Вы може¬ те по желанию произвести настройку переменных, чтобы преобразовать другие объемы. Прежде чем начать шаг 1, убедитесь, что вы еще в подкаталоге c_progs. Если не уверены, используйте команду pwd, чтобы отыскать имя ваше¬ го рабочего каталога. Ввод программы Вы теперь имеете каталог для хранения двух программ на языке Си, введите пер¬ вую программу и сохраните ее в этом каталоге. 1. Начните новый сеанс редактирования. а) Наберите ed и имя файла и нажмите RETURN: $ ed metric.c
Редактирование текста с помощью редактора ed 131 6) Введите программу на Си (не включая номера строк): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 /* Print а List of conversions from gallons to liters */ main() { int low, high, incr; float gals, ltrs; low = 10; /* starting value in gallons */ high = 20; /* ending value in gallons */ incr = 2; /* increment for each step */ gals = low; whi le (gals <= high) < ltrs = (gals * 3.785) [ошибкавэтойстроке] printf("%4.0f %6.2f\n", gals, ltrs); gals = gals + incr; > 370 2. Скомпилируйте программу, не выходя из редактора ed. а) Наберите \ccmetric.c и нажмите RETURN: !cc metric.c б) Компилятор Си в ответ выдаст следующие сообщения: )cc metric.c metric.c:15: Expression syntax metric.c:15: Unknown character metric.c:17: f undefined metric.c:17: n undefined ! Выполнение коррекций Напомним еще раз, что ваша работа заключается в том, чтобы исправить ошибки, выявленные компилятором Си, перекомпилировать программу и попытаться ее запустить. Хотя в данном случае появилось четыре сообщения об ошибках, в дей¬ ствительности имеется лишь одна ошибка (пропущена точка с запятой). 5*
132 Часть II 1. Вернитесь в редактор ed, чтобы вывести на экран строку с ошибкой, а) Наберите 14p, чтобы вывести на экран строку с ошибкой: г*«л ltrs = (gals * 3.785) б) Наберите s/$/;/p, чтобы добавить пропущенную точку с запятой и вывести на экран скорректированную строку: l.ifpJ ltrs = (gals * 3.785) |s/$/;/p ltrs = (gals * 3.785); в) Сохраните коррекцию: И 371 В данном случае, вместо того чтобы разрешить компилятору cc посылать вы¬ ходную информацию в стандартный выходной файл a.out, мы переадресуем ее в другой файл. 2. Перекомпилируйте программу, не выходя из редактора. а) Используйте опцию -о, чтобы переадресовать вывод в файл, называемый metric, и нажмите RETURN: !cc -о metric metric.c ! б) Компилятор Си в ответ выдаст еще один восклицательный знак, говорящий о том, что программа скомпилирована успешно. 3. Теперь вы готовы запустить программу. а) Наберите !metric и нажмите RETURN: |!metric б)10 37.85 12 45.42 14 52.99 16 60.56 18 68.13 20 I 65.70 б) Программа работает.
Редактирование текста с помощью редактора ed 133 Модификация программ Как уже говорилось выше, вы можете модифицировать программу перевода мер длины metric.c (чтобы получать другие результаты), изменяя присвоения началь¬ ных значений переменным в строках 7, 8 и 9. Например, изменяя значение low на 11, значение high на 25 и значение incr на 1, вы можете получить преобразования для 11, 12, 13, ..., 25 гал: low = 11 high> = 25 incr = 1 Ввод следующей программы на языке Си 1. Начните новый сеанс редактирования редактором ed. а) Начните сеанс редактирования нового файла, называемого compact.c: $ ed compact.c 7compact.c б) Введите и сохраните следующую программу (но не номера строк): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 а /* Remove newlines */ #include <stdio.h> main() { int с, nnl=0; while ((c=getcharO) != E0F) < if (c==*Nn*) nnl++ else nnl=0; [Описательная строка комментариев] [Стандартный файл ввода-вывода] [Начало программы] [Начало первого блока] [Объявление с как целого, nnl как целого и установка его в 0] [Считать символ;остановиться,если он является признаком конца файла (Д D)] [Начало второго блока] [Новая строка символов?] [Если да, добавить к счетчику] [Если нет, ... восстановить нулевое значение счетчика] [Меньше, чем две новые строки?] [Если да, вывести этот символ] [Конец второго блока] [Конец первого блока] [Не набирайте доставайтесь в ed] Прежде чем продолжать, рассмотрим кратко эту программу. Она принимает символы с клавиатуры и подсчитывает число последовательно встречающихся
134 Часть II символов новых строк. Каждый раз, когда существует по крайней мере два таких символа, программа игнорирует их, кроме первых двух, и переходит к следующе¬ му символу, таким образом, уплотняя файл. Строка 9 при вводе содержит ошиб¬ ку: пропущена точка с запятой. Поэтому при компиляции программы появится со¬ общение об ошибке, и вы сможете быстро исправить ошибку в строке 9. 2. Скомпилируйте программу, не выходя из редактора ed. а) Используйте символ временного переключения (!) перед cc, чтобы произвести компиляцию файла compact.c: !cc compact.c б) Компилятор Си в ответ сообщит следующее (точное содержание сообщения может отличаться в разных системах): !cc compact.c compact.c:10: Expression syntax ! Сообщение об ошибках сформировалось в строке 10, когда cc пытался компи¬ лировать compact.c. Так как была пропущена точка с запятой в строке 9, cc пошел по аварийной ветви в строке 10 и компиляция compact.c закончилась неудачно. Решение заключается в том, чтобы добавить пропущенную точку с запятой и по¬ пытаться снова запустить cc. Выполнение коррекции программы Теперь, когда вы ввели программу и провели новую компиляцию, вы готовы ис¬ править ошибку, о которой сообщил компилятор, и попытаться провести вторую компиляцию. 1. Вернитесь к редактированию и добавьте пропущенную точку с запятой, а) Наберите 9p и нажмите RETURN, чтобы вывести на экран строку 8: 9p nnl++ б) Наберите s/$/;/p, чтобы добавить пропущенную точку с запятой и вывести на экран откорректированную строку: s/$/;/p nnl++; в) Сохраните откорректированный текст: И 179
Редактирование текста с помощью редактора ed 135 2. Вторично скомпилируйте программу, не выходя из редактора ed. а) Снова используйте перед cc знак переключения (!): !cc -о compact compact.c [Направитьвывод в compact] 6) После того как cc запущен, редактор ed в ответ выдаст еще один восклица¬ тельный знак: !cc -о compact сотрас^с[Направитьвывод в compact] На этот раз компиляция прошла успешно — ошибок нет. Если вы не определили другой файл, компилятор cc помещает результаты компиляции в файл, называе¬ мый a.out. Это стандартный выходной файл для cc. Однако, используя опцию-о для компилятора cc, мы уже направили выходной поток в файл compact. Запуск программы Так как compact.c скомпилирован успешно, вы теперь готовы к запуску программы. Отметим, что compact — выполняемый файл. Это означает, что для запуска программы вы должны набрать compact после приглашения интерпретатора shell. Однако, так как вы еще продолжаете сеанс редактирования, вы не увидите приглашения интерпретатора shell. 1. Запустите программу. а) Скопируйте файл spaces из файла text_files в файл c_progs: !cp ../text_files/spaces spaces б) Используйте снова символ переключения (!^, чтобы запустить compacV. !compact < spaces в) На экране появится вывод: This is h'ne 1 This is line 2 This is line 3 ! [Конец вывода программы] Эта программа иллюстрирует один из методов устранения лишних пустых строк из файла. Вы могли бы также проделать это командой s. 22. Закончите сеанс редактирования, набрав q.
136 Часть II Дополнительные сведения о программировании на языке Си В этой главе вы немного поработали с языком Си — языком, на котором написа¬ на большая часть системы Юникс. Если бы вы захотели узнать о языке Си боль¬ ше, вам потребовалась бы другая книга. В данной книге нет возможности под¬ робно изложить язык Си, поэтому ниже приводится только некоторый список ли¬ тературы. CProgramming Guide by Jack Purdum, Que Corporation, Indian- apoUs, Indiana 46250 (1983) Learning to Program in C by Thomas Plum, Plum HaU, Cardiff, New Jersey 08232(1983) Programming in C by Stephen G. Kochan, Hayden Book Com¬ pany, Inc., Hasbrouck Heights, New Jersey 07604 (1983) The C Programming Language by Brian W. Kernighan and Den¬ nis M. Ritchie, Prentice-HaU, Inc., Englewood Cliffs, New Jersey 07632 (1978) The UNIX Programming Environment by Brian W. Kernighan and Rob Pike, Prentice-НаИ, Inc., Englewood CUffs, New Jersey 07632 (1984) Другие языки программирования Хотя с самого начала при разработке системы Юникс использовался язык Си, не¬ которые другие популярные языки программирования для микроЭВМ, такие, как Фортран и Паскаль, также включены в систему Юникс. Стандартный компилятор с Фортрана, называемый f77, компилирует исходные программы в файлы, кото¬ рые заканчиваются .f. Широко используемый компилятор с языка Паскаль из Ка¬ лифорнийского университета, называемый pc, компилирует исходные программы в файлы, которые заканчиваются .p. Оба этих компилятора, подобно Си, помеща¬ ют выполняемые программы, полученные после компиляции, в файл a.out, если не указан другой выходной файл. Все три компилятора (Си, Фортран и Паскаль) имеют опцию -о, которая позволяет направлять выходной поток в другой файл. Наконец, существует еще один язык, тесно связанный с системой Юникс, кото¬ рый рассматривается ниже в книге. Вы имеете дело с интерпретатором shell си¬ стемы Юникс почти с тех пор, как приступили к чтению данной книги. Интерпре¬ татор shell — это процессор команд, который принимает каждую вводимую вами команду, проверяет факт выполнения команды и затем посылает вам результа¬ ты. Однако shell представляет собой также язык, который вы можете использо¬ вать для написания программ, называемых процедурами shell (гл. 21—27). Для выполнения некоторых работ вы можете предпочесть пользование процедурами shell потому, что они не требуют компиляции и хранения специального файла. Для других работ вы можете предпочесть использование программ на Си потому, что они лучше производят символьную обработку. Для третьих работ вы можете использовать Фортран, Паскаль или другой язык, имеющийся в вашей системе. • Краткое изложение главы 10 В этой главе вы узнали, как выполнять команды системы Юникс, не выходя из редактора ed. В качестве примера выполнения команд системы Юникс вы вводи¬ ли, компилировали и запускали две программы на языке Си.
Редактирование текста с помощью редактора ed 137 Прерывание редактирования Чтобы прервать редактирование редактором ed для выполнения еще одной ко¬ манды системы Юникс, наберите восклицательный знак (!), название команды и нажмите RETURN. После того как команда Юникс будет выполнена, вы сможете вернуться в редактор ed, который останется неизменным в том же состоянии. Подготовка программы на языке Си Чтобы подготовить к запуску программу на языке Си, вы должны выполнить сле¬ дующие шаги. Ввод исходного ТЕКСТА. Вызовите редактор ed или другой текстовый редактор, введите программу и занесите ее в файл (с суффиксом .c). Компиляция ПРОГРАММЫ. Используйте компилятор cc, посылая объектные коды или в стандартный выходной файл a.out: !cc fi Le.c или в ваш файл: !cc -о ex.fi Le fi le.c ВыполнЕНИЕ КОРРЕКЦИИ. Так как вы находитесь еще в редакторе ed, то можете лег¬ ко выполнить коррекцию любых ошибок, о которых сообщил cc, используя коман- ДУ s. Здпуск ПРОГРАММЫ. Чтобы запустить программу, наберите только имя выходного файла, созданного компилятором cc. Другие языки программирования Фортран — это стандартный язык, но Паскаль и другие языки также имеются во многих системах Юникс. Компилятор с Фортрана f77 компилирует программу, хранящуюся в исходном виде в файлах, заканчивающихся .f; один из компилято¬ ров Паскаля, pc, компилирует исходный текст, хранимый в файлах, которые за¬ канчиваются .p. Оба этих компилятора, подобно Си, позволяют направлять вы¬ ходной поток в другой файл с помощью опции -о.
Часть III. Редактирование текста с помощью редакторов vi и ex Глава 11. Введение в визуальный редактор vi Обозначения vi и ex — два различных имени расширенной версии редактора ed. Эта программа работает как экранно-ориентированный редактор при обращении по имени vi и как строчно-ориентированный редактор при обращении по имени ex. Редактор vi (начальные буквы словосочетания visual interpreter — визуальный интерпретатор), разработанный в Калифорнийском университете Вильямом Джо¬ ем, может быть включен или не включен в вашу систему Юникс. Поскольку версия vi использует весь экран, так же как распространенные программы обработки слов, то вы найдете ее весьма удобной для работы. Одна¬ ко вы не сможете сразу вызвать программу и начать ее использовать подобно то¬ му, как это вы делали с редактором ed. Сначала вы должны убедиться, что си¬ стема Юникс располагает подробной информацией о вашем терминале. (Это со¬ ответствует выполнению процедуры installation для некоторых программ обра¬ ботки слов.) Чтобы определить, подготовлена ли ваша система Юникс для работы с вашим терминалом, перейдите к следующему разделу книги и исследуйте вызов vi. Если на вашем экране появится правильное, как описано, изображение, то вы можете завершить изучение оставшейся части этой главы. Однако, если появится иска¬ женное изображение или совсем не появится, обратитесь к приложению 8 (опи¬ сание терминала для редактора vi). Затем следует возвратиться к этой главе и продолжить ее чтение. Набор текста письма Если кем-либо был определен ваш терминал через shell системы Юникс, как это описано в приложении 8, вы можете вызывать vi и начинать набор письма. Начало работы с новым каталогом Выше уже говорилось о том, что одним из путей полного использования возмож¬ ностей файловой системы Юникс является организация вашего начального ката¬ лога в виде совокупности подкаталогов для различных видов файлов. Если вы не изучали работу редактора ed в этой книге, эту главу следует начать с созда¬ ния нового подкаталога в вашем начальном каталоге, куда помещаются ваши vi- файлы, а затем обратиться к этому каталогу с примерами данной главы. 1. Создайте новый подкаталог (только в том случае, если вы пропустили ч. II книги). а) Создайте каталог text files по команде mkdir: $ $ mkdi г text fi Les
Редактирование текста с помощью редакторов vi и ex 139 6) Каталог создан, но вы еще находитесь в вашем начальном каталоге. 2. Перейдите из вашего начального каталога к text files. а) Перейдите к подкаталогу text files по команде cd: $ $ cd text files 6) Теперь вашим текущим каталогом является text_files (удостовериться в этом можно по команде pwd, т. e. по команде print working directory — получить имя текущего каталога). Любой создаваемый вами файл будет храниться в этом каталоге. 3. Вызовите визуальный редактор vi. а) После приглашения со стороны shell системы Юникс наберите текст vi letter и нажмите клавишу RETURN: vi letter б) Через некоторое время экран будет очищен и на нем появится следующее: "letter" [Новый файл] В ранних версиях vi последняя строка (статусная строка) выглядела следую¬ щим образом: "letter" No such file or directory Число строк, которое представлено на экране дисплея, зависит от типа терми¬ нала. Набор первого наброска При наличии запущенного в работу редактора vi и поименованного файла вы го¬ товы к тому, чтобы начать вводить текст вашего письма. 1. Подключение. а) Наберите символ а (без нажатия клавиши RETURN) для подсоединения текста в режиме text entry (ввод текста). б) Символ а не появится на экране, но после его однократного набора вы може¬ те начинать вводить текст.
140 Часть III 2. Набор нескольких строк текста. а) Наберите следующий текст, нажимая клавишу RETURN в конце каждой строки: Dear Mr. Fenton: RETURN RETURN We can't do the job you asked for. RETURN We don*t know what we're doing. RETURN RETURN б) Текст будет появляться на экране по мере того, как вы его набираете, причем каждая новая строка начинается со знака ~ . 3. Возврат в командный режим vl. а) Нажмите клавишу ESC (escape — знак переключения) для выхода из режима text entry (ввод текста). б) Экран дисплея останется без изменения, но переход в командный режим vi будет осуществлен. В этом режиме вы можете вводить команды. 4. Попытайтесь выполнить команду повторения (repeat command). а) Наберите точку (без нажатия клавиши RETURN), чтобы повторить только что набранный вами текст. б) На экране появится следующее сообщение: Dear Мг. Fenton: We can't do the job you asked for. We don't know what we're doing. Dear Mr. Fenton: We can't do the job you asked for. We don't know what we're doing. После набора точки . редактор vi повторил текст из пяти строк (включая две пустые строки). Знак _ указывает расположение курсора на экране. Неиспользо¬ ванные строки ниже текста начинаются, как и прежде, со знака ~ . 5. Попытайтесь выполнить команду аннулирования u (undo command): а) Наберите символ u, чтобы аннулировать только что внесенную вами вставку. б) На экране снова появится следующее: Dear Мг. Fenton: We can't do the job you asked for. We don't know what we're doing.
Редактирование текста с помощью редакторов vi и ex 141 в) Наберите снова символ u, чтобы восстановить вставку. г) Наберите символ u еще раз, чтобы удалить вставку. Вы можете пользоваться командой аннулирования для устранения ошибки. При аннулировании проводится действие над наиболее поздними изменениями. Отметим, что при исполнении команды u дважды подряд будет производиться аннулирование действия предшествующей команды аннулирования. 6. Запишите текст в файл. а) Наберите символы :w и нажмите клавишу RETURN, чтобы записать данный текст письма. б) Прежде всего вы увидите символы :w в нижней части экрана; далее на ста¬ тусной строке вы увидите следующее сообщение: "letter" [New file] 6 lines, 88 characters Знак двоеточия : всегда означает временную смену командного режима ex, из которого вы можете использовать ех-команды — в данном случае использована команда w (write — писать). Внесение даты Добавим к тексту письма дату. Для этого подведем курсор к началу экрана и от¬ ведем место для следующей строки текста. 1. Сдвиг курсора в начало экрана. а) Нажмите клавишу SHIFT и наберите прописную букву H, чтобы перевести кур¬ сор в верхний левый угол экрана. б) На дисплее появится следующее сообщение: Dear Mr. Fenton: We can't do the job you asked for. We don't know what we're doing. 2. Начните новую строку сверху. а) Нажмите клавишу SHIFT и наберите прописную букву О, чтобы начать новую строку, находящуюся над первой строкой текста. б) Теперь имеется пустая строка над первой строкой текста при расположении курсора в самой левой позиции. 3. Набор даты. а) Наберите дату на пустой строке и нажмите клавишу RETURN. б) На дисплее появится следующее: March 17, 1985 Dear Mr. Fenton: We can't do the job you asked for. We don't know what we're doing.
142 Часть III 4. Возврат в командный режим vi. а) Нажмите клавишу ESC для возврата в режим ввода текста. б) Вы должны делать это всякий раз, когда заканчиваете набор нового текста. В противном случае редактор vi будет интерпретировать ваше последующее на¬ жатие клавиши как последующий символ текста вместо команды. Внесение нового раздела1) После внесения в текст даты и выбора режима vi вы можете внести в текст но¬ вый раздел. Для этого вы должны сдвинуть курсор вниз и выбрать режим встав¬ ки. 1. Сдвиг курсора вниз. а) Наберите дважды /, чтобы передвинуть курсор вниз на пустую строку после приветствия в письме. б) Если ваш терминал имеет клавиши управления курсором, помеченные стрелка¬ ми (и запись в файле termcap позволяет это), можете воспользоваться клави¬ шей "стрелка вниз“, т.е. 1, вместо символа /. 2. Подготовка к вставке нового раздела. а) Для выполнения вставки в режиме ввода текста наберите символ /. б) На экране вы не увидите символа / и изображение останется прежним: March 17, 1985 Dear Мг. Fenton: We can't do the job you asked for. We don't know what we're doing. 3. Вставка нового раздела. а) Нажмите клавишу RETURN, чтобы перейти с пустой строки после приветствия в письме. Затем наберите новый текст, нажимая клавишу RETURN после набо¬ ра каждой строки: Thank you for your recent letter. RETURN It is aLways а deLight to read RETURN your ideas. RETURN 1) Под разделом понимается объединение нескольких смежных строк текста. Границами раздела являются пустые строки. Эквивалентное название раздела — абзац, который так¬ же используется в тексте. — Прим. ред.
Редактирование текста с помощью редакторов vi и ex 143 б) На дисплее появится следующее: March 17, 1985 Dear Мг. Fenton: Thank you for your recent letter. It is always а deLight to read your 1deas. We can't do the job you asked for. We don't know what we're doing. 4. Возврат в командный режим, vi. а) Нажмите клавишу ESC, чтобы выйти из режима ввода текста. б) Не забудьте возвратиться в командный режим vi после окончательного фор¬ мирования текста письма. 5. Повторение раздела. а) Для практики наберите точку, чтобы повторить текст только что набранного раздела. б) На дисплее появится следующее изображение: March 17, 1985 Dear Мг. Fenton: Thank you for your recent letter. It is always а delight to read your ideas. Thank you for your recent letter. It is always а delight to read your ideas. We can't do the job you asked for. We don't know what we're doing. 6. Поскольку повторение текста этого абзаца не требовалось, удалите его ко¬ пию. а) Наберите символ и (но не символ U), чтобы аннулировать действие предыду¬ щей команды. б) Скопированный текст абзаца исчезнет с экрана.
144 Часть III Добавление текста в конце письма Для набора заключительной части письма необходимо сдвинуть курсор вниз и добавить новый текст. 1. Сдвиг курсора на последнюю строку экрана дисплея. а) Нажмите клавишу SHIFT и наберите символ L для перемещения курсора на пу¬ стую строку, следующую за вторым разделом текста. б) Курсор переместится в нижний левый угол окна дисплея. 2. Повторное установление действия присоединения в режиме ввода текста. а) Наберите символ а для присоединения нового текста. б) На экране все останется без изменений, но редактор vi перейдет в состояние готовности воспринимать последующий текст. 3. Наберите окончание текста письма. а) Нажмите клавишу RETURN после набора текста каждой строки: Your most humble, obedient servant, RETURN RETURN Frank Failsquick C'Mr. Macho1') RETURN 6) На вашем дисплее появится следующее: March 17, 1985 Dear Mr. Fenton: Thank you for your recent letter. It is always a delight to read your ideas. We can't do the job you asked for. We don't know what we're doing. Your most humble, obedient servant, Frank Failsquick C'Mr. Macho'') 4 54. Возврат в командный режим vi. а) Нажмите клавишу ESC, чтобы выйти из режима ввода текста. б) Не забудьте возвратиться в командный режим vi после окончательного фор¬ мирования текста письма. 5. Запись текста в файл. а) Наберите символы :w и нажмите клавишу RETURN, чтобы записать данный текст письма.
Редактирование текста с помощью редакторов vi и ex 145 6) На экране вы увидите изображение :w, а затем в нижней части экрана сооб¬ щение: "letter" [Modified] 15 lines, 255 characters Выполнение изменений в тексте письма Имея к данному моменту завершенное письмо, сделаем определенные изменения в нем. Это поможет нам рассмотреть различные свойства редактора vi. Изменение даты Изменим дату в начале письма. Для этого сначала передвинем курсор, а затем внесем изменения. 1. Перемещение курсора вверх на первую строку. а) Нажмите клавишу SHIFT и наберите символ H, чтобы переместить курсор в верхнюю часть дисплея. б) Курсор встанет в позицию, находящуюся под буквой M в слове March. 2. Изменение слова March на слово September. а) Для изменения слова наберите символы cw. На дисплее появится следующее сообщение: Marc$ 17, 1985 б) Без нажатия клавиши пробела набрать слово September и нажать клавишу ESC. в) Первая строка текста будет выглядеть следующим образом: September 17, 1985 Команда с (change — изменить) может быть использована либо как одиночная команда, либо вместе с другими символами команд (в данном случае использует¬ ся символ w, что означает word (слово)). Символ, который следует за командой с, определяет, сколько текста будет изменено. B>i изучите способы использования команды с и другие команды с использованием символов, подобных w, в после¬ дующих главах. Изменение фамилии Изменим фамилию в строке, содержащей приветствие. Это предполагает переме¬ щение курсора в определенную позицию и осуществление двойного изменения. 1. Перемещение курсора в начало фамилии в строке с приветствием. а) Набрать косую черту /, чтобы задать поиск символов, которые следует напеча¬ тать непосредственно за ним, т. e. символы Mr. В нижней части экрана вы увидите следующее: /Mr_ б) Нажмите клавишу RETURN, чтобы начать поиск требуемой позиции курсора. в) Курсор установится в позицию под буквой M в слове Mr. на третьей строке текста письма.
146 Часть III 2. Изменение слов Ш. Fenton на слова Mrs. Benson. а) Для изменения двух слов наберите символы 2cW. На строке экрана появится следующее: Dear Mr. Fenton$ б) Без нажатия клавиши пробела наберите слова Mrs. Benson сразу же после символов 2cW, а затем нажмите клавишу ESC. в) Строка с приветствием будет выглядеть теперь следующим образом: Dear Mrs. Benson: Выполнение команд Юникс Иногда вы так усердно работаете за терминалом, что теряете представление о времени. Вместе с тем редактор vi дает вам возможность следить за временем с помощью команды data (дата) без прерывания вашей работы по редактированию. Вы можете также выполнять одновременно любую команду Юникс из редактора vi. 1. Определение времени. а) Для определения даты и времени наберите символы :!date и нажмите клавишу RETURN. б) Вы увидите на экране дисплея следующее: \~: !date [No write since last change] Mon Арг 3 13:52:27 PST 1985 [Hit return to continue] в) Как указано в подсказке в приведенном тексте в квадратных скобках, нажми¬ те клавишу RETURN для возврата в редактор vi. 2. Определение списка работающих в системе. а) Для определения списка активных пользователей наберите символы :!who и нажмите клавишу RETURN. б) Вы должны увидеть на экране сообщение, подобное следующему: : !who john tty07 Арг 3 08:43 janice tty16 Арг 3 09:17 billy tty03 Арг 3 08:24 [Нажать RETURN для продолжения работы] — Вы можете набрать аналогичным образом любую команду shell. Главное, что следует помнить: вы можете выполнить любую команду Юникс из редактора vi с помощью набора перед командой на командной строке двух символов ;/. Знак двоеточия задает ваш режим ex, восклицательный знак дает доступ к shell. Для продолжительной работы с shell вы можете использовать команду :sh, далее вы¬ полнять ваши команды, а затем набором CTRL-D перейти в редактор vi.
Редактирование текста с помощью редакторов vi и ex 147 Получение информации Прежде чем выполнять какие-либо изменения, запросим у редактора vi некото¬ рую информацию. 1. Сдвиг на определенную строку. а) Наберите 7G, чтобы перевести курсор на строку 7. б) Нажмите клавишу CTRL и наберите G (одновременно), чтобы запросить у ре¬ дактора vi статусную информацию. в) Вы увидите в нижней части экрана следующее сообщение: "letter" [Modified] line 7 of 15 —46%— В этой строке сообщается об имени вашего файла (letter), о номере строки, где остался курсор (7), общем числе строк (15) и о том, насколько далеко отстоит курсор от начала файла (46% файла), а также о том, были ли сделаны ранее из¬ менения в файле ([Modified]). 2. Переход к первой и последней строкам. а) Для перемещения курсора на последнюю строку экрана наберите символ L и повторно нажмите CTRL-G. В нижней части вы увидите следующее сообщение: "letter" [Modified] line 15 of 15 —100%— б) Наберите H и в третий раз нажмите клавиши CTRL-G, чтобы вернуться обрат¬ но на первую строку. В нижней части экрана вы увидите сообщение: "letter” [Modified] line 1 of 15 —6%— Каждый раз по мере нажатия CTRL-G редактор vi выдает статусную информа¬ цию в соответствии с положением курсора в тексте. Удаление слов Попробуем удалять пары слов, чтобы убедиться, как много общего имеют различ¬ ные команды в редакторе vi. 1. Сдвиг курсора к началу слова most в двенадцатой строке: а) Наберите /most и нажмите клавишу RETURN. б) Курсор устанавливается в позицию под буквой m слова most в словосочета¬ нии most humble. 2. Удаление слов most humble (вместе с запятой). а) Для удаления этих двух слов (и запятой) наберите символы d2W. б) Строка будет выглядеть следующим образом: Your obedient servant, 3. Аннулирование удаления. а) Поскольку заключение письма оказалось бессмысленным, восстановим его начальный текст путем набора символа u. б) Заключение письма примет первоначальную форму: Your most humble, obedient servant,
148 Часть III Установление прописных букв в словах Чтобы завершить краткое рассмотрение vi-команд, попробуем выполнить опера¬ цию установления прописных букв в словах. При этом может быть обработано любое слово; выберем слово letter на строке 5. Поскольку курсор в текущий мо¬ мент находится на строке 12, это повлечет за собой "обратный поиск" (если вы не используете команду "wrapscan", описанную в приложении 4). 1. Перевод курсора в необходимую позицию. а) Чтобы перевести курсор вверх на строку 5, наберите символы ?letter и нажми¬ те клавишу RETURN. б) Курсор теперь находится под буквой / слова letter. 2. Установление прописной буквы в слове. а) Для осуществления изменения наберите знак ’. б) Строка 5 будет выглядеть теперь следующим образом: Thank you for your recent Letter. в) Поскольку такое установление прописной буквы в слове не имеет какого-либо смысла, восстановим начальную букву путем набора команды u (аннулиро¬ вать). Запишем отредактированный текст на дисковый файл letter и передадим управ¬ ление shell Юникс. 1. Запись текста в файл letter. а) Для записи файла наберите символы :w и нажмите клавишу RETURN. б) В нижней части экрана вы увидите следующее сообщение: "letter" [Modified] 15 lines, 241 characters 2. Окончание проверки работы редактора vi. а) Для окончания проверки наберите :q и нажмите клавишу RETURN. б) На дисплее появится сообщение, показывающее, что вы вышли из редактора vi и возвратились в shell Юникс: Отметим, что vi дает возможность объединять команды записи и выхода в од¬ ну команду: Окончание процесса редактирования Пя] $ m $ $ $ или или
Редактирование текста с помощью редакторов vi и ex 149 Краткое изложение главы 11 В этой главе вы изучили процедуры предварительной подготовки и некоторые общие процедуры vi, такие как начало работы, ввод текста, вставка нового текс¬ та, проведение изменений и окончание работы. ПодготовкА СЕАНСА РАБОТЫ. Прежде чем использовать редактор vi, у вас должна быть полная уверенность в том, что выполнены следующие две операции: • Кто-то подсоединил ваш терминал к файлу /etc/termcap. • Вам присвоено одно из имен вашего терминала shell-переменной TERM и значе¬ ние TERM передано в систему (два шага в В-shell и один шаг в C-shell). B*sheU C-sheU $[TERM=adm3; export TERM| % setenv TERM adm3 Вызов РЕДАКТОРА vi. Для вызова vi осуществляется набор символов vi, указание объема памяти и имени файла. Для работы с новым файлом необходимо очи¬ стить экран и перейти в командный режим vi. Для существующего файла его со¬ держание отобразится на экране. ВстАВКА ТЕКСТА. Для вставки текста набрать символ а (append — подсоединить), / (insert — вставить) или одну из нескольких других букв без нажатия клавиши RETURN. Затем ввести текст и нажать клавишу ESC для возврата в командный режим vi. ПовтоРЕниЕ и АннулировАНИЕ. К числу двух наиболее важных команд в редакторе vi относятся команда повторения (.), которая приводит к повторению выполнения самой последней команды, и команда аннулирования (u), которая аннулирует действие, произведенное самой последней командой. ОБРАЗОВАНИЕ новой строки. Для образования новой пустой строки для вставки но¬ вого текста используется либо команда о (образовать пустую строку под текущей строкой) или команда 0 (образовать пустую строку над текущей строкой). Затем ввести текст и нажать клавишу ESC для обеспечения возврата в командный ре¬ жим vi. ВстАВКАТЕКСТА. Для вставки нового текста используется либо команда i (вставить перед курсором), либо команда I (начать вставку с первой позиции текущей стро¬ ки). Ввести текст, затем нажать.клавишу ESC для возврата в командный режим vi. ИзмЕНЕНИЕ ТЕКСТА. Для изменения слова перевести курсор под первую букву сло¬ ва, затем набрать символы cw или cW (change word — изменить слово) и без про¬ бела набрать новое слово и нажать клавишу ESC. Для изменения двух слов ис¬ пользовать символы 2cw или 2cW, а для изменения трех слов — символы 3kw или 3cW. Поиск. Для организации поиска набрать либо косую черту / (поиск вперед), либо вопросительный знак ? (поиск назад). За этим знаком набрать сразу номер желае¬ мой строки и нажать клавишу RETURN. ВыполнЕНИЕ комАнд юникс. Для выполнения команд Юникс до окончания вашей работы с редактором vi набрать символы :/, вслед за которыми набрать имя ко¬ манды и нажать клавишу RETURN (использовать символы :sh для порождения subshelPj. ОПРЕДЕЛЕНИЕ ТЕКУЩЕй позиции в ТЕКСТЕ ФАЙЛА. Для определения вашего относитель¬ ного расположения в тексте нажать CTRL-G для вывода на экран изображения, подобного следующему: "letter" [Modified] line 15 of 60 --25%--
150 Часть III УДАЛЕНИЕТЕКСТА. Для удаления слова подвести курсор под первую букву слова, за¬ тем набрать символы dw или dW (delete word — удалить слово). Для удаления двух слов использовать символы d2w или d2W, а для удаления трех слов — сим¬ волы d3w или d3W. ИзмЕНЕНИЕ шриФТА БУКВ. Для изменения строчной буквы на прописную, и наоборот, установить курсор под буквой в командном режиме vl и набрать знак ~ Символы, не относящиеся к алфавиту, не обрабатываются. ОкончАНИЕ РАБОты. Чтобы закончить работу с редактором vi, набрать символы :w для печати текста файла, затем набрать :q для окончания работы (qult — выход) и возвратиться в shell Юникс. Можете также объединить эти две команды в од¬ ну: ;wq или га или _ZZ J $ $ Рис. 11.1. Схема переходов между режимами работы.
Редактирование текста с помощью редакторов vi и ex 151 Глава 12. Выполнение изменений с помощью редактора vi После рассмотрения некоторых наиболееобщих свойств редакторау| в предыдущей главе ниже мы изучим эти свойства более подробно. Начнем это изучение с органи¬ зации входа в новый сеанс работы с редактором и с представления системе при раз¬ личных вариантах перемещения курсора по экрану дисплея. Начало новой работы Потребуется немного изменений, если вами закончено изучение предыдущей главы. Предварительно сделаем короткое замечание о возврате в редактор vi к тому же файлу, с которым проводилась работа в гл. 11. 1. Перейдите к вашему начальному каталогу text _ files. а) Используйте команду cd (change directory — изменить каталог) следующим обра¬ зом: $ $ б) Для проверки используйте команду pwd: $ pwd /usr/robin/text_files $ _ 2. Вызовите тот же файл (letter). а) После знака приглашения $ наберите vi letter и нажмите клавишу RETURN: $ vi letter б) Через некоторое время экран очистится и на нем появится текст вашего письма. При этом курсор будет установлен в начало первой строки: September 17, 1985 Dear Mrs. Benson: Thank you for your recent letter. It is always a delight to read your ideas. We can't do the job you asked for. We don't know what we're doing. Your most humble, obedient servant, Frank Failsquick ("Mr. Macho") cd text files "letter" 15 lines, 255 characters
152 Часть III Перемещение курсора Для эффективного использования редакторау| вам необходимо научиться переме¬ щать курсор из одной позиции в другую. Это также поможет вам изучить работу ре¬ дактора vl, так как многие функции редактора становятся рабочими лишь при опре¬ деленном положении курсора. В этом разделе вы узнаете, как использовать опреде¬ ленные символы для установки курсора в определенную позицию на экране. Ниже в главе вы узнаете, как использовать многие из этих символов с операторами редак¬ тора vi для осуществления проверочных функций. Перемещение символа Ваша клавиатура может иметь отдельную панель управления курсором с изображе¬ нием стрелок на клавишах (рис. 12.1). В этом случае вы можете использовать эти кла¬ виши для перемещения курсора на одну позицию в указанном направлении. При от¬ сутствии таких клавиш вы должны использовать клавиши с символами h, j, k и I (рис. 12.2). Некоторые операторы предпочитают использовать эти клавиши, даже когда имеются клавиши со стрелками. Нажмите клавишу«сдвигвниз» (I или^иподержите ее нажатой в течение 5 с , чтобы перевести курсор на шестую строку письма (It is always ...). Теперь попробуйте поработать со всеми четырьмя клавишами для дости¬ жения такого же эффекта. Затем после окончания практических занятий переведи¬ те курсор на начало пятой строки (Thank you ...). Рис. 12.1. Рис. 12.2. ^ 4 Влево Вверх \ CTRL L»J CTRL lJjj ( > CTRL P f N space V Вниз 4 Вправо Рис. 12.3. Кроме этого, имеется другой набор клавиш (рис. 12.3), который работает в случае использования другой версии редактора vi (не беспокойтесь, клавиша space (про¬ бел) не сотрет ваш текст).
Редактирование текста с помощью редакторов vi и ex 153 Перемещение слова Вы можете с помощью клавиши для перемещения курсора переместить целое слово либо вперед [клавиша w (forward)], либо назад [клавиша b (back)]. Нажимайте клавишу w в течение -10 с , а затем клавишу b. Вы убедитесь, что конец одной строки непре¬ рывно движется к началу следующей, и наоборот. Когда осуществляется замена строчных букв на прописные, эти две клавиши выполняют похожие функции. Кла¬ виши W и В "игнорируют" знаки препинания. Если вы используете клавиши w или b,. курсор будет останавливаться на знаках препинания. Две команды e и E позволяют перемещать курсор к последнему символу слова. Отметим, что вы можете набирать множитель перед символом команды для ука¬ зания коэффициента пересчета числа шагов перемещения, например 2 w, 3 w и т. д. Перемещение предложения Клавиши с изображением левой и правой круглых скобок (могут быть заменены кла¬ вишами с символами 9 и 0) обеспечивают перемещение курсора к началу текущего предложения в случае использования левой скобки или к концу — при правой скоб¬ ке. Отметим, что редактор vi рассматривает предложение законченным, если за ним следуютдва пробела (или пустая строка), что дает возможность пометить конец предложения. Проверьте действие этих клавиш. Так же как и выше, вы можете использовать множители 3(, 4) и т. д. Перемещение раздела Клавиши с изображением левой и правой фигурных скобок обеспечивают возмож¬ ность перемещать курсор к началу текущего раздела в случае использования ( или к концу в случае). Обычно редактор vi рассматривает в качестве разделителей разде¬ ла пустые строки. Однако если вы пишете программу на языке Си, то можете изме¬ нить разделители на фигурные скобки, которые определяют границы блоков кода. Более подробно эти возможности рассмотрены в гл. 17. Исследуйте теперь дейст¬ вие этих двух клавиш. Вы можете использовать множители 3[, 5] и т. д. Перемещение курсора в начало или конец строки Имеются две клавиши для обеспечения перемещения курсора к началу (клавиша д) и к концу (клавиша $) текущей строки (те же два символа используются редактором ed). Символ 0 вызывает подобное действие. Он также обеспечивает перемещение курсора в начало строки. Однако при нажатии 0 курсор перемещается к левому краю строки, а клавиша д перемещает курсор только к первому видимому символу. Осу¬ ществите несколько переводов курсора с помощью этих клавиш. Перемещение курсора в начало и конец экрана Клавиши с символами H и L дают возможность передвигать курсор к началу (клави¬ ша H) и к концу (клавиша L) экрана. Можете запомнить эти символы как начальные буквы слов home (возврат в начало) и lower left (нижний левый). Проверьте действие этих клавиш.
154 Часть III Перемещение к середине экрана С помощью клавиши M (middle — середина) курсор перемещается в середину экрана. Проверьте действие этой клавиши вместе с клавишами H и L. Перемещение на заданную строку Клавиша G (Go to) дает возможность переводить курсор на любую строку текста в бу¬ фере редактирования независимо от того, отображается или не отображается стро¬ ка в текущий момент времени на экране. Ha6op2G, 5G и т. д. позволит вам перейти ко второй, пятой и т. д. строкам. Но для этого необходимо знать номер требуемой строки. Подробно эти вопросы рассмотрены в гл. 17. Отметим, что сам символ G означает последнюю строку файла и нажатие CTRL-G дает ответ на вопрос: "Какой номер текущей строки?“. Проверьте эти варианты. Перемещение курсора к парной скобке Если в текущий момент курсор находится под любым из символов скобок (круглые, квадратные или фигурные скобки), вы можете использовать символ процента % для перемещения курсора к парной скобке. Для этого установите курсор на послед¬ нюю строку текста и проверьте действие клавиши % на примере выражения, заклю¬ ченного в скобки (”Mr. Macho“). Подвод курсора к символу T или t Чтобы подвести курсор к символу на текущей строке, используйте команду T для пе¬ ремещения влевго и команду t для перемещения вправо. После установления курсора на требуемую строку наберите Tx или tx (где x — выбранный вами символ). Курсор перейдет на позицию рядом с первым в тексте искомым символом. Проверим дейст¬ вие этой команды на примере последней строки текста письма. 1. Переместите курсор к слову Мг.. а) При положении курсора в начале последней строки текста письма (под буквой F в слове Frank)*Hаберите tM. б) Вы увидите, что курсор перейдет в позицию перед словом Мг.: Frank Failsquick CJMr. Macho") 2. Переместите курсор к слову Macho. а) Для повторения перемещения наберите tM. б) Теперь курсор перейдет в позицию перед словом Macho.: Frank Failsquick ("Mr.__Macho") 3. Переместите курсор назад к слову Failsquick. а) Наберите TF. б) Вы увидите, что курсор перейдет к букве а в слове Failsquick. Frank*Failsquick (мМг. Macho") 4. Переместите курсор к слову Frank. а) Снова наберите TF, чтобы продолжить движение курсора. б) Вы увидите, что курсор перейдет к букве г в слове Frank: Frank Failsquick ("Мг. Macho")
Редактирование текста с помощью редакторов vi и ex 155 Замечание о клавишах перемещения курсора Для того чтобы использовать любую из описанных выше клавиш перемещения курсо¬ ра, вы должны находиться в командном режиме vi. (Для возврата в командный ре¬ жим vi следует нажать клавишу ESC. Если вы услышите звуковой сигнал, ваш терми¬ нал уже находится в этом режиме.) Ни одна из клавиш перемещения курсора не бу¬ дет работать после входа в один из режимов вставки текста. Использование маркеров Маркировка позиции Вы можете установить в любом месте в рабочей области маркер позиции по коман¬ де m. Для этого передвиньте курсор к желаемой позиции и наберите m, а затем лю¬ бую строчную букву алфавита, которая становится именем позиции маркера. Перемещение маркера После установления по команде m маркера в рабочей области, вы можете переме¬ щать курсор к маркеру, используя одиночные кавычки любого из двух типов. Набе¬ рите одиночную кавычку ‘ и первую букву имени маркера для перемещения курсора к требуемой позиции маркера. Наберите теперь символ обычной кавычки ’, затем букву имени маркера для перемещения курсора к началу строки, которая содержит этот маркер. Управление экраном дисплея Смещение содержимого экрана Имеется пара клавиш, с помощью которых можно сместить содержимое экраналибо на строку вверх (клавиша CTRL-U), либо на строку вниз (клавиша CTRL-D). Если курсор находится в верхней части экрана, смещение содержимого экрана вверх может вы¬ звать «сброс» курсора на последнюю строку экрана. Если же курсор находится в нижней части экрана, смещение содержимого экрана вниз может вызвать «сброс» курсора на первую строку экрана. Для проверки действия этих клавиш переместите курсор на последнюю строку (L), наберите команду а для ввода некоторой части текста, нажимайте на клавишу RETURN в течение - 12c, затем нажмите клавишу ESC. После этого вы можете прове¬ рить действие клавиш CTRL-U и CTRL-D. Листание страниц Редактор vi позволяет использовать клавиши CTRL-B для листания страниц назад и клавиши CTRL-F для листания страниц вперед («листание страниц» означает смеще¬ ние текста на один полный экран). Когда вы будете работать с длинными текстами документов, вы обнаружите, что эта возможность создает большие удобства. После того как вы поработаете с этими клавишами, можете сместить дополни¬ тельные пустые строки путем выхода из текста (: q!). Затем начните работу снова (vi letter).
156 Часть III Перестановка текущей строки В редакторе vl имеется команда, которую можно использовать для переустановки текущей строки в поле экрана — это команда z (zero screen — очистить экран). Для размещения текущей строки в верхней части экрана наберитеги нажмите RETURN, в середине экрана наберите7.,адля размещения в нижней части экрананаберитег-. Эта команда может иметь несколько вариантов. Если вы наберете номер строки перед символом z, эта строка будет размещена в верхней части экрана; если вы на¬ берете номер после z, поле вашего экрана уменьшится (или увеличится) до данного числа строк. Например, набор 15z приведет к размещению строки с номером 15 в на¬ чале экрана. Ha6opz72 сократит поле экрана вашего дисплея до 12 строк. Стирание системных сообщений Вы можете использовать две взаимосвязанные команды для стирания системных сообщений на вашем экране: CTRL-R и CTRL-L. Они будут стирать системные сообще¬ ния на экране, но оставлять неизменным текст в вашей рабочей области. Добавление нового текста В гл. 11 говорилось о том, что имеются три варианта добавления нового текста в ре¬ дакторе vi без изменения существующего текста: • подсоединение текста (в конец существующего); • вставка текста (перед существующим); • резервирование места для новой строки текста. В этой главе рассмотрим каждую из этих возможностей более подробно. Подсоединение текста Для подсоединения текста на экране вы можете использовать одну из двух команд: команду а, которая позволяет добавить новый текст непосредственно за курсором, или команду А, которая позволяет добавить текст к концу текущей строки. Рассмот¬ рим каждую из них, используя вторую строку первого параграфа (строка 6) в тексте письма. 1. Переместите курсор в позицию. а) В командном режиме vi наберитебЭ для перемещения курсора на строку 6. б) Для перемещения курсора по строке к букве а наберитеЗ^. в) Строка будет выглядеть следующим образом: It is always а deLight to read 2. Присоедините слово special (с предшествующим пробелом) после буквы а. а) В командном режиме vi наберите а для подсоединения текста после курсора. б) Наберите слово special и нажмите клавишу ESC для возврата в командный режим vi. 3. Присоедините слово and enjoy (с предшествующим пробелом) к концу строки. а) Для подсоединения текста к концу строки наберите А в командном режиме vi. б) Наберите слова and enjoy и нажмите ESC для возврата в командный режим vi. в) Теперь строка будет иметь следующий вид: It is always а special delight to read and enjo^ На этих трех примерах вы смогли убедиться, что vi-команды имеют один смысл при использовании строчных букв (а) и другой — при использовании прописных (А).
Редактирование текста с помощью редакторов vi и ex 157 Вставка текста i и I Для того чтобы вставить текст перед существующим на экране текстом, можете ис¬ пользовать одну из двух команд: команду i, которая позволяет подсоединить текст непосредственно перед курсором, и команду I, которая позволяет подсоединить но¬ вый текст с начала текущей строки. (Если текст начинается с абзаца, можете исполь¬ зовать команды Oi или Ol). Рассмотрим действие команд i и I для строки 5 в письме. 1. Переместите курсор в позицию. а) Для перемещения курсора на строку 5 наберите k (или I) в командном режиме vi. б) Наберите четыре раза b для перемещения курсора от конца строки к букве f в сло¬ ве for. в) Строка будет иметь следующий вид: Thank you for your recent letter. 2) Вставьте слово — profusely (с отслеживанием пробела) перед словом for. а) Для вставки текста перед курсором наберите / в командном режиме vi. б) Наберите слово profusely и нажмите клавишу ESC (для возврата в командный ре¬ жим vi). 3. Вставьте в начало строки слова / wish to (с отслеживанием пробела). а) Для осуществления вставки текста в начале строки наберите / в командном режи¬ ме vi. б) Наберите слова / wish to и нажмите клавишу ESC для возврата в командный режим vi. 4. Замените прописную букву T на строчную t в словах Thank you. а) Для смещения курсора к букве T наберите W. б) Для замены буквы T на t наберите знак -. в) Теперь строка будет иметь следующий вид: I wish to thank you profusely for your recent letter. Образование новой строки о и О Вы можете зарезервировать место для новой строки под текущей строкой (команда о) или над текущей строкой (команда О). Рассмотрим действие этих команд на при¬ мере последней строки в тексте письма. 1. Переместите курсор в позицию. а) Для перемещения курсора на последнюю строку текста наберите G, а затем k. б) Курсор установится в начало строки (для этих команд не имеет значения, где на¬ ходится курсор на строке): Frank Failsquick (MMr. Macho") 2. Добавьте словосочетание Chief Consulting Officer, записанное в новой строке. а) Наберите о для образования новой строки под текущей. б) Наберите словосочетание Chief Consulting Officer и нажмите клавишу ESC для воз¬ врата в командный режим vi. 3. Добавьте словосочетание The Man for the Job на новой строке сверху. а) Наберите k для возврата на строку, начинающуюся словами Frank Failsquick.
158 Часть III б) Наберите 0 для образования новой строки над текущей. в) Наберите словосочетание The Man for the Job и нажмите клавишу ESC для возвра¬ та в командный режим vi. г) В окончательном виде три строки будут иметь следующий вид: The Man for the Job: Frank Failsquick ("Мг. Macho") Chief Consulting Officer Подробно эти команды рассмотрены в гл. 15. Краткое изложение главы 12 В этой главе вы научились перемещать курсор и добавлять новый текст. Перемещение курсора ПЕРЕМЕЩЕНИЕ курсоРА нА одну позицию. Возможно либо с помощью набора клавиш на панели управления курсором, либо с помощью клавиш основного наборного поля h, j, k,l. ♦ Влево Вверх Вниз Вправо I - Имеется другой набор клавиш, пригодный для любой версии vi: ^ ♦ Влево ВввР* Вниз Вправо
Редактирование текста с помощью редакторов vi и ex 159 ДРУГИЕ КОМАНДЫ ПЕРЕМЕЩЕНИЯ КУРСОРА К предыдущему слову: b К последующему слову: w В W К концу слова: e E К началу предложения: ( К концу предложения: ) К началу раздела: ( К концу раздела: К началу строки: А К концу строки: $ В верх экрана: н В низ экрана: L К середине экрана: м На строку с номером n: nG К парным скобкам: % К концу текста: G ПЕРЕМЕЩЕНИЕКСИМВОЛУ (x) Влево: Tx Вправо: tx МножитЕли. Многие из этих команд могут быть снабжены множителями: 2b, 2B, 3w, 4(, 4), 5(, 5). Управление экраном дисплея СМЕЩЕНИЕ СОДЕРЖИМОГО ЭКРАНА НА ОДНУ СТРОКУ Вверх: CTRL-U (AU) Вниз: CTRL-D (AD) СМЕЩЕНИЕ ЭКРАНА НА ОДИН КАДР(ЛИСТАНИЕ) Вперед: CTRL-F (AF) Назад: CTRL-B (лВ) РАЗМЕЩЕНИЕТЕКУЩЕЙ СТРОКИ В верхней части экрана: z RETURN В середине экрана: z. В нижней части экрана: z- ОЧИСТКА ЭКРАНА ОТ СООБЩЕНИЙ CTRL-R или CTRL-L ДОБАВЛЕНИЕ НОВОГО ТЕКСТА ПОДСОЕДИНЕНИЕ ТЕКСТА после курсора: а в конце строки: А ВСТАВКА ТЕКСТА перед курсором: i в начале строки: I ОБРАЗОВАНИЕ НОВОЙ СТРОКИ под текущей строкой: о над текущей строкой: О
160 Часть III Глава 13. Изменение и удаление текста с помощью редактора vi В главе 12 говорилось о том, как перемещать курсор, настраивать дисплей в редак¬ торе vi и добавлять новый текст. В этой главе показано, как изменять и удалять текст. Эти две функции очень похожи в редакторе vi. Изменениетекста cwnnncw До сих пор мы только добавляли текст к существующему. Для выполнения измене¬ ний в существующем тексте используются символы перемещения курсора совмест¬ но с командой изменения с с целью получения определенного числа вариантов. Ни¬ же в этом разделе мы обсудим вопрос о сдвиге текста в любом направлении. Изменение слова Команда изменения с может быть использована для изменения отдельной буквы. Но мы будем использовать другую команду для этих целей и здесь рассмотрим лишь изменение слова. Для иллюстрации действия этой команды перейдем к первой строке второго раздела письма. 1. Переместите курсор в позицию. а) В командном режиме vi наберите 7can't и нажмите RETURN (поскольку строка, к которой мы перешли, находится выше нашей начальной позиции, был использо¬ ван знак ? вместо / для организации поиска назад). б) Курсор теперь находится под буквой с на строке 9. We can't do the job you asked for. 2. Измените слово can’t на cannot. а) Для изменения слова наберите cW в командном режиме vi. б) Знак доллара появится вместо буквы t. We can'$ do the job you asked for. в) Наберите слово cannot и нажмите ESC для возврата в командный режим vi. г) Строка будет иметь следующий вид: We cannot do the job you asked for. В этом примере нами использована команда cW вместо cw, так как в середине слова can’t содержится апостроф. Применение команды cw приведет к следую¬ щему: We ca$'t do the job you asked for. Смещение курсора и vi-команды Предыдущий пример иллюстрирует свойства, которые вы вправе считать как поло¬ жительными, так и отрицательными в редакторе vi. Вспомните, что с помощью ко¬ манды W можно осуществить переход курсора к следующему слову (игнорируя знаки
Редактирование текста с помощью редакторов vi и ex 161 пунктуации): We can't do the job you asked for. We can't do the job you asked for. Если вы объединяете команду W с командой с, то вы заставляете vi изменить текст (без учета пробела), к которому был подведен курсор по команде W. Изменить текст, заключенный между стрелками: We 1 can't do the job you asked for. Ue can't do t the job you asked for. В рассмотренном примере мы могли бы использовать различные знаки, но прави¬ ло всегда остается одним и тем же: изменение начинается с того места, где в теку¬ щий момент располагается курсор, и заканчивается перед позицией, где курсор установится после перехода. Изменение словосочетания cnw или cnW Изменение словосочетания выполняется так же, как и изменение одного слова. От¬ личие состоит только в том, что перед символом w вы помещаете число, чтобы сооб¬ щить редактору vi, сколько слов необходимо изменить. Для иллюстрации использу¬ ем ту же строку1> в тексте. 1. Переместите курсор в позицию. а) Для смещения курсора к букве с в слове cannot наберите b в командном режиме vi. б) Теперь строка будет иметь следующий вид: Ue cannot do the job you asked *or. 2. Измените слова cannot do на словосочетание are unable to complete in а timely man¬ ner. а) Для изменения двух слов наберите c2w. б) Вы увидите, что знак доллара появится перед словом the: We cannot d$ the job you asked for. в) Наберите are unable to complete in а timely manner и нажмите ESC для возврата в командный режим vi. г) Теперь строка должна иметь следующий вид: We are unable to complete in а timely manner the job you asked for. Здесь было использовано правило для перемещения курсора: изменение начина¬ ется с позиции начального расположения курсора и заканчивается перед буквой t в слове the (что определяется командой 2w, осуществляющей передвижение курсора). 1) Строка, которая получена в результате работы в предыдущем разделе. — Прим. ред. 6-771
162 Часть III Изменение в начале строки с Для изменения текста от середины строки к началу используют команду с, за кото¬ рой следует знак д, что является командой перемещения курсора к началу строки. Для иллюстрации этого используем третью строку первого раздела письма. 1. Переместите курсор в позицию. а) Наберите ?ideas в командном режиме vl и нажмите клавишу RETURN. б) Курсор установится под буквой / в слове ideas. your 2deas. 2. Замените слово your треми словами. а) Чтобы осуществить изменения от начала строки до текущего расположения курсо¬ ра, наберитесд. _your$ideas. б) Сразу же после с д наберите all your extraordinary (с пробелом после буквы у) и на¬ жмите клавишу ESC для возврата в командный режим vi. в) Теперь строка должна иметь следующий вид: all your extraordinary_ideas. Изменение в конце с троки c$ Для изменения текста от какого-либо места в строке и до конца используется коман¬ да с, за которой следует знак $, что определяет команду перемещения курсора к концу строки. Для иллюстрации этого используем первую строку того же раздела письма. 1. Переместите курсор в позицию. а) Наберите 7recent в командном режиме vi и нажмите клавишу RETURN. б) Теперь курсор сместится под букву r в слове recent. I wish to thank you profusely for your recent letter. 2. Замените слова recent letter, несколькими другими словами. а) Для указания требования на изменение от места расположения курсора до конца строки наберите c$. I wish to thank you profusely for your recent letter$ б) Сразу же после символов c$ наберите слова letter of March 2. и нажмите клавишу ESC для возврата в командный режим vi. в) Теперь строка будет иметь следующий вид: I wish to thank you profusely for your letter of March 2^ Изменение полной с троки cc Одно из правил редактора vi для большинства команд заключается в следующем: чтобы действие команды распространялось на всю строку, наберите эту команду дважды. В соответствии с этим правилом команда для изменения строки будет иметь вид: cc. Для иллюстрации изменения строки используем последнюю строку текста письма.
Редактирование текста с помощью редакторов vi и ex 163 1. Переместите курсор в позицию. а) В командном режиме vi наберите IFrank и нажмите клавишу RETURN. б) Курсор установится теперь под буквой F в слове Frank: Frank Failsquick (мМг. Macho") 2. Замените словосочетание Frank Failsquick ("Mr. Macho") следующим Franklin F. Failsquick, Jr. а) Для выполнения изменения полной строки наберите cc (строка исчезнет). б) Сразу же после команды cc наберите текст Franklin F. Failsquick, Jr. и нажмите кла¬ вишу ESC для возврата в командный режим vi. в) Теперь строка будет иметь следующий вид: Franklin F. Failsquick, Jr^ После всех изменений полный текст письма будет следующим: September 17, 1985 Dear Mrs. Benson: I wish to thank you profusely for your letter of March 2. It is always a special delight to read and enjoy all your extraordinary ideas. We are unable to complete in a timely manner the job you asked for. We don't know what we're doing. Your most humble, obedient servant, The Man for the Job: Franklin F. Failsquick, Jr. Chief Consulting Officer Изменение в на чале предложения c( Изменение текста от начала предложения до определенного места в нем, подобно изменению строки, описанному выше. Отличие заключается только в том, что ис¬ пользуется команда с (вместо команды cO). Для иллюстрации действия этой коман¬ ды возьмем вторую строку третьего раздела письма, т. e. we don’t know.... 1. Сместите курсор в позицию. а) Наберите 7what в командном режиме vi и нажмите клавишу RETURN. б) Курсор установится под буквой w в слове what. We don't know what we're doing. 6*
164 Часть III 2. Измените первую половину предложения. а) Для вызова изменения от начала строки до места положения курсора наберите команду c(: We don't know$what we're doing. б) Сразу же наберите текст We have по notion (с последующим пробелом) и нажмите клавишу ESC для возврата в командный режим vi. в) Строка должна иметь следующий вид: We have no notion_what we're doing. 3. Аннулирование изменения а) Для восстановления текста предложения наберите команду u. б) Предложение будет иметь следующий вид: We don't know what we're doing. Изменение в конце предложения с) Изменение от определенного места до конца предложения аналогично изменению в конце строки, описанному выше. Единственное отличие в том, что используется команда с) вместо cS. Для иллюстрации действия этой команды используем ту же строку, что и выше. 1. Измените вторую половину предложения. а) Подведите курсор под букву w в слове what с помощью командыЗИЛ б) При положении курсора под буквой w в cnosewhat наберите командус^ для вызо¬ ва изменения в тексте от места положения курсора до конца строки: We don't know what we're doing$ в) Сразу же после команды наберите what’s going on. и нажмите клавишу ESC для воз¬ врата в командный режим vi. г) Строка будет иметь следующий вид: We don't know what's going огк 2. Аннулируйте изменения. а) Для восстановления текста предложения наберите команду u. б) Предложение будет иметь следующий вид: We don't know what we're doing. Изменение в начале раздела c( Изменение текста от начала раздела до определенного места в нем подобно измене¬ нию предложения в его начале. Единственное отличие в том, что вы используете командус( вместо командыс^. Для иллюстрации действия этой команды использу- емтотжераздел. 1. Переместите курсор в позицию. а) В командном режиме vi наберите ?the и нажмите клавишу RETURN. б) Курсор установится теперь под буквой t в слове the. We are unabLe to complete in а timely manner the job you asked for. We don't know what we're doing.
Редактирование текста с помощью редакторов vi и ex 165 2. Измените первую часть раздела. а) Для вызова изменений в тексте от начала раздела до положения курсора наберите команду c[. We are unable to complete in а timely manner$the job you asked for. [Это должно оказаться в одной строке] We don't know what we're doing. б) Сразу за командой наберите текст We are incapable of completing (с последующим пробелом) и нажмите клавишу ESC для возврата в командный режим vi. в) Теперь раздел будет иметь следующий вид: We are incapable of completing_the job you asked for. We don't know what we're doing. Изменение в конце раздела с) Изменение текста от определенного места в разделе и до его конца подобно измене¬ нию в конце строки. Единственное отличие в том, что вы используете команду cJ вместо команды c$. Для иллюстрации действия этой команды используем ту же строку. 1. Изменение оставшейся части раздела. а) При расположении курсора под буквой t в слове the наберите команду c| для вызо¬ ва изменения с места положения курсора и до конца раздела (текст исчезнет с экрана): We are incapable of completing _ б) Затем завершите раздел, как показано, нажмите клавишу ESC для возврата в ко¬ мандный режим vi. We are incapable of completing anything we attempt. <RETURN> We just don't know what we're doing at all.__ 2. Аннулируйте изменения. а) Для восстановления текста раздела наберите команду u. б) Он будет снова иметь следующий вид: We-are incapable of completing_the job you asked for. We don't know what we're doing. Сдвигстроки < < и > > Если вам требуется «сместить» текст в различные места строки, в редакторе vi име¬ ется команда для смещения строки влево (<<) и команда для смещения вправо (>>). После подвода курсора к требуемой строке наберите символы < < или > >. (Величина перемещения равна восьми позициям и может оказаться недостаточной. Вы можете изменить эту величину путем изменения «ширины сдвига». Эти вопросы более подробно рассмотрены в гл. 17.) Для иллюстрации действия команды сдвига строки используем строку, содержащую дату. 1. Переместите курсор в позицию. а) В командном режиме vi наберите команду ?17 и нажмите клавишу RETURN.
166 Часть III 6) Курсор установится под началом изображения числа 17: September Yl, 1985 2. Переместите текст даты вправо и влево по строке. а) Наберите команду > > и точку для смещения даты вправо: September 17, 1985 б) Наберите команду < < и точку для смещения даты к левому краю: September 17, 1985 Сдвигнесколькихстрок n < < и n> > Для смещения нескольких строк используйте множитель перед командами < < или > >. Для иллюстрации действия этих команд возьмем строки заключительного раз¬ дела в письме. 1. Переместите курсор в позицию. а) В командном режиме vi наберите команду IMan и нажмите клавишу RETURN. б) Курсор установится под буквой M в слове Man: The Man for the Job: FrankLin F. Failsquick, Jr. Chief Consulting Officer 2. Сместите три строки вправо и влево вдоль строки. а) Наберите команду 3> > и несколько раз точку для сдвига строк раздела по эк¬ рану: The Man for the Job: Franklin F. Failsquick, Jr. Chief Consulting Officer б) Теперь наберите команду 3< < и точку, чтобы сдвинуть строки к левому краю: The Man for the Job: Franklin F. Failsquick, Jr. Chief Consulting Officer Удаление текста Для удаления текста используйте символы управления перемещением курсора со¬ вместно с командой удаления d. Поскольку нами будет производиться много удале¬ ний, мы будем большую часть из них аннулировать с помощью команды u (undo — ан¬ нулировать). Удаление символа x Команда x для удаления одиночного символа отличается от команд удаления дру¬ гих сегментов текста. Для удаления символа подведите курсор к символу и набери¬ те x (но не d).
Редактирование текста с помощью редакторов vi и ex 167 Удаление нескольких символов nx Для удаления нескольких символов (например, четырех символов) поместите мно¬ житель 4 перед командой x. Проверим действие этой команды. 1. Подведите курсор в позицию. а) В командном режиме vi наберите lankl и нажмите клавишу RETURN. б) Курсор теперь окажется под буквой а в слове Franklin. Franklin F. Failsquick, Jr. 2. Измените слово Franklin на слово Frin путем удаления четырех букв. а) Для осуществления удаления наберите 4x. б) Строка будет иметь следующий вид: Fnn F. Failsquick, Jr. в) Аннулируйте удаление с помощью команды u. Franklin F. Failsquick, Jr. Удаление слова (или слов) dw Для удаления слова сместите курсор к первой букве слова и наберите dw. При этом выполнится действие, подобное действию при выполнении команды cw, за исклю¬ чением того, что вы будете не в состоянии ввести некоторый изменяемый текст с командой dw. Попробуем удалить несколько слов в тексте. 1. Подведите курсор в позицию. б) Наберите ?in а timely и нажмите клавишу RETURN. б) Курсор сместится к букве / в слове in во втором разделе: We are unable to complete j^n а timely manner the job you asked for. 2. Удалите одно слово. а) Для удаления in наберите команду dw. б) Строка должна иметь теперь следующий вид: We are unable to complete а timely manner the job you asked for. 3. Удалите несколько слов. а) Наберите команду 3dw (или d3w) для удаления слов а tfmefy manner. б) Строка должна теперь иметь следующий вид: We are unable to complete the job you asked for. Если за удаляемым словом (или словами) следуют знаки препинания или в словах содержатся знаки пунктуации (isn’t, won’t, $5.67), используйте команду W вместо w. 4. Сместите курсор вниз к следующей строке. а) Наберите /we’re и нажмите клавишу RETURN. б) Курсор переместится к букве w в слове we’re. We don't know what we're doing.
168 Часть III 5. Удалите два слова вместе со знаком пунктуации. а) Наберите команду 2dW (или d2W). б) Строка должна теперь иметь следующий вид: We don’t know what__ в) Аннулируйте удаление с помощью команды u. We don't know what we're doing. Чтобы удалить часть слова, сместите курсор к первой букве, которая должна быть удалена, и проделайте ту же процедуру по удалению. Например, для устране¬ ния части слова ment в слове establishment подведите курсор к букве m и наберите команду dw. Удаление от начала строки dA Для удаления текста от начала до определенного места в строке используйте коман¬ ду с/л, которая аналогична команде сл. Чтобы сделать это, необходимо сместить курсор к первому символу, который должен остаться в слове, и набрать команду dA. Весь текст на строке влево от курсора будет удален. Для иллюстрации этого без сме¬ щения курсора1> наберите команду с/л на текущей строке. Весь текст слева от курсо¬ ра исчезнет: we'ге doing. Аннулирование такого удаления производится командой u: We don't know what we're doing. Удаление в конце строки d$ Для удаления текста от определенного места в строке и до ее конца используйте командус№, которая аналогична командес#. Подведите курсор к первому удаляемо¬ му символу и наберитес^. Весь текст на строке справа от курсора исчезнет. Прове¬ рим действие этой команды. 1. Сместите курсор вверх к первому разделу. а) Наберите команду ?and и нажмите клавишу RETURN. б) Курсор установится под буквойа в словeand. It is always а special delight to read and enjoy 2. Удалите часть строки, находящейся справа. а) Для выполнения операции удаления наберите команду d$. б) Строка должна теперь иметь следующий вид: It is always а special delight to read_ в) Аннулируйте удаление с помощью команды u. It is always а special delight to read_and enjoy 1) Курсор остается в положении, рассмотренном в текущем примере. — Прим. ред.
Редактирование текста с помощью редакторов vi и ex 169 Удаление полной строки dd Для удаления полной строки используйте «правило удвоения» (dd). Сместите курсор налюбое место в строке и наберите dd. Например, оставьте курсор там, где он распо¬ ложен и наберите dd. Строка исчезнет, курсор останется при этом на следующей строке: I wish to thank you profusely for your recent letter, all your extraordinary ideas. Для восстановления удаленной строки используйте команду u. I wish to thank you profusely for your recent letter. It is always a special delight to read and enjoy Отметим, что перед командой можно набрать множитель для удаления несколь¬ ких строк. Например, для удаления четырех строк текста (текущая строка и следую¬ щие три) наберите команду 4dd. Проверим действие этой команды. Четыре строки исчезнут, а на экране появится следующий текст: I wish to thank you profusely for your recent letter. We don't know what we're doing. Восстановите исчезнувший текст по команде u: lt is always а special delight to read and enjoy all your extraordinary ideas. We are incapable of completing the job you asked for. We don't know what we're doing. Удаление в начале предложения d( Для удаления текста от начала предложения до определенного места в нем исполь¬ зуйте команду d(, которая аналогична команде c(. Сместите курсор к первому симво¬ лу, который должен быть оставлен, и наберите d(. Весь текст предложения, пред¬ шествующий месту положения курсора, будет удален. Проверим действие этой команды. 1. Переведите курсор вниз на следующую строку. а) Наберите lextra и нажмите клавишу RETURN. б) Курсор установится под буквой e в слове extraordinary: It is always а special delight to read and enjoy all your extraordinary ideas. 2. Удалите первую часть предложения. а) Для устранения всех слов, находящихся перед курсором, наберите d(. б) Теперь на экране появится следующий текст: I wish to thank you profusely for your recent letter, extraordinary ideas. в) Восстановите удаленные слова с помощью команды u: lt is always а special delight to read and enjoy all your extraordinary ideas.
170 Часть III Удаление в конце предложения d) Для удаления текста от определенного места в предложении и до конца его исполь¬ зуйте команду d), которая аналогична команде с). Сместите курсор к последнему символу текста, который должен быть оставлен, и наберитес^. Весь текст в предло¬ жении, который находится вправо от курсора, будет удален. 1. Переместите курсор вдоль строки к слову to. а) Для перемещения курсора вперед наберите 6w. б) Курсор установится под буквой t в слове to: It is aLways а special delight to read and enjoy all your extraordinary ideas. 2. Удалите последнюю часть предложения. а) Для удаления всех слов, которые расположены вправо от курсора, наберитес/j. б) На экране появится следующий текст: It is always а special de 1 ight в) Восстановите удаленные слова с помощью команды u. It is always а special delight to read and enjoy all your extraordinary ideas. Для удаления всего предложения просто сместите курсор на начало предложе¬ ния и наберите d). Для удаления нескольких предложений поместите перед коман¬ дой множитель и выполните ту же последовательность действий. Удаление в начале раздела d[ Для удаления текста от начала раздела до некоторого места в нем используйте ко¬ манду d{, которая аналогична команде c[. Переместите курсор к первому символу, который должен быть оставлен в тексте, и наберите команду d [. Весь текст раздела, который предшествует курсору, будет удален. Без смещения курсора проверьте действие этой команды, исходя из текущего вашего местоположения в тексте перво¬ го раздела. После того как вы наберете d(, на экране появится следующий текст: Dear Mrs. Benson: to read and enjoy all your extraordinary ideas. Восстановите исчезнувшие слова с помощью команды u: Dear Mrs. Benson: I wish to thank you profusely for your letter of March 2. It is always а special delight to read and enjoy all your extraordinary ideas. Удаление в конце раздела d) Для удаления текста от определенного места в разделе и до его конца используйте команду d], которая аналогична командес]. Сместите курсор к последнему символу в тексте, который должен быть оставлен, и наберите d]. Весь текст в разделе, ко¬
Редактирование текста с помощью редакторов vi и ex 171 торый расположен вправо от курсора, будет удален. Проверим действие этой ко¬ манды. 1. Переместите курсор в позицию. а) Для перемещения курсора вперед наберите lfor и нажмите клавишу RETURN. б) Курсор установится под буквой f в слове for. I wish to thank you profusely for your letter of March 2. It is always a special delight to read and enjoy all your extraordinary ideas. 2. Удалите остаток раздела. а) Для удаления остатка раздела наберите dj. б) На экране появится следующий текст: I wish to thank you profusely_ в) Теперь восстановите раздел с помощью команды u: Dear Mrs. Benson: I wish to thank you profusely for your letter of March 2. It is always a special delight to read and enjoy all your extraordinary ideas. Чтобы удалить весь раздел, переведите курсор к началу раздела и наберите d]. Для удаления нескольких разделов перед командой наберите множитель и вы¬ полните ту же последовательность действий. Окончание работы Теперь запишем отредактированный текст письма и возвратимся в shell системы Юникс. 1. Запишите текст в файл letter. а) Для записи файла наберите :w и нажмите клавишу RETURN. б) В нижней части экрана вы увидите следующее сообщение: "letter" [Modified] 17 lines, 391 characters 2. Закончите данную работу с редактором vi. а) Для окончания работы наберите :g и нажмите клавишу RETURN. б) На экране появится следующее сообщение, указывающее на то, что вы вышли из редактора vi и возвратились в shell системы Юникс: Пя $. Отметим, что редактор vi также позволяет вам объединять команды записи и выхо¬ да в одну команду подобно следующему: fiwql $ _ "letter" 17 lines, 377 characters
172 Часть III Краткое изложение главы 13 В этой главе вы узнали, как изменять и удалять текст. ИЗМЕНЕНИЕТЕКСТА Изменение слова Изменение нескольких слов Изменение Изменение всей строки Изменение нескольких строк Изменение Изменение нескольких предложений Изменение Изменение нескольких разделов Смещение строки Смещение нескольких строк УДАЛЕНИЕТЕКСТА Удаление слова Удаление нескольких слов Удаление Удаление всей строки Удаление нескольких строк Удаление Удаление нескольких предложений Удаление Удаление нескольких разделов КОМАНДЫ cw или cW c2w, c2W, c3w, c3W и т. д. начала строки: cO конца строки: c$ cc 2cc, 3cc, 4cc и т. д. начала предложения: с (конца предложе¬ ния: с) c2), сЗ), c4) и т. д. начала раздела: с [конца раздела: с] c2),c3),c4) и т. д. влево: < < вправо: > > влево: n < < вправо: n > > КОМАНДЫ dw или dW d2w, d2W, d3w, d3W и т. д. начала строки: dO конца строки: d$ dd 2dd, 3dd, 4dd и т.д. начала предложения: d( конца предло¬ жения: d) d2), d3), d4) и т. д. начала раздела: d[ конца раздела: d) d2], d3J, d4) и т. д. Глава 14. Поиск и замена текста с помощью редактора vi В главе 13 мы изучили несколько способов изменения и удаления текста с помощью редактора vi. В этой главе мы рассмотрим способы поиска и замены текста. Начало новой работы Напомним еще раз о том, как начать работу с редактором vi: если необходимо, перей¬ дите из вашего текущего каталога к text _ files, а затем начинайте редактирование того же файла (letter). $ cd text_files $ pwd /usr/robin/text files $|vi letter
Редактирование текста с помощью редакторов vi и ex 173 Теперь вы должны увидеть на экране следующее: September 17, 1985 Dear Mrs. Benson: I wish to thank you profusely for your letter of March 2. It is always a special delight to read and enjoy all your extraordinary ideas. We are incapable of completing the job you asked for. We don't know what we're doing. Your most humble, obedient servant, The Man for the Job: Franklin F. Failsquick, Jr. Chief Consulting Officer "letter" 17 lines, 377 characters Поискстроки fx Имеются две vi-команды, которые позволяют осуществлять поиск символа в том или другом направлении на текущей строке и осуществлять изменения. Поиск вправо Для осуществления поиска отдельного символа в направлении слева направо в те¬ кущей строке используйте команду fx (где x — искомый символ). Затем, если необхо¬ димо продолжить поиск того же символа, вы можете использовать одну из двух ко¬ манд повторения: ; (повторить поиск в том же направлении) , (повторить поиск в противоположном направлении) Например, предположим, что вы хотите найти символ r в первой строке первого раздела. 1. Переместите курсор в позицию. а) Сместите курсор к началу строки (5G или //). б) Строка должна иметь следующий вид: I wish to thank you profusely for your letter of March 2. 2. Сместите курсор к первому символу r. а) Наберите fr. б) Курсор перейдет к букве r в слове profusely: I wish to thank you profusely for your letter of March 2. 3. Сместите курсор к следующему символу r. а) Наберите точку с запятой ; для продолжения поиска в прямом направлении.
174 Часть III б) Курсор перейдет к букве r в слове for : I wish to thank you profusely for your letter of March 2. 4. Сместите курсор к следующему символу r. а) Наберите точку с запятой ; для повторного продолжения поиска. б) Курсор перейдет к букве r в слове your : I wish to thank you profusely for your letter of March 2. Вы можете набрать точку с запятой еще 2 раза с тем, чтобы перевести курсор к следующим двум символам r в строке. Затем вы можете набрать запятую для перехо¬ да курсора назад к каждому предшествующему символу в противоположном направ¬ лении. Поисквлево Fx Для осуществления поиска отдельного символа в направлении справа налево ис¬ пользуйте команду Fx (где x — искомый символ). И снова, если необходимо про¬ должить поиск этого же символа, можете использовать одну из двух команд для по¬ вторения: ; (повторить поиск в том же направлении) , (повторить поиск в противоположном направлении) В качестве примера осуществим поиск символа r в первой строке в направлении справа налево. 1. Переместите курсор в позицию. а) Сместите курсор к концу строки по команде $. б) Строка будет иметь следующий вид: I wish to thank you profusely for your letter of March 2^ 2. Сместите курсор к первому символу r. а) Наберите команду Fr, чтобы начать поиск влево. б) Курсор перейдет к букве r в слове March: I wish to thank you profusely for your letter of March 2. 3. Сместите курсор к следующему (влево) символу r. а) Наберите точку с запятой ; для продолжения поиска влево. б) Курсор перейдет к букве r в слове letter : I wish to thank you profusely for your letter of March 2. 4. Сместите курсор к следующему символу r. а) Наберите точку с запятой ; для повторного продолжения поиска. б) Курсор перейдет к букве r в слове your : I wish to thank you profusely for your letter of March 2. Вы можете набрать команду точку с запятой еще 2 раза с тем, чтобы перевести курсор к следующим двум символам r. Затем вы можете набрать запятую для перево¬ да курсора назад к каждому следующему символу гпри поиске в обратном направле¬ нии.
Редактирование текста с помощью редакторов vi и ex 175 Поиск в файле /string Для поиска строки в рабочей области редактор vi имеет две команды, аналогичные командам^ и F: одна для поиска вперед и одна для поиска назад в редактируемом буфере. Для осуществления поиска строки в прямом направлении в файле наберите команду1> lstring и нажмите клавишу RETURN. Если необходимо продолжить поиск строки, можете использовать одну из двух клавишей: n (повторить поиск в прямом направлении) N (повторить поиск в противоположном направлении) В качестве примера предположим, что необходимо найти набор символов you в тексте письма. 1. Переместите курсор в позицию. а) Установите курсор в начале файла по команде 1G. б) Первая строка будет иметь следующий вид: September 17, 1985 2. Начните поиск. а) Наберите lyou и нажмите клавишу RETURN. б) Курсор перейдет к букве у в слове you в строке 5: I wish to thank ^ou profusely for your Letter of March 2. 3. Продолжите поиск а) Для продолжения поиска в прямом направлении наберите n. б) Курсор перейдет к слову your в той же строке: I wish to thank you profuseLy for ^our letter of March 2. 4. Повторите продолжение поиска. а) Наберите снова n. б) Курсор переместится к слову your в строке 7: aLL _your extraordinary ideas. Вы можете набрать опять символ n для продолжения поиска вперед или символ N для поиска назад по отношению к началу текста письма. Если вы не хотите, чтобы курсор останавливался перед словами your, yourself или другими словами, содержа¬ щими you, оставьте пробел в команде после символа и, когда начинаете поиск, т. e. наберите lyou . Для осуществления поиска строки в обратном направлении в файле наберите ко¬ манду 7string и нажмите клавишу RETURN. И снова, если необходимо продолжить поиск строки, используйте одну из двух клавиш: Поиск в прямом направлении Поиск в обра тном направлении 7string 1) В данной команде string — искомое словосочетание. — Прим, перев.
176 Часть III n (повторить поиск в обратном направлении); N (повторить поиск в прямом направлении). В качестве примера предположим, что необходимо найти набор символов you в тек¬ сте письма. 1. Переместите курсор в позицию. а) Установите курсор в конце файла по команде G. б) Строка будет иметь следующий вид: Chief Consulting Officer 2. Начните поиск. а) Наберите ?уои и нажмите клавишу RETURN для начала поиска в обратном направ¬ лении. б) Курсор перейдет к букве у в слове you строки 9: We are incapable of completing the job ^ou asked for. 3. Продолжайте поиск. а) Для продолжения поиска в противоположном направлении наберите n. б) Курсор перейдет к слову your в строке 7: all ^our extraordinary ideas. 4. Повторите продолжение поиска. а) Для продолжения поиска в противоположном направлении вновь наберите n. б) Курсор переместится к слову your в строке 5: I wish to thank you profusely for _your letter of March 2. Наберите n повторно для продолжения поиска назад или N для поиска вперед. И снова, если не хотите останавливать курсор перед словами your, yourself или други¬ ми словами, содержащими you, поставьте пробел после слова you, когда начинаете поиск, т. e. наберите ?уои . Поскольку при всех поисках осуществляется смена на¬ правления при движении от одного конца буфера редактирования к другому, то са¬ мо собой разумеется, что вполне достаточно команды для поиска вперед, т. e. Istring. Замена текста Каждый раз после остановки курсора при организации поиска вы можете заменить текст (добавить или вставить). Поскольку подсоединение и вставка текста уже бы¬ ли обсуждены подробно выше, обратим внимание на особенности замены в данном случае. Для замены текста в файле редактор vi имеет следующие основные команды (дополнительно к команде изменения, которая была рассмотрена в предыдущей гла¬ ве): команда для замены отдельного символа на другой; команда для замены после¬ довательности символов; команда для замены отдельного символа несколькими символами; команда для замены полной строки. Замена одного символа на другой r Для замены одного символа на другой в составе vi имеется простая команда r. Сме¬ стите курсор к символу, наберитегизатем наберите новый символ. Например, вы хо¬ тите изменить дату на текущей строке — вместо March 2 установить March 9.
Редактирование текста с помощью редакторов vi и ex 177 1. Переместите курсор в позицию. а) Для смещения курсора к цифре 2 наберите f2. б) Строка будет иметь следующий вид: I wish to thank you profusely for your letter of March 2. 2. Выполните изменения. а) Наберите r9 без нажатия клавиш RETURN или ESC с тем, чтобы изменить цифру 2 на цифру 9. б) Строка будет теперь иметь следующий вид: I wish to thank you profusely for your letter of March 9. Замена совокупности символов R Для замены сразу нескольких последовательных символов используйте команду R. Переместите курсор к первому из символов, наберите R и затем наберите последова¬ тельность новых символов, вслед за которыми нажмите клавишу RETURN. Напри¬ мер, необходимо изменить название месяца в дате March 9 на другое названиеДрг/'/9 в тексте письма. 1. Переместите курсор в позицию. а) Для подвода курсора к букве M в слове March наберите b. б) Строка будет иметь следующий вид: I wish to thank you profusely for your letter of March 9. 2. Выполните изменения: а) Наберите Я, затем слово April без пробела, вслед за тем нажмите клавишу ESC с тем, чтобы заменить слово March на слово April. б) Теперь строка будет иметь следующий вид: I wish to thank you profusely for your letter of AprU 9. Заменяющий текст не должен быть длиннее заменяемого. Замена одного символа несколькими символами s Для замены одного символа на любое число символов в составе редактора vi имеет¬ ся команда s. Подведите курсор к символу, наберите s и наберите новые символы. Например, вы хотите изменить дату на текущей строке с April 9 на April 12. 1. Переместите курсор в позицию. а) Для сдвига курсора к цифре 9 наберите w. б) Строка будет иметь следующий вид: I wish to thank you profusely for your letter of April 9. 2. Выполните изменения. а) Для изменения цифры 9 на 12 наберите s72, а затем нажмите клавишу ESC. б) Теперь строка будет иметь следующий вид: II wish to thank you profusely for your letter of April 12.
178 Часть III Замена полной строки S Для замены полной строки текста используйте команду S (которая эквивалентна команде cc). Сместите курсор к любой позиции на строке, наберите S, а затем набе¬ рите текст новой строки (или строк) и нажмите клавишу RETURN. Например, вы хоти¬ те изменить заголовок письма — текст Chief Consulting Officer заменить на Supreme Supervisor. 1. Переместите курсор в позицию. а) Для смещения курсора к последней строке текста наберите IChief. б) Строка должна иметь следующий вид: Chief Consulting Officer 2. Выполните изменения. а) Для вызова изменения в строке (которая исчезнет) наберите команду S. б) Чтобы набрать новую строку без начального пробела наберите текст Supreme Su¬ pervisor, и далее нажмите клавишу ESC. в) Новая строка будет иметь следующий вид: Supreme Supervisor г) Для аннулирования изменения наберите команду U. Замечание. Если бы редактор vi был на 100% логически выдержан, команда S должна была быть эквивалентна команде c$, а не команде cc. Окончание работы Запишем отредактированный текст на дисковый файл letter и возвратимся в shell системы Юникс. Для записи буфера и выхода из vi наберите :wq и нажмите клавишу RETURN. Выполнение замен В главе 8 мы изучили команду замены s, которая имеется в составе редактора ed. В редакторе ex имеется также команда замены, называемая s, которая очень похожа на команду замены в редакторе ed. (Напомним, что редактор vi есть визуальный ва¬ риант более общего редактора ex — более развитой версии редактора ed.) Копирование файлов из других каталогов Прежде чем иметь дело с командой s в редакторе vi, скопируем файл, с которым вы уже работали (metric.c в каталогec_progs) в ваш текущий Kajanor(text_files). Что¬ бы помочь вам осуществить это, на рис. 14.1 показано соотношение между вашим главным каталогом и подкаталогами в данный момент. robin
Редактирование текста с помощью редакторов vi и ex 179 1. Проверьте ваши каталоги, а) Проверьте ваш текущий каталог: $ pwd /usr/robin/text_files $ б) Проверьте подкаталоги в вашем начальном каталоге: $ ls sp .profi Le ed files c_progs vi_files 2. Скопируйте срайл metric.c в ваш текущий каталог, а) Выполните копирование: $ $ cp ../cprogs/metric.c vi_files б) Проверьте ваш каталог, чтобы убедиться в правильности копирования: $ ls | sp barbershop hours rates letter compact.c metric.c Вы нашли копии файлов display.c и metric.c. Теперь можно производить замены. (В том случае, если вы не ознакомились с гл. 11 этой книги, вы не можете теперь об¬ ратиться к файлу metric.c и должны будете его набрать.) Начало новой работы с редактором vi После того как вы скопировали metric.c в ваш каталог text_files, можно произво¬ дить редактирование этого файла с помощью редактора vi: vi metric.c На экране должно появиться следующее изображение: /* List conversions from gallons to liters*/ main() > int low, high, incr; float gals, ltrs; low = 10; /* starting value in gallons */ high = 20; /* ending value in gallons */ incr = 2; /* increment for each step */ gals = low; while (gals <= high) < ltrs = (gals * 3.785); printf("%4.0f %6.2fXn", gals, ltrs);
180 Часть III > > gals = gals + incr; "metric.c" 18 lines, 319 characters Изменение некоторых установочных:режимов работы редактора1) Поскольку представленный выше текст является программой, а не письмом, опреде¬ лим значения некоторых опций. Для упрощения изменим только две опции: ■ nu (number — число) опция для нумерации строк ■ sw (shift-width — ширина сдвига) опция, которая определяет, насколько далеко должен быть произведен сдвиг строк экрана по мере выполнения ко¬ манд < < и > > 1. Установите нумерацию строк. а) Наберите :set пи и нажмите клавишу RETURN. б) Перед нажатием RETURN вы увидите, что в нижней строке экрана появится текст :set пи. в) После нажатия RETURN вы увидите номера строк слева от текста. 2. Установите ширину сдвига равной 5. а) Наберите :set sw=5 и нажмите клавишу RETURN. б) Перед нажатием клавиши RETURN в нижней строке экрана вы увидите текст :set sw = 5. в) Ширина всех сдвигов будет изменена с 8 (по умолчанию) на 5. Таким образом, ваш редактор vi работает с файлом metric.c и провел нумерацию строк. Опция shift-width установлена на значение 5 колонок. Теперь вы в состоянии начать испытание некоторых замещений. Выполнение замещений :s Одна из причин выбора файла metric.c для осуществления в нем замещений заклю¬ чается в том, что он содержит достаточно много повторений одних и тех же слов. Например, переменная gals встречается семь раз в короткой программе. Очевидно, что вы можете сделать семь замещений вручную без больших хлопот. Но команда за¬ мещения s выполняет такие изменения автоматически. Это средство очень удобно для больших программ. 1. Измените имя переменной gals на gallons. а) Для организации замещений во всех строках файла (от строки с номером 1 до по¬ следней строки) наберите : 1,$s. 1) Редактор vi имеет ряд опций — некоторых внутренних переменных, которые предна¬ значены определять различные режимы его работы. Значения опций могут быть установлены либо по умолчанию, либо изменены с помощью команды :set. — Прим. ред.
Редактирование текста с помощью редакторов vi и ex 181 б) Без нажатия клавиши «пробел» наберите lgals/gallons/g для организации замеще¬ ния слова gal на слово gallons во всех словах каждой строки, на что указывает символ g. в) Если в нижней строке экрана появится следующее сообщение: :1# $s/ga Ls/ga L Lons/g J нажмите клавишу RETURN, чтобы начать замещение, г) Если вы заметили ошибки, подведите курсор к ним и исправьте, а затем нажмите клавишу RETURN. 2. Измените слова ltrs на liters. а) Для организации замещений во всех строках файла (от строки с номером 1 до по¬ следней строки) наберите :1,$s. б) Без нажатия клавиши «пробел» наберите lltrs/liters/g для организации замещения слова ltrs на слово liters во всех словах каждой строки. в) Если в нижней строке экрана появится следующее изображение: :1,$s/ltrs/liters/g нажмите клавишу RETURN, чтобы начать замещение, г) Если вы заметили ошибки, подведите курсор к ним и исправьте, а затем нажмите клавишу RETURN. Если вы заметили сделанные ошибки и затем случайно нажали клавишу RETURN, можете всегда аннулировать это действие с помощью команды u (undo— аннулиро¬ вать). 3. Посмотрите теперь на экране на результат замещения: 1 /* List conversions from gallons to liters ★/ 2 main() 3 i 4 int low, high, incr; 5 float gallons, liters; 6 7 low = 10; /* starting value in gallons */ 8 high = 20; /* ending value in gallons */ 9 incr = 2; /* increment for each step */ 10 11 gallons = low; 12 while (gallons <= high) 13 { 14 liters = (gallons * 3.785); 15 printf(*'%4.0f %6.2fNn", gallons, liters); 16 gallons = gallons + incr; 17 > 18 > 3 substitutions on 3 lines
182 Часть III Видно, что замещение в редакторе vi выполняется тем же способом, что и в ре¬ дакторе ed. Поговорим теперь об использовании команды s в редакторе vi (которая аналогична команде s в редакторе ed). • Команда s всегда начинается с двоеточия, чтобы вызвать переключение на ex, а затем следует диапазон номеров строк. • Номера строк могут быть целыми числами, искомыми строками или символами: :1,20 :15,/place/ :5,. :.,* :.-20,7end? Строки 1—20 Строки от 15 до первой, содержащей place Строки от 5 до текущей строки Строки от текущей до последней в файле 20 строк перед текущей строкой до первой, содержащей end :7WPP7,$-2 Строки в пределах от первой, содержащей WPP (над текущей строкой),до двух строк перед последней строкой файла • Косая черта / используется для организации поиска в прямом направлении, а во¬ просительный знак 7 — для организации поиска в обратном направлении. • Команда g используется в конце командной строки для замещения всех объектов в каждой строке, а не только в первом встретившемся объекте замещения. Сдвигстрок < < или > > Проверьте настроенную ранее команду по установлению ширины сдвига с помощью перемещения курсора к различным строкам и наборазнаков < < или > >. Каждый сдвиг в данном случае проходит на пять позиций вместо восьми. Сдвигразделов < j или > ] Проверим сдвиг разделов (в данном случае это группа строк, ограниченная пустыми строками — строками пробелов) с помощью операторов <] и >). 1. Сдвиньтестроки 4 и 5. а) Для смещения курсора к строке 4 Ha6epnTe4G. б) Наберите >j для смещения двух строк (это раздел при работе с vi) вправо: int low, high, incr; float gallons, liters; в) Наберите <j для обратного смещения строк раздела назад: int low, high, incr; float gallons, liters;
Редактирование текста с помощью редакторов vi и ex 183 2. Сдвиньте строки 7—91). а) Для смещения курсора к строке 7 наберите 7G. б) Наберите >) для смещения трех строк вправо: low = 10; /* starting value in gallons */ high = 20; /* ending value in gallons */ incr = 2; /* increment for each step */ в) Наберите <J для выполнения обратного сдвига строк: low = 10; /* starting value in gallons */ high = 20; /* ending value in gallons */ incr = 2; /* increment for each step */ 3. Сдвиньте строки 11—18. а) Для подвода курсора к строке 11 наберите 11G. б) Наберите >) для сдвига строк вправо: gallons = low; while (gallons <= high) < liters = (gallons * 3.785); printf("%4.0f %6.2fXn", gallons, liters); gallons = gallons + incr; > > в) Наберите <] для выполнения обратного сдвига строк: gallons = low; while (gallons <= high) { liters = (gallons * 3.785); printf("%4.0f %6.2fXn", gallons, liters); gallons = gallons + incr; > С помощью редактора vi вы можете смещать предложения. Для этого использу¬ ются команды <) и >). Ну, а теперь закончим работу с редактором vi путем набора команды :wg с последующим нажатием клавиши RETURN. Краткое изложение главы 14 В этой главе вы изучили, как осуществлять поиск текста в строке и в файле и каким образом проводить замещения. 1) Это по определению отдельный раздел так же, как и строки 11—18, которые рассмотре- нцв примере ниже. В данном примере раздел сдвигается на 4 позиции. — Прим. ред.
184 Часть III Поиск символа на текущей строке Поиск влево Fx Поиск вправо fx Поиск строки в буфере редактирования Поиск вперед /string Поиск назад 7string Независимо от заданного направления поиск будет проходить по всему буферу редактирования, возвращаясь в конце пути поиска к исходной заданной вами точке. Выполнение замещений Замещение одного символа на другой r Замещение любого числа символов R Замещение одного символа произвольным числом символов s Замещение полной строки S ВыполнЕниЕ ЗАМЕЩЕний. Для замены каждого объекта замещения на одной строке другим в диапазоне строк с номерами от n до N введите команды ex в форме: :n, Ns/старая строка/новая строка/g (поиск вперед) :n, Ns? старая строка? новая строка?д (поиск назад) Номера строк n и N могут быть целыми числами, искомыми строками или симво¬ лами для номеров строк (подобно использованию s в редакторе ed). Символ g показывает, что будет замещен каждый объект замены на данной стро¬ ке, а не только первый на этой строке. Глава 15. Выполнение изменений в файле с помощью редактора vi В главе 14 вы изучили, как искать текст и проводить замещения. Вы также провели копирование другого файла в ваш каталог text__files. В данной главе вы изучите раз¬ личные методы перемещения и копирования текста в пределах файла. Но вначале поговорим о путях выхода из редактора vi. Выход из редактора vi Выше вы использовали команды w (write — писать) и q (quit — покидать), чтобы осу¬ ществить выход из vi-файла. Это действие отображалось комбинированной коман¬ дой wq. :wq <RETURN>
Редактирование текста с помощью редакторов vi и ex 185 Условная запись Чтобы выполнить запись перед выходом, только в том случае если вами были сдела¬ ны изменения (т. e. необходимо выполнять условную запись), вы можете использо¬ вать следующую команду: :x <RETURN> (котораяэквивалентнагг) Выход из файла Для отказа от файла (выхода из него) без сохранения любых изменений, которые вы могли сделать в нем, используйте принудительный выход в виде: :q! <RETURN> Перемещение текста в пределах файла В главе 14 вы изучили, как использовать команды изменения с и удаления d. В этой главе вы изучите две новые команды: yank(y) (вытаскивать) и put(p или P) (выдавать). Вы узнаете, что команды delete и yank подобны. Вы можете использовать одну из этих команд с командой put, чтобы вызвать исчезновение текста, его повторное по¬ явление или многократное повторение. Если вы представите себя в роли фокусника, а слова, предложения и разделы, с которыми работаете, в роли косынок, кроликов и ассистентов, тогда вам не соста¬ вит труда представить, как работают команды delete, yank и put. Действие delete, подобно помещению кролика в цилиндр, а затем демонстрации зрителям того, что цилиндр пуст. Выполнение действия yank подобно помещению косынки в ваш кар¬ ман, однако с сохранением другой в руке. Последовательное выполнение действий delete и put подобно помещению вашего ассистента в деревянный ящик, а затем по¬ явлению его в другом конце сцены. Последовательное выполнение действий yank и put подобно помещению вашего ассистента в один из деревянных ящиков, а затем его появлению из этого ящика и появлению близнеца из другого1>. Создание нового файла Прежде чем обсуждать, как перемещать текст с места на место, создадим новый файл в каталоге text__files, который назовем disks. Используйте редактор vi для ре¬ дактирования файла, названного disks: $ vi disks а далее введите следующий ниже текст, оставляя пустые строки (строки пробелов) и нажимая клавишу RETURN в конце каждой строки, а в конце текста нажимая клави¬ шу ESC: Advertisement [Один знак табуляции] [Пустая строка] ★ ★ ★ ★ ★ * * * * ★ * ★ ★ * * ★ * ★ [i8 звездочек] [Пустая строка] 1) Фокус состоит в «размножении», т. e. копировании ассистента. — Прим. ред.
186 Часть III Spinrite diskettes have a lifetime guarantee. That's right, every Spinrite diskette is guaranteed for life. Not two years, not three years, not five years, but life. Advanced technology makes it possible. Sophisticated marketing makes it incredible. Superior distribution makes it available. And state-of- the-art manufacturing makes it. No matter what you've read, no matter what you've heard, no matter what you've thought, our warranty stands: Every Spinrite diskette will last until it wears out. That's quality, and that's our guarantee. Don't settle for anything less. Don't waste your time with the amateurs. Step up to the pro¬ fessionals. Step up to Spinrite. * 1 2 3 4[Пустая строка] [Пустая строка] [Пустая строка] ESC Теперь запишите текст на дисковый файл по команде .w. Перемещение текста на один символ xp Для перемещения текста с одного места на другое можете сделать так, чтобы он ис¬ чез в одном месте (по команде delete), а затем появился в другом месте (по команде put). После осуществления записи на диск подведите курсор к букве о в слове thought на строке 19(no команде 7ought). Затем при расположении курсора под буквой о на¬ берите xp (нажимать клавишу RETURN нет необходимости). Теперь слово будет представлено (побуквенно) следующим образом: thuoght — буквы о и u поменялись местами. Это простейший вид перемещения. Теперь наберите команду h (курсор влево), а затем опять команду xp, чтобы анну¬ лировать перемещение. Ниже поэтапно показано, как происходит перемещение. 1. Курсор находится под буквой о (следите за курсором): you've thought, our warranty stands: 2. Удалите букву о по команде x. you've thught, our warranty stands: 3. «Выдайте» букву о обратно по команде p. you've thuoght, our warranty stands: 4. Аннулируйте изменение, набирая команду U (но не команду u). Команда U воз¬ действует на всю строку.
Редактирование текста с помощью редакторов vi и ex 187 Вы следили за перемещением курсора? По мере исчезновения буквы о курсор смещался кбуквеи. Поскольку командар всегда выдается для текста, находящего¬ ся над курсором, буквао оказывается за буквойи.(Запомните, что командой для уда¬ ления одного символа является x, а не d.) Перемещение слова dw и P dwnp Перемещение слова аналогично перемещению символа. Основное отличие заключа¬ ется в том, что командой для удаления слова является dw (или dW), а не x. Для осу¬ ществления перемещения подведите курсор к слову, удалите слово, а затем переме¬ стите курсор к новому месту и «выдайте» здесь слово. В качестве примера переме¬ стим слово every со строки 6 на строку 8. 1. Переместите курсор в позицию. а) Для перемещения курсора к слову every наберите команду 7every и нажмите клави¬ шу RETURN. б) На дисплее появится следующее изображение: Spinrite diskettes have а Lifetime guarantee. That's right, every Spinrite diskette is guaranteed for life. Not two years, not three years, not five years, but life. 2. Удалите слово с его текущего местоположения. а) Для удаления слова every наберите dw. б) Строка будет иметь следующий вид: guarantee. That's right, 3. Подведите курсор к новому месту. а) Для перемещения курсора к слову life на строке 8 наберите команду llife. б) Строка будет иметь следующий вид: for _h'fe. Not two years, not three 4. «Выдайте» слово на новом месте. а) Для помещения слова every перед словом life наберите прописную букву P (но нер). б) Текст раздела будет иметь теперь следующий вид: Spinrite diskettes have а lifetime guarantee. That's right, Spinrite diskette is guaranteed for everylife. Not two years, not three years, not five years, but life. в) Чтобы вставить пробел между словами every и life, наберите команду а, нажмите клавишу «пробел» и ESC. (Этого не надо делать, если вы сразу же набрали пробел после слова every.) В данном примере вы использовали прописную букву P, а не строчную, так как команда P означает помещение текста перед курсором (над текущей строкой в стро¬ ковой операции). Командой p следует пользоваться, когда желаете помещать текст после курсора (или под текущей строкой).
188 Часть III Перемещение предложения d) и P d)np Перемещение предложения подобно перемещению слова. Основное отличие состо¬ ит в том, что командой для удаления предложения является d), а не dw. Для смеще¬ ния предложения подведите курсор к началу предложения, удалите предложение, затем подведите курсор к новому месту и «выдайте» здесь предложение. В качестве примера сместим второе предложение первого раздела в конец раздела. 1. Переместите курсор в позицию. а) Для подвода курсора к слову That’s наберите ?That и нажмите клавишу RETURN. б) На дисплее появится следующее изображение: Spinrite diskettes have а Lifetime guarantee. That's right, Spinrite diskette is guaranteed for every Life. Not two years, not three years, not five years, but Life. 2. Удалите предложение с его текущего местоположения. а) Для удаления всего второго предложения наберите командус^. б) Текст раздела будет иметь следующий вид: Spinrite diskettes have а Lifetime guarantee. Not two years, not three years, not five years, but Life. 3. Переместите курсор к новому месту. а) Для подвода курсора к слову life в строке 8 наберите команду llife и нажмите кла¬ вишу RETURN. б) Переместите курсор затем в конец строки по символу $. в) Строка должна иметь следующий вид: years, not five years, but Life. 4. «Выдайте» предложения в новом месте. а) Для помещения второго предложения за третьим наберите строчную букву p. б) Текст раздела будет следующим: Spinrite diskettes have а Lifetime guarantee. Not two years, not three years, not five years, but Life.That's right, Spinrite diskette is guaranteed for every Life. в) Чтобы вставить два пробела между точкой и словом That’s наберите /, нажмите дважды клавишу «пробел» и клавишу ESC. Перемещение раздела d) и P dj ир Перемещение раздела подобно перемещению предложения. Основное отличие со¬ стоит в том, что используется команда для удаления dJ, а не d). Для смещения разде¬ ла подведите курсор к началу раздела, удалите раздел, затем переместите курсор к
Редактирование текста с помощью редакторов vi и ex 189 новому месту и «выдайте» здесь раздел. В качестве примера сместим второй раздел на место третьего раздела. 1. Переместите курсор в позицию. а) Для подвода курсора вперед к началу второго раздела наберите j. б) На дисплее появится следующее изображение: Spinrite diskette is guaranteed for every life. Advanced technology makes it possible. Sophisticated marketing makes it 2. Удалите раздел с его текущего местоположения. а) Наберите d| для устранения целиком второго раздела. б) На дисплее теперь будет следующее изображение: Spinrite diskette is guaranteed for every life. No matter what you've read, no matter what you've heard, no matter what 3. Переместите курсор в новую позицию. а) Наберите ) для продвижения курсора вперед к началу следующего раздела. б) На дисплее появится следующее изображение: until it wears out. That's quality, and that's our guarantee. Don't settle for anything less. Don't waste your time with the 4. «Выдайте» раздел в новом месте. а) Для «выдачи» второго раздела над четвертым наберите прописную букву P (а не строчную). б) На дисплее появится следующее изображение: Adverti sement ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ Spinrite diskettes have а lifetime guarantee. Not two years, not three years, not five years, but life. That's right, Spinrite diskette is guaranteed for every life. No matter what you've read, no matter what you've heard, no matter what you've thought, our warranty stands:
190 Часть III Every Spinrite diskette will Last until it wears out. That's quality, and that's our guarantee. [Этот раздел был смещен, т. e. переставлен местами с предыдущим разделом] Don't settle for anything less. Don't waste your time with the amateurs. Step up to the pro¬ fessionals. Step up to Spinrite. Advanced technology makes it possible. Sophisticated marketing makes it incredible. Superior distribution makes it available. And state-of- the-artmanufacturing makes it. Перемещение строки dd и P dd и p Перемещение строки аналогично перемещению слова. Основное отличие заключа¬ ется в том, что используется команда удаления dd, а не dw. Для перемещения строки подведите курсор к строке, удалите строку, затем подведите курсор к новому месту и «выдайте» здесь строку. В качестве примера переместим вторую строку первого раздела на место, где теперь располагается четвертая строка. 1. Переместите курсор в позицию. а) Для подвода курсора к слову two (строка 6) наберите ?two и нажмите клавишу RETURN. б) На дисплее появится следующее изображение: Spinrite diskettes have а lifetime guarantee. Not two years, not three years, not five years, but life. That's right, Spinrite diskette is guaranteed for every life. 2. Удалите строку, на которую указывает курсор. а) НаберитеаМ для удаления второй строки. б) Раздел будет иметь следующий вид: Spinrite diskettes have а lifetime ^ears, not five years, but life. That's right, Spinrite diskette is guaranteed for every life. 3. Переместите курсор в новую позицию. а) Для перевода курсора к слову Spinrite в следующей строке наберите /'. б) Раздел будет иметь следующий вид: Spinrite diskettes have а lifetime years, not five years, but life. That's right,
Редактирование текста с помощью редакторов vi и ex 191 Spinrite diskette is guaranteed for every life. 4. «Выдайте» строку в новом месте. а) Для «выдачи» второй строки на место под текущей строкой наберите строчную буквур. б) Раздел теперь будет иметь следующий вид: Spinrite diskettes have а lifetime years, not five years, but life. That's right Spinrite diskette is guaranteed guarantee. Not two years, not three for every life. Другие возможные перемещения В тех примерах, которые вы только что рассмотрели, осуществлялось смещение од¬ ного объекта (символа, слова, предложения, раздела или строки) с одного места на другое. Вместе с тем можно смещать часть объекта (предполагая, что курсор нахо¬ дится где-то в середине его) или нескольких объектов. Ниже приведены некоторые возможности: db и p (или P) d( и p (или P) d( и p (или P) dA и p (или P) Смещение левой части слова Смещение начала предложения Смещение начала раздела Смещение левой части строки dw и p (или P) d) и p (или P) d] и p (или P) d$ и p (или P) Смещение правой части слова Смещение конца предложения Смещение конца раздела Смещение правой части строки хЗ и p (или P) d3w и p (или P) d3) и p (или P) d3) и p (или P) 3dd и p (или P) Смещение трех символов Смещение трех слов Смещение трех предложений Смещение трех разделов Смещение трех строк И снова по команде p производится «выдача» объекта смещения после курсора, а при использовании команды P «выдача» производится перед курсором. (В строко¬ вых операторах по команде p объект смещения выдается под текущей строкой, а по команде P объект выдается над текущей строкой.) Выход из файла Прежде чем переходить к копированию текста в пределах буфера редактирования, откажемся от изменений, которые были сделаны в тексте в нашей рабочей области. Затем мы можем начать повторно все действия с файлом disks. Для отказа от рабо¬ чей области наберите :q! и нажмите клавишу RETURN. Затем наберите vi_disks, что¬ бы начать новую работу с первоначальным текстом.
192 Часть III Копирование текста в пределах файла Копирование текста, расположенного в одном месте, на другое подобно смещению текста. Отличие состоит только в том, что вы будете использовать команду yank вместо команды delete. При команде yank копия текста не исчезает, а остается в его начальном месте расположения. Все остальное остается тем же. Начнем новую ра¬ боту: $ vi disks Копирование слова yw и P ywnp Мы не будем копировать символ, а просто сместим курсор вперед для копирования слова. Копирование слова подобно смещению слова. Основное отличие заключает¬ ся в том, что вы будете «вытаскивать» слово, затем производить подвод курсора к новому месту и «выдавать» здесь слово. В качестве примера скопируем слово Spin- rite из строки 5 в несколько других мест. 1. Переместите курсор в позицию. а) Для подвода курсора к слову Spinrite наберите ISpinrite и нажмите клавишу RETURN. б) На дисплее появится следующее изображение: Spinrite diskettes have а lifetime guarantee. That's right, every Spinrite diskette is guaranteed for life. Not two years, not three years, not five years, but life. 2. «Вытащите» слово с его текущего местоположения. а) Чтобы «вытащить» слово Spinrite, наберите yw. б) Строка будет иметь следующий вид (остается прежней): Spinrite diskettes have а lifetime 3. Переведите курсор в новую позицию. а) Для подвода курсора к слову years в строке 8 наберите lyears. б) Строка будет теперь иметь следующий вид: for life. Not two ^ears, not three 4. «Выдайте» слово в новом месте. а) Для «выдачи» слова Spinrite перед словом years наберите прописную букву P. б) Текст раздела теперь будет иметь следующий вид: Spinrite diskettes have а lifetime guarantee. That's right, every Spinrite diskette is guaranteed for life. Not two Spinrite__years, not three years, not five years, but life. Набирая команду n дважды и повторяя шаг 4 (т. e. nnP), вставьте копии слова Spin¬ rite между словами three и years, а также между five и years. После того как вы сдела-
Редактирование текста с помощью редакторов vi и ex 193 ете это, раздел будет иметь следующий вид: Spinrite diskettes have а Lifetime guarantee. That's right, every Spinrite diskette is guaranteed for life. Not two Spinrite years, not three Spinrite years, not five Spinrite__years, but Life. Копирование предложения у) и P у)ир Копирование предложения подобно копированию слова. Основное отличие сос¬ тоит в том, что команда «вытаскивания» используется в виде у), а не в виде yw. Для копирования предложения переместите курсор к началу предложения, «вытащите» предложение, затем произведите перемещение курсора к новой позиции и «выдай¬ те» здесь предложение. В качестве примера скопируем второе предложение перво¬ го раздела в конец раздела. 1. Переместите курсор в позицию. а) Для подведения курсора к слову That’s наберите ?That и нажмите клавишу RETURN. б) На дисплее появится следующее изображение: Spinrite diskettes have а Lifetime guarantee. That's right, every Spinrite diskette is guaranteed for Life. Not two Spinrite years, not three Spinrite years, not five Spinrite years, but life. 2. «Вытащите» предложение с его текущего местоположения. а) Чтобы «вытащить» полностью второе предложение наберитey). б) Раздел теперь будет иметь следующий вид (остается прежним): Spinrite diskettes have а Lifetime guarantee. That's right, every Spinrite diskette is guaranteed for Life. Not two Spinrite years, not three Spinrite years, not five Spinrite years, but life. 3. Переместите курсор в новую позицию. а) Для подвода курсора к слову five в строке 8 наберите /five и нажмите клавишу RETURN. б) Опустите курсор на строку пробелов путем набора /. в) На дисплее появится следующее изображение: Spinrite years, not five Spinrite years, but life. Advanced technology makes it possible. 4. «Выдайте» предложение в новом месте. а) Для «выдачи» второго предложения после третьего наберите строчную буквур. 7-771
194 Часть III б) Раздел теперь будет иметь следующий вид: Spinn'te diskettes have а Lifetime guarantee. That's right, every Spinrite diskette is guaranteed for life. Not two Spinrite years, not three Spinrite years, not five Spinrite years, but Life. That's right, every Spinrite diskette is guaranteed for Life. Advanced technology makes it possible. в) Чтобы восстановить строку пробелов между разделами, наберите дважды/ для смещения курсора вниз к слову for,наберите о для образования новой строки под этим словом и нажмите клавишу ESC. Копирование раздела у)и P у)ир Копирование раздела подобно копированию предложения. Основное отличие за¬ ключается в том, что в качестве команды «вытаскивания» используется yJ, а не у). Для копирования раздела переведите курсор к началу раздела, «вытащите» раздел, затем переведите курсор в новую позицию и «выдайте» здесь раздел. В качестве примера скопируем второй раздел на место после третьего раздела. Дисплей в на¬ стоящее время должен высвечивать следующее изображение: Spinrite diskette is guaranteed for life. Advanced technology makes it possible. Sophisticated marketing makes it 1. «Вытащите» раздел с его текущего местоположения. а) Чтобы «вытащить» весь второй раздел, наберитеу). б) На дисплее должно быть следующее изображение: Spinrite diskette is guaranteed for life. Advanced technology makes it possible. Sophisticated marketing makes it 2. Переведите курсор в новую позицию. а) Для перевода курсора к началу четвертого раздела наберите дважды ). б) Для поднятия курсора на одну строку и установку под букву а в слове and набери¬ те k. б) На дисплее теперь появится следующее изображение: until it wears out. That's quality, and that's our guarantee. Don't settle for anything less. Don't waste your time with the
Редактирование текста с помощью редакторов vi и ex 195 3. «Выдайте» раздел в новом месте. а) Для «выдачи» второго раздела после третьего наберитер. б) На дисплее появится следующее изображение: Advertisement ★ * * * * * * * * * * * * * ★ * ★ * Spinn'te diskettes have а lifetime guarantee. That's right, every Spinrite diskette is guaranteed for life. Not two Spinrite years, not three Spinrite years, not five Spinrite years, but life. That's right, every Spinrite diskette is guaranteed for life. Advanced technology makes it possible. Sophisticated marketing makes it- incredible. Superior distribution makes it available. And state-of- the-art manufacturing makes it. No matter what you've read, no matter what you've heard, no matter what you've thought, our warranty stands: Every Spinrite diskette will last until it wears out. That's quality, and that's our guarantee. Advanced technology makes it possible. Sophisticated marketing makes it incredible. Superior distribution makes it available. And state-of- the-art manufacturing makes it. Don't settle for anything less. Don't waste your time with the amateurs. Step up to the pro¬ fessionals. Step up to Spinrite. Копирование строки yy и P ууир Копирование строки подобно копированию слова. Основное отличие заключается в том, что используется команда «вытаскивания» строки в видеуу, а не в видеуиг Для копирования строки переместите курсор к строке, «вытащите» строку, затем переме¬ стите курсор к новой позиции и «выдайте» здесь строку. В качестве примера скопи¬ руем первую строку последнего раздела в нескольких местах в тексте. [Этот раздел был скопирован вниз] [Этот раздел является копией раздела из верхней части] 7'
196 Часть III 1. Переместите курсор в позицию. а) Для установки курсора в начале слова settle (первая строка последнего раздела) наберите lsettle. б) На дисплее теперь будет следующее изображение: Don't settle for anything less. Don't waste your time with the amateurs. Step up to the pro¬ fessionals. Step up to Spinrite. 2. «Вытащите» строку из ее текущего местоположения. а) Наберитеуу, чтобы «вытащить» целиком вторую строку. б) Раздел должен будет теперь иметь следующий вид (он остается без изменения): Don't settle for anything less. Don't waste your time with the amateurs. Step up to the pro¬ fessionals. Step up to Spinrite. 3. Переведите курсор в новую позицию. а) Для подвода курсора к словам No matter в предыдущем разделе наберите ?No matter и нажмите клавишу RETURN. б) Строка должна теперь иметь следующий вид: No matter what you've read, no matter 4. «Выдайте» строку в новом месте. а) Для «выдачи» строки, лежащей над текущей, наберите прописную буквуР (но не буквур). б) Начало раздела теперь будет иметь следующий вид: Don't settle for anything less. No matter what you've read, no matter what you've heard, no matter what you've thought, our warranty stands: Другие возможные виды копирования В примерах, которые вы только что рассмотрели, производилось копирование еди¬ ного целого (слова, предложения, раздела или строки) с одного места в другое. Вместе с тем можно копировать часть целого (предполагая, что курсор находится где-то в середине обрабатываемого целого) или нескольких целых частей. Ниже приведены некоторые возможности: yb и p (или P) y( и p (или P) y( и p (или P) уд и p (или P) Копирование левой части слова Копирование начала предложения Копирование начала раздела Копирование левой части строки yw и p (или P) у) и p (или P) у и p (или P) y$ и p (или P) Копирование правой части слова Копирование конца предложения Копирование конца раздела Копирование правой части строки
Редактирование текста с помощью редакторов vi и ex 197 y3w и p (или P) уЗ) и p (или P) уЗ) и p (или P) Зуу и p (или P) Копирование трех слов Копирование трех предложений Копирование трех разделов Копирование трех строк Отметим, что по команде p происходит «выдача» целого после курсора, а по ко¬ манде P — «выдача» целого перед курсором. (В строковых операторах по команде p происходит «выдача» целого на место под текущей строкой, а по командеР— целого над текущей строкой.) , В конце главы давайте выйдем из нашей рабочей области. Затем мы можем начать работу снова с первоначальной версией файла disks в следующей главе. Чтобы выйти из рабочей области, наберите :q! В этой главе вы изучили различные способы выхода из редактора vi и методы сме¬ щения и копирования текста в пределах файла. Здпись и выход. Для записи текста из рабочей области в файл и окончания работы наберите :wq( RETURN). УсловнАЯ здпись. Для записи текста только в случае, если были сделаны изменения, идля последующего выхода наберите ;x<RETURN> илиИ. СохРАНЕниЕ ТЕКСТА в РАБОЧЕЙ ОБЛАСти. Чтобы оставить текст в рабочей области (тем самым сохранить текст в файле), наберите :q!( RETURN>. СмЕЩЕНИЕСИМВОЛА. Для смещения символа с одного места на другое подведите кур¬ сор к месту расположения символа, наберитех, переместите курсор в новую пози¬ цию и наберите строчную буквуp. Если вы пропускаете действие по перемещению курсора между командами x и p, можете переставить два соседних символа. СМЕЩЕНИЕ словд. Для смещения слова используйте команды dw (или dW) и p (или P). СМЕЩЕНИЕ ПРЕДЛОЖЕНИЯ. Используйте команды d) и p (или P). СМЕЩЕНИЕ РАЗДЕЛА. Используйте команды dJ и p (или P). СМЕЩЕНИЕ строки. Используйте команды dd и p (или P). ДругиЕвидысмЕЩЕНИй. Используя правило peflaKTopavi, можете также осуществлять другие виды смещений путем изменения выражения, набираемого nocned. В каждом случае команда p «выдает» объект для смещения после курсора, а команда P — перед курсором. (В строковых операциях команда p «выдает» объект смещения на место под текущей строкой, а команда P — над текущей строкой.) Выход из файла Краткое изложение главы 15 Выход из редактора vi Смещение текста в пределах файла Копирование текста в пределах файла КопировАНИЕСЛОВА. Используйте команды yw (или yW) и p (или P). КопировАниЕ ПРЕДЛОЖЕНИЯ. Используйте команды у) и p (или P). КОПИРОВАНИЕ РАЗДЕЛА. Используйте команды у) и p (или P).
198 Часть III КОПИРОВАНИЕ строки. Используйте команды yy и p (или P). ДругиЕ виды копировАния. Используя правила peflaKTopavi, можно осуществлять дру¬ гие виды копирования путем изменения выражения, набираемого послеу. В каждом случае команда p «выдает» обрабатываемое целое после курсора, а команда Р— перед курсором. (В строковых операциях команда p «выдает» обраба¬ тываемое целое на место под текущей строкой, а команда P — над текущей строкой.) Смещение и копирование (в общем виде) СмЕЩЕНИЕТЕКСТА. Для смещения любого сегмента текста, определенного в редакторе vi, в общем случае вы должны подвести курсор к началу текста, который должен быть смещен, и набрать: dtext затем переместить курсор в новое место и набрать команду P для размещения текста перед курсором или над текущей строкой или команду p для размещения текста по¬ сле курсора или под текущей строкой. КопировАНИЕТЕКСТА. Для копирования любого сегмента текста, определенного в pe- flaKTopevi, необходимо подвести курсор к началу текста, который будет копировать¬ ся, и набрать: ytext затем переместить курсор в новое местои набрать командуР для размещения текста перед курсором или над текущей строкой или командур для размещения текста по¬ сле курсора или под текущей строкой. СЕГМЕНты ТЕКСТА. В обоих из определенных в общем виде команд text — это может быть любой из символов управления перемещением курсора из числа вами изучен¬ ных: w, W, e, E, ), J. (Для смещения символа используется одиночная команда x — единственное исключение.) МНОЖЕСТВЕННЫЕ Функции. Выше мы использовали множители в основном между дву¬ мя символами (как в команде d2W). Однако отметим, что редактор vi допускает ис¬ пользование множителя перед символами (как в команде 2dW) и даже использова¬ ние одного множителя перед каждым символом в команде (как в команде 3d2W), что будет указывать на удаление шести слов при игнорировании знаков пунктуации. Глава 16. Использование редактора vi при работе с несколькими файлами В главе 15 вы изучили, как смещать и копировать текст с одного места файла в дру¬ гое. В этой главе вы изучите, каким образом смещать и копировать текст из одного файла в другой, что обеспечивает редактирование второго файла без выхода из ре¬ дактора vi. Вы изучите также, каким образом помечать файл и начинать редактиро¬ вание с помощью различных опций. Редактирование другого файла В редакторе vi, как и в ed, можно начинать редактирование нового файла без выхо¬ да из вашего редактора и возврата в shell. Для этого можно использовать несколько команд в зависимости от того, каким образом вы хотите сохранить ваш текущий файл.
Редактирование текста с помощью редакторов vi и ex 199 Сохранение и редактирование :e Если вы уже располагаете сохраненным текущим файлом (команда :w), можете на¬ чинать редактирование другого файла без выхода из vi с помощью команды :e (edit — редактировать). Для этого выполняются действия в следующей последова¬ тельности: :w oLd file RETURN :e new fi Le RETURN Сохранение старого файла Начало редактирования нового файла Выход и редактирование :e! Если вы не хотите сохранять текущий файл, можете начинать редактирование дру¬ гого файла сразу же по команде :e/ следующим образом: :e! new file RETURN Выход из старого файла и начало редактирования нового Авторедактирование :n Если вы хотите, чтобы ваш файл был сохранен автоматически, как только начина¬ ете работать с другим файлом, вы должны установить опцию автозаписи по коман¬ де :set (как описано в гл. 17). Выполнив это однажды, можете затем использовать команду :n для начала редактирования нового файла следующим образом: :n new file RETURN Начало редактирования нового файла (старый файл автоматически сохраняется) Имеется другой вариант команды :n, которую вы можете использовать при ре¬ дактировании более чем одного файла. Допустим, вы вызвали peflaKTopvi с указани¬ ем трех файлов, которые должны быть отредактированы, как показано ниже: vi fi Le.1 file.2 fi le.3 Редактирование начнется с файла7/7е.7. По мере окончания работы cfile.1 мо¬ жете набрать :n без имени файла. Если вы установили опцию автозаписи, текст из буфера редактирования будет автоматически записан в файл7/7е.7 и файл//7е.2 бу¬ дет считан в буфер редактирования. После того как вы закончили работать с фай- noMfile.2, наберите снова :n, чтоб записать файл7/7е.2 и вызвать в буфер файл7/7е.З. Теперь проверим это свойство. 1. Подготовьте авторедактирование. а) начните редактирование трех различных файлов: $ vi letter metric.c disks 3 fi Les to edit "letter" 17 lines, 377 characters б) Когда текст письма окажется на экране, установите режим автозаписи: :set aw
200 Часть III 2. Выполните авторедактирование. а) Без внесения каких-либо изменений в текст письма перейдите к следующему фай¬ лу (metric.c): ш "metric.c" 19 lines, 332 characters б) Без внесения каких-либо изменений в текст перейдите к следующему файлу (disks): ЕЮ "disks" 27 lines, 733 characters 3. Закончите эту работу: ЕЮ Итак, имеется очень удобное средство редактирования, которое позволяет вы¬ зывать несколько файлов одновременно и производить их перемещение. Если вы попытаетесь произвести в данном примере третье перемещение, увидите, что поя¬ вится сообщение: No more files to edit (больше нет файлов для редактирования). Пересылка текста между файлами Перемещение текста из одного файла в другой подобно смещению текста в преде¬ лах одного файла, но имеется два отличия: • Вы можете оставить текст во временной области памяти (буфере), имеющей одно¬ символьное имя. • Вы можете вызвать новый файл без выхода из peflaKTopavi, используя одну из ко¬ манд, которые вы изучили раньше в этой главе: Редактирование с сохранением Выход из текста и редактирование Редактирование с автоматическим сохранением :e fite RETURN :e! fUe RETURN :n fi Le RETURN Начало новой работы Прежде чем перемещать какой-либо текст, начнем новую работу редактора vi с фай- noMdisks. Наберитеу/ disks и нажмите клавишу RETURN. vi disks RETURN Перемещение предложения ”xd) и ”хР ”xd) и ”хР Перемещение предложения в другой файл подобно смещению предложения в пре¬ делах одного файла. Для этого необходимо подвести курсор к предложению, уда¬ лить это предложение в файле и перенести предложение в буфер, затем подвести курсор в позицию нового файла и «выдать» предложение из того же буфера. В ка¬ честве примера переместим предложение из файласУ/s^s в конец файла/effer. 1. Переместите курсор в позицию. а) Для подвода курсора к слову That’s наберите IThat и нажмите клавишу RETURN.
Редактирование текста с помощью редакторов vi и ex 201 6) На дисплее появится следующее изображение: Spinrite diskettes have а Lifetime guarantee. That's right, every Spinrite diskette is guaranteed for life. Not two years, not three years, not five years, but life. 2. Удалите предложение с его текущего местоположения. а) Наберитe"ad), чтобы удалить целиком второе предложение в буфер с именем "а”. б) Раздел будет иметь теперь следующий вид: Spinrite diskettes have а lifetime guarantee. Not two years, not three years, not five years, but life. 3. Вызовите файл letter и переместите курсор в новую позицию. а) Для того чтобы автоматически сохранить файл disks и получить для редактирова¬ ния файл letter, наберите :n letter и нажмите клавишу RETURN. б) После появления текста на экране наберитеЭ, чтобы переместить курсор в конец файла. в) На дисплее появится следующее изображение: The Man for the Job: Franklin F. Failsquick, Jr. Chief Consulting Officer 4. «Выдайте» предложение на новое место из буфера "а”. а) Чтобы взять предложение из буфера "а” и «выдать» его в конец текста файла let¬ ter, наберите "ар. б) На дисплее появится теперь следующее изображение: The Man for the Job: Franklin F. Failsquick, Jr. Chief Consulting Officer That's right, every [Здесь нет пустой строки] Spinrite diskette is guaranteed for life. Перемещениераздела ”xd) и "xP "xd)и"xP Перемещение раздела подобно перемещению предложения. Основное отличие за¬ ключается в том, что для удаления используется команда d], а не d). Чтобы переме¬ стить раздел, необходимо подвести курсор к началу раздела, перенести раздел в бу¬ фер, затем переместить курсор в новую позицию и «выдать» здесь раздел из того же буфера. В качестве примера переместим раздел из файла letter в файл disks. 1. Переместите курсор в позицию. а) Для перемещения курсора к началу первого раздела файла letter наберите ?/ wish. б) Для перемещения курсора к предшествующей строке пробелов наберите^.
202 Часть III в) На дисплее теперь появится следующее изображение: I wish to thank you profusely for your letter of March 2. It is always a special delight to read and enjoy all your extraordinary ideas. 2. Удалите раздел из текста и поместите его в буфер ”. а) Чтобы перенести весь второй раздел в буфер , наберите "bd]. б) На дисплее теперь появится следующее изображение: Dear Mrs. Benson: We are incapable of completing the job you asked for. We don't know what we're doing. 3. Начните редактирование dpa&\naclisks и переместите курсор в новую позицию: а) Чтобы выйти из текста файла letterи получить файл наберит б) Когда появится текст, наберите INo matter, чтобы подвести курсор к началу треть¬ его раздела. в) Для подвода курсора к предшествующей строке пробелов наберитек. г) На дисплее появится следующее изображение: No matter what you've read, no matter what you've heard, no matter what you've thought, our warranty stands: 4. «Выдайте» раздел на новое место из буфера "b". а) Для «выдачи» раздела на место, расположенное над текущей строкой, наберите "bP. б) На дисплее появится следующее изображение: Advanced technology makes it possible. Sophisticated marketing makes it incredible. Superior distribution makes it available. And state-of- the-art manufacturing makes it. 2 wish to thank you profusely for your letter of March 2. It is always a special delight to read and enjoy all your extraordinary ideas. No matter what you've read, no matter what you've heard, no matter what you've thought, our warranty stands: Every Spinrite diskette will last until it wears out. That's quality, and that's our guarantee.
Редактирование текста с помощью редакторов vi и ex 203 Сохранение текста Прежде чем начинать копирование текста в другой файл, оставим текст в нашей ра¬ бочей области. Затем можно начинать повторно проводить все, что изложено выше с файлами letter и disks. Наберите :q!, чтобы оставить рабочую область, а затем на¬ берите: $ vi disks RETURN чтобы начать новую работу с первоначальным текстом. Копирование текста в другой файл Копирование текста изодного файла в другой в редактореу1 подобно перемещению текста. Единственное отличие состоит в том, что используется команда у (yank — вытащить) вместо команды удаления d. Копирование предложения " xy) и "xp "xy)H"xP Для копирования предложения, которое выполняется так же, как перемещение предложения, необходимо подвести курсор к предложению, «вытащить» предложе¬ ние в буфер, затем переместить курсор в новую позицию и «выдать» предложение в эту позицию из того же буфера. В качестве примера давайте скопируем предложе¬ ние из dpaunadisks в файл letter. 1. Переместите курсор в позицию. а) Переместите курсор noflS в словeSuperior: /Superior RETURN б) На экране дисплея появится теперь следующее изображение: Advanced technology makes it possible. Sophisticated marketing makes it incredible. Superior distribution makes it available. And state-of- the-art manufacturing makes it. 2. «Вытащите» предложение с его текущего местоположения в буфер "с". а) Чтобы полностью «вытащить» второе предложение, наберите”су;. б) Раздел будет иметь следующий вид (остается неизменным): Advanced technology makes it possible. Sophisticated marketing makes it incredible. Superior distribution' makes it available. And state-of- the-art manufacturing makes it.
204 Часть III 3. Начните редактирование файла/efter и переместите курсор в новую позицию. а) Наберите:е/ __letter и нажмите клавишу RETURN, чтобы оставить dpawndisks и вы¬ звать файл letter. б) Когда появится изображение, наберите IYour и нажмите клавишу RETURN для пе¬ ремещения курсора к строке, в которой содержится текст Your... servant. в) На экране появится следующее изображение: We don't know what we're doing. Your most humble, obedient servant 4. «Выдайте» предложение на новое место из буфера "с". а) Наберите ”сР, чтобы «выдать» предложение на место, находящееся над текущей строкой. б) Теперь изображение на дисплее будет иметь следующий вид: We are incapable of completing the job you asked for. We don't know what we're doing. Superior distribution makes it available. Your most humble, obedient servant Копированиераздела "xy) и"хр "xy) и”хР Для копирования раздела, которое выполняется так же, как перемещение предло¬ жения, необходимо подвести курсор к началу раздела, «вытащить» раздел в буфер, затем переместить курсор в новую позицию и «выдать» здесь раздел из того же бу¬ фера. В качестве примера скопируем раздел из файла/etter в файл disks. 1. Переместите курсор в позицию. а) Для перемещения курсора к началу предыдущего раздела наберите дважды фи¬ гурную скобку). б) На дисплее должно появиться следующее изображение: We are incapable of completing the job you asked for. We don't know what we're doing. Superior distribution makes it available. Your most humble, obedient servant 2. «Вытащите» предложение с его текущего местоположения в буфер "d". а) Чтобы «вытащить» полностью второй раздел в буфер "cf", наберите "dy. б) На дисплее должно появиться теперь следующее изображение (остается без изме¬ нений): We are incapable of completing the job you asked for. We don't know what we're doing. Superior distribution makes it available. Your most humble, obedient servant 3. Вызовите файл disks и переместите курсор в новую позицию, а) Для выхода из текста/efter и получения dpawnadisks наберитe:e!disks.
Редактирование текста с помощью редакторов vi и ex 205 б) Чтобы подвести курсор к началу последнего раздела, наберите IDon’t, затем набе¬ рите^, чтобы подвести курсор к строке пробелов. в) На экране должно появиться следующее изображение: Don't settle for anything less. Don't waste your time with the amateurs. Step up to the pro¬ fessionals. Step up to Spinrite. 4. «Выдайте» раздел на новое место из буфера "cf". а) Для «выдачи» разделу на место, находящееся над текущей строкой, из буфера "d" наберите "dP. б) На дисплее должно появиться теперь следующее изображение: Every Spinrite diskette will last until it wears out. That's quality, and that's our guarantee. We are incapable of completing the job you asked for. We don't know what we're doing. [Вставленныйтекст] Don't settle for anything less. Don't waste your time with the amateurs. Step up to the pro¬ fessionals. Step up to Spinrite. Сохранение текста Прежде чем закончить обсуждение вопроса о копировании текста, оставим текст в нашей рабочей области. Затем мы можем снова начать выполнять все действия, описанные в следующей главе с первоначальной версией файла. Чтобы оставить рабочую область, наберите.д/ Вызов редактора vi До сих пор редактор vi вызывался вами с помощью простейшей формы командной строки, что устанавливало курсор в начало файла без указания каких-либо дополни¬ тельных опций: vi letter Вместе с тем имеется ряд опций, которые доступны вам в начале редактирования. Определение начальной строки + line В начале работы вы можете определить номер строки, с которой хотите начать ре¬ дактирование. Для этого наберите «плюс» и за ним — номер строки. Все набирается после символов vi. Для иллюстрации сказанного (предполагая, что вы находитесь в каталогеГех? _files) проверим вызов файлашеГг/с.с сустановкой курсора в начало основной подпрограммы (routine) в тексте программы (строка 14). Это осуществляет¬ ся по команде: $ vi +14 metric.c
206 Часть III Полученное изображение должно иметь следующий вид: gaLLons = low; while (gallons <= high) { _h'ters = (gallons * 3.785); printf("%4.0f %6.2fW, gallons, liters); gallons = gallons + incr; > "metric.c" 18 lines, 404 characters Можно использовать вариант рассмотренного действия — использовать поиск строки по ключу вместо указания номера строки. Для иллюстрации сказанного набе- рите.д и нажмите клавишу RETURN для выхода H3vi, затем повторно войдите в файл с первой строки, которая содержит слово float vi +/float/ metric.c [Можно набрать здесь + / float ] Полученное изображение должно иметь следующий вид: /* List conversions from gallons to liters */ main() < int low, high, incr; float gallons, liters; low = 10; /* starting value in gallons */ high = 20; /* ending value in gallons */ incr = 2; /* increment for each step */ "metric.c" 18 lines, 404 characters Другой вариант — использовать «плюс» для выставления курсора на последнюю строку файла. (Это может быть полезным, если вы хотите добавить в конец файла новый текст.) Для иллюстрации этого действия наберите :q и нажмите клавишу RETURN, чтобы выйти из vi, а затем повторно войдите в файл на его последнюю строку: $ vi + metric.c Полученное изображение будет иметь следующий вид: low = 10; /* starting value in gallons */ high = 20; /* ending value in gallons */ 11) Слово float служит для организации контекстного поиска строки, т. e. поиска по клю¬ чу. — Прим. ред.
Редактирование текста с помощью редакторов vi и ex 207 incr = 2; /* increment for each step */ gaLLons = low; whiLe (gallons <= high) { liters = (gallons * 3.785); printf("%4.0f %6.2f\n", gallons, liters); gallons = gallons + incr; > "metric.c" 18 lines, 404 characters Теперь вы можете набрать :q и нажать клавишу RETURN, чтобы опять выйти H3vi и сразу же возвратиться в shell системы Юникс. Выбор опций Если «плюс» служит для указания номера начальной строки, «минус» указывает на одну из пяти возможных опций редактора vi. Каждая опция выбирается путем набо¬ ра одной буквы после «минуса»: — r ВосстАНОВЛЕНИЕ ФАЙЛА. Использование этой опции после системного или программного краха1* (системы Юникс или редактора vi) обеспечивает со¬ хранение самой последней версии файла. Если вы опустили имя файла, то имена файлов, которые могли бы быть восстановлены, будут отпечата¬ ны. (Отметим, что системный или программный крах обычно не является катастрофическим. Вы можете использовать определенные опции для ре¬ старта.) - R Только читАТЬ. Эта опция используется для редактирования файла в ре¬ жиме «только читать» и означает, что файл можно только просматривать, но не модифицировать. -t ПокАЛЬНЫйТЕГ. Эта опция используется для вызова файла, который со¬ держит поименованный тег, и устанавливает начало редактирования с места, определенного тегом. (Данная опция рассмотрена в следующем разделе.) -x РАСШИФРОВЫВАЮЩЕЕ чтЕНИЕ. Эта опция используется для просмотра истин¬ ного содержания текста в зашифрованном файле. (Сам файл не обяза¬ тельно расшифровывается.) Ниже приведено несколько примеров для иллюстрации использования перечислен¬ ных выше опций: Сохранение файла letter Редактирование файла те/г/с.с(только для чтения) Начать редактирование файла, содержащего поименованный тег, и установить курсор в позицию тега Редактировать зашифрованный файл remark, crypt 1) В системе крахом (crash) называют ситуацию, когда она не может функционировать по каким-либо причинам. — Прим. ред. vi -r letter vi -R metric.c vi -t tag vi -x remark.crypt
208 Часть III Использование тегов в текстовых файлах Вы только что изучили, какспомощью peflaKTopavi открыть файл и сместить курсор под определенную строку (в разделе «Определение начальной строки»). С помощью тегов можно выполнить те же действия. Редактор vi позволяет составить отдельно файл, содержащий список начальных точек (или «тегов») в текстовом файле, с кото¬ рым вы работаете. Файл, который содержит теги, называется tags; другие имена для него использовать нельзя. Например, предположим, что вы используете файлс^Яэ очень часто и хотели бы быстро получать доступ к нему. Предположим также, что вы хотели бы иметь воз¬ можность отмечать начало каждого раздела, чтобы начинать редактирование лю¬ бого из них по указанной отметке. Ниже показано, каким образом это можно сде¬ лать. 1. Соедините ваши теги в отдельный файл tags. а) Создайте новый файл, называемый tags: $ vi tags б) Нажмитеа для определения режима «ввод текста» и введите следующие четыре строки с колонками, установленными по знакам табуляции: par.1 cH sks 5 раг.2 di sks /Advanced/ раг.З di sks 17 раг.4 di sks /sett Le/ ESC в)Теперь сохраните текст и по команде/wqf возвратитесь в shell Юникс: fTwql ''tags11 5 lines, 74 characters $ Каждая строка в файле тегов содержит три поля, разделенные знаками табуляции: Имя тега Имя файла Местоположение тега Местоположение тега указывается с помощью либо номера строки, либо коман¬ ды поиска, как описано выше в разделе «Определение начальной строки». Однако в файле тегов знак «плюс» не используется перед информацией. Две из приведенных выше записей содержат номера строк, а две — ключевые слова для организации по¬ иска. Для третьей записи обозначениepar.3 (paragraph 3 — раздел 3) — имя тега]disks — имя файла, который содержит тег, а число 17 указывает местоположение тега (строка 17 — номер строки, с которой начинается третий раздел). 2. Используйте данный файл тегов для начала редактирования. а) Используйте опции -t из состава команд редактора vi, чтобы начать редактиро¬ вание с начала третьего раздела (тегpar. 3): vi -t par.3 Имя файла не требуется [Вам даже не потребовалось имя файла.] б) На экран будет выведен файлсУ/s^s при расположении курсора на первой строке третьего раздела:
Редактирование текста с помощью редакторов vi и ex 209 Advanced technology makes it pqssible. Sophisticated marketing makes it incredible. Superior distribution makes it available. And state-of- the-art manufacturing makes it. No matter what you've read, no matter [Курсор устано- what you've heard, no matter what вится здесь] you've thought, our warranty stands: Every Spinrite diskette will last until it wears out. That's quality, and that's our guarantee. Вы можете использовать теги не только, когда начинаете редактирование, но и в процессе редактирования другого файла. Для этого используйте команду :tag из командного режимау| для указания имени тега. Например, пусть вы редактировали файл letter. Если вы хотите сохранить текст с учетом самых последних изменений, можете набрать в командном режиме vi команду, подобную следующей: :tag раг.З В заключение следует отметить, что в приведенном выше примере мы использо¬ вали только теги из одного файла. Однако ваш файл тегов может содержать записи для многих различных файлов при условии, что вы упорядочили их в алфавитном порядке. (Для этого можете использовать команду сортировки sort.) Поскольку при работе номера строк могут изменяться, то лучше использовать в качестве указате¬ лей ключевые слова для организации поиска местоположения тега. Использование тегов в программах При написании программ на языках Си, Фортран или Паскаль вы можете использо¬ вать в системе Юникс nporpaMMyctags, чтобы создавать автоматически файл тегов. Программа ctags будет заводить по одной записи на каждую функцию в вашей про¬ грамме. Например, пусть вы хотите создать файл тегов для программы, называемой list.c, которая содержит три функции: main() split(x) unite(y) Если вы выполните командную строку: $ ctags list.c $ то программа ctags создаст файл тегов из трех строк, который называется tags и может быть просмотрен по команде cat: $ cat tags Mlist list.c 7AmainO$? split list.c 7Asplit(x)$? unit list.c 7Aunite(y)$? $
210 Часть III Первое имя тега, используемое программой ctags, всегда будет именем исходно¬ го файла (с буквой M, добавленной перед именем, и без знаков .c, удаленных в кон¬ це). Программа ctags выбирает только имена функции, расположенные на отдель¬ ных строках. ПРЕДОСТЕРЕЖЕНИЕ. nporpaMMactags сотрет ваш текущий файл тегов, перезаписывая в него собственные записи. Поскольку программа ctags отмечает тегами только функции и не «щадит» ваши текущие теги — это серьезный недостаток, поэтому используйте эту программу, только если можете допустить ее ограничения. Краткое изложение главы 16 В этой главе вы изучили, каким образом начинать редактирование различных фай¬ лов без выхода из peflaKTopavl. Вы также изучили два разных метода перемещения (или копирования) текста из одного файла в другой. Наконец, вы изучили опции, ко¬ торые доступны в начале новой работы по редактированию, и попробовали исполь¬ зовать теги. Редактирование другого файла СОХРАНЕНИЕ и РЕДАКТИРОВАНИЕ. Для сохранения текста из вашего текущего файла пе¬ ред вызовом другого используйте команду :w для записи старого файла и команду :e для чтения нового файла. РЕДАКТИРОВАНИЕ с ОСТАВЛЕНИЕМ ТЕКСТА. Чтобы оставить текст из вашего текущего фай¬ ла и начать сразу редактировать другой файл, используйте команду :e!. АвтоРЕДАКтиРОВАНИЕ. Для автоматического сохранения вашего файла перед тем, как вызвать другой, вы должны установить опцию автозаписи. Затем используйте команду :n. Перемещение текста в другой файл ПЕРЕМЕЩЕНИЕ ПРЕДЛОЖЕНИЯ. Используйте команды ”xd) и ”хр (или ”хР), где ”х” — лю¬ бой из 26 буферов, обозначаемый строчной буквой алфавита. ПЕРЕМЕЩЕНИЕ РАЗДЕЛА. Используйте команды ”xd] и ”хр (или "xP). ДругиЕ виды ПЕРЕМЕЩЕНИЙ. Используя правила редактирования в vl, вы можете осу¬ ществлять другие виды перемещений путем изменения выражения, набираемого по¬ сле команды ”xd (w, e и т. д.). Еще раз напомним, что по команде p объект «выдается» после курсора, а по ко¬ манде P — перед курсором. (В строковых операторах команда p «выдает» объект под текущей строкой, а команда P — над текущей строкой.) Копирование текста в другой файл КопировАНИЕ ПРЕДЛОЖЕНИЯ. Используйте команды ”ху) и p (или P). КопировАНИЕ РАЗДЕЛА. Используйте команды ”ху) и p (или P). ДругиЕ виды копировАния. Используя правила редактирования в vi, вы можете осу¬ ществлять другие виды копирования путем изменения выражения, набираемого по¬ сле команды ”ху (w, e и т. д.) Еще раз напомним, что по команде p объект копирования «выдается» после кур¬ сора, а по команде P — перед курсором. (В строковых операторах команда p «выда¬ ет» объект под текущей строкой, а команда P — над текущей строкой.)
Редактирование текста с помощью редакторов vi и ex 211 Перемещение и копирование в общем виде ПЕРЕМЕЩЕНИЕ ТЕКСТА. Для перемещения любого сегмента текста, определенного в vi, в другой файл необходимо установить курсор на начало перемещаемого текста и на¬ брать: "xdtext Затем перевести курсор в новую позицию и набрать команду P для размещения текс¬ та перед курсором или над текущей строкой или команду p для размещения текста после курсора или под текущей строкой. КОПИРОВАНИЕ ТЕКСТА. Для копирования любого сегмента текста, определенного в vi, в другой файл, необходимо переместить курсор в начало копируемого текста и на¬ брать "xytext Затем переместить курсор в новую позицию и набрать команду P для размещения текста перед курсором или над текущей строкой или командурдля размещения текс¬ та после курсора или под текущей строкой. ИМЕНА БУФЕРОВ. Вы можете использовать любую строчную букву алфавита для при¬ своения имени буферу. СЕГМЕнты ТЕКСТА. В используемых выше предложениях слово text означает, что на этом месте может быть любой из изученных вами символов управления курсором: w, W, e, E,), J. (Для перемещения символа используется толькох — единственное исклю¬ чение.) Средства для начала новой работы с редактором ОПРЕДЕЛЕНИЕ нАЧАЛьной строки. Для определения начальной строки в момент начала вашей работы с vi наберите: vi, «пробел», знак «плюс», номер строки, еще «пробел», имя файла. В качестве «номера строки» можно использовать следующее: число, строку для поиска, пробел. Выворопции. Для выбора одной из четырех специальных опций в начале работы с vi наберите: vi, «пробел», знак «минус», букву, другой «пробел», имя файла. Используе¬ мые опции: - r (восстановление файла), - R (только читать), -1 (локальный тег) и - x (расшифровывающее чтение). ЙспользовАНИЕТЕГов. Вы можете создать файл тегов в виде списка начальных точек для редактирования в vi, а затем начать редактирование в одной из этих точек с по¬ мощью использования либоопции -t в командной CTpoKevi, либо команду1ад в про¬ цессе редактирования. Глава 17. Настройка характеристик peflaKTopavi В предыдущих главах вы изучили, как использовать peflaKTopvi в его стандартных операционных режимах. В этой главе вы изучите, каким образом с помощью опций, определяемых пользователем, изменять его многие свойства и каким образом ис¬ пользовать сокращения и ключи. Установка опций В главе 16 вы использовали команду :set для установки двух опций в vi. Они позволя¬ ют проводить нумерацию строк и устанавливать ширину сдвига:
212 Часть III :set nu Установить нумерацию строк set sw = 5 Установить ширину сдвига, равную 5 позициям Наиболее важной характеристикой является наличие сокращений, таких, как nu (для number — номер) и sw (для shift width — ширина сдвига). Большинство опций устанавливаются в ключевом режиме: характеристика опций либо включена (nu), либо выключена (nonu). Другие опции требуют специально присваиваемых величин, которые могут быть либо числами, либо строками символов. В этой главе мы рассмотрим несколько наиболее часто используемых опций. Список всех опций в peflaKTopevi приведен в приложении 4. Выполнение временных изменений Для установления опции на период времени редактирования вы должны только на¬ брать команду :set в командном режимеу| и нажать клавишу RETURN. Опция, кото¬ рую вы установили, будетдействовать только до тех пор, пока вы не noKHHeTevi и не возвратитесь в shell системы Юникс. Ниже приведены три примера команд: :set aw :set report = 3 :set wm = 6 Установить автозапись (принудительная автоматическая за¬ пись перед вызовом нового файла или исполнением shell- команды системы Юникс). Установить значение report (сообщение), равное 3 (требование, чтобы сообщение после любого действия влекло за собой три повторения, таких, например, как три удаляемые строки, три подсоединяемые строки и т. д. И не может быть сообщений меньше трех). Установить значение «заворачивание на границе» равным 6. Изменение ширины каждого сдвига Для иллюстрации действия по изменению значения опции используем файл для проведения некоторых экспериментов. 1. Начните новую работу с новым файлом. а) По приглашению shell системы Юникс наберите vi custom и нажмите клавишу RETURN, чтобы начать новую работу с файлом custom. б) Наберите приведенный ниже текст с нажатием клавиши RETURN в конце каждой строки (и нажатием ESC в конце текста для возврата в командный режим vi): Settings for vi Неге are а few lines of text to demonstrate how we can change the way the editor works. ESC 2. Переместите текст относительно его текущего местоположения: а) Наберите 7Here, чтобы подвести курсор кбуквеН в словeHere, затем наберите >), чтобы сдвинуть предложение вправо: Settings for vi Here are а few Lines of text
Редактирование текста с помощью редакторов vi и ex 213 to demonstratehow we can change the way the editor works. 6) Как вы можете видеть, каждый сдвиг перемещает текст на 8 позиций вправо. 3. Измените значение опций shift width (ширина сдвига). а) Наберите/sefsw? (сознаком вопроса в конце) и нажмите клавишу RETURN для про¬ верки текущего значения ширины сдвига: :set sw? б) Вы увидите ответ на служебной строке в нижней части экрана, который указыва¬ ет, что каждый сдвиг в текущий момент будет перемещать на 8 позиций: shi ftwidth=8 в) Для изменения величины ширины сдвига наберите set sw = 5 и нажмите клавишу RETURN. :set sw=5 г) Для сдвига предложения назад влево наберите <(. Settings for vi Неге are а few Lines of text to demonstrate how we can change the way the editor works. Как видно, каждый сдвиг перемещает теперь текст на 5 позиций вместо восьми. Проверьте несколько видов сдвига, а затем восстановите текст в его первоначаль¬ ном виде. «Заворачивание» слов на границе Другая опция изменяет в vi управление вводимыми словами по мере того, как курсор приближается к правому краю экрана. Если эта опция отсутствует, при наборе сло¬ ва на границе экрана его остаток будет переходить границу экрана. (Ваш терминал, но не редактор vi, может «заворачивать» слова на начало следующей строки.) Одна¬ ко при использовании опции «заворачивание на границе» вы можете заставить ре¬ дактор vi «завернуть» слово на следующую строку, что является общим свойством си¬ стем обработки символьной информации. Значение опции определяет «заворот» в форме положительного числа. 1. Проверьте ввод некоторого текста без опции. а) Установите курсор на последнюю строку (L). б) Нажмите клавишу RETURN и наберите команду а для указания на подсоединение текста, затем наберите следующий текст1) без нажатия клавиши RETURN в конце строки: 1)Текст набирается на строке подряд исходя из того, что строка может содержать 80 сим¬ волов. — Прим. ред.
214 Часть III We're going to type a very long line of text to see what happens when we get close to the side of the screen. в) В конце нажмите ESC для возвращения в командный режим vi. Словос/ose будет расщеплено на границе экрана (предполагается, что строка ва¬ шего экрана вмещает 80 символов) следующим образом: clo/se. Но это результат работы терминала, а не редактора vi. 2. Измените значение опции «заворачивание на границе». а) Наберите :set wm7(c вопросительным знаком в конце) и нажмите клавишу RETURN для проверки текущего состояния опции «заворачивание на границе»: :set wm? б) Вы увидите ответ в нижней части экрана, говорящий о том, что опция для завора¬ чивания слов не включена: wrapmargin=0 в) Наберите :set wm = 10 и нажмите клавишу RETURN для установления значения «за¬ ворачивания» на 10. :set wm=10 3. Теперь вводите текст для проверки свойств при установке значения опции. а) Переведите курсор на последнюю строку (L), наберитеа и следующий текст (вто¬ рично) — опять же без нажатия клавиши RETURN в конце строки: This time we're going to type а very long line of text to see what hapDens when we get close to the side of the screen. б) В конце наберите ESC для возвращения в командный режим vi. Поскольку вы установили величину «заворачивания на границе», равную 10, то редактор vi «завернет» слово when на следующую строку (в предположении, что ваш терминал имеет 80 знакомест на строке). Число 10 указывает peflaKTopyvi на необхо¬ димость «заворачивания» любого слова, которое будет попадать в поле из десяти позиций, отсчитывая от правого края экрана. Выполнение других изменений Вы можете устанавливать ряд опций для выбора планируемого вида работы. Ниже приведены несколько таких средств: :set ai Установка автоотступа. (При нажатии клавиши RETURN курсор переме¬ щается на следующую строку, но с тем же отступом, который был в тексте предыдущей строки.) :set list Установка списка list (на экране высвечиваются знаки табуляции и символы новых строк подобно списку команд в peflaKTopeed). :set nu Установка номера (на экране высвечиваются номера строк). Для просмотра списка текущих значений всех опций в peflaKTopevi используйте команду :set all: :set all
Редактирование текста с помощью редакторов vi и ex 215 На дисплее появится следующее изображение (подробности приведены в приложе- нии 4): noautoi ndent open noslowopen autoprint nooptimi ze tabstop=8 noautownte paragraphs=IPLPPPQPP LIpplpipbp taglength=0 nobeauti fy prompt tags=tags /usr/lib/tags di rectory=/tmp noreadonly term=adm3 noedcompatible redraw noterse noerrorbells remap timeout hardtabs=8 report=5 ttytype=adm3 noignorecase scroll=11 warn noli sp sections=NHSHH HUnhsh- wi ndow=23 nolist shell=/bin/sh wrapscan magi с shiftwidth=5 wrapmargi n=10 nonumber noshowmatch nowri teany [Hit return to continue]_ Установление постоянного действия изменений Если вы решили, какие опции будут работать при использовании vi, можно их сохра¬ нить путем создания из них отдельного файла. Этот файл, называемый .exrc (ex read command) считывается в начале каждого сеанса работы с vi. Например, допустим, вы хотите иметь средства автоматической записи и значение «заворачивания на границе», равноеб, считая от края экрана. Для этогозакончите pa6oTycvi, войдите в ваш начальный каталог, создайте файл по имени .exrc и введите следующие строки (без двоеточия): set autoindent set ai set autowrite или set aw или set ai aw wrp=6 set wrapmargin=6 set wm=6 Сохраните текст (по команде \wq) и возвратитесь к файлу text __ files (по команде cd text _ files). Затем при следующем сеансе работы cvi перечисленныеопции будут введены в действие автоматически. Вам не потребуется набирать какую-либо из команд установки опции. Определение сокращений аь Если вам приходится неоднократно набирать длинное имя или строку, удобно иметь средство ввода сокращенной формы такого повторяющегося объекта. В ре¬ дакторе vi имеется команда, которая позволяет заменять длинную строку коротким сокращением1>. Затем после установленного такого присвоения вы можете наби¬ рать сокращение, а vi будет заменять его длинным текстом. Установление временного действия сокращений Для того чтобы можно было использовать сокращения, присваиваемые во время те¬ кущей работы, наберите команду :ab, «пробел», сокращение, другой «пробел», полную, без сокращений строку и затем нажмите клавишу RETURN. Например, ис¬ пользуя повторно файл custom, выполним следующую процедуру: 1) Это можно назвать операцией присваивания. — Прим. ред.
216 Часть III 1. Вызовите peflaKTopvi (если необходимо) и сместите курсор к концу рабочей обла¬ сти. а) Если peflaKTopvi не работает, наберитеу/ + custom для того, чтобы начать новый сеанс работы с файлом custom при расположении курсора в конце файла. б) Если редактор работает и текст файлас^ол? уже находится на экране, наберите L, чтобы переместить курсор в конец текста. 2. Присвойте сокращения. а) Для того чтобы для строки текста XENIX operating system установить сокращение xen, наберитe:ab xen XENIX operating system, а затем нажмите клавишу RETURN. б) Для того чтобы для строки текста UNIX operating system установить сокращение unx, наберите ab unx UNIX operating system, а затем нажмите клавишу RETURN. в) Для того чтобы для строки текста Bell Telephone Laboratories установить сокраще¬ ние btl, наберите ab btl Bell Telephone Laboratories, а затем нажмите клавишу RETURN. 3. Наберите предложение сиспользованием трех сокращений. а) Наберитea и введите следующее ниже предложение, в конце которого нажмите ESC: The xen was derived from the unx, which originated at btL in 1969. ESC б) Ниже приведен данный текст на экране: The XENIX operating system was derived from the UNIX operating system, which originated at BeLL Telephone Laboratories in 1969. Этот простой пример должен убедить вас в значимости данного свойства (часто используемое в индустрии текстовой обработки под названием «глоссарий»). Осуществление постоянного действия сокращений Любые сокращения, которые вы планируете часто использовать, могут быть добав¬ лены к вашему файлу .exrc наряду с командами установки set. Например, чтобы обеспечить доступность в любой момент времени использования редактора к трем сокращениям, которые были только что рассмотрены, включите их в файл .exrc сле¬ дующим образом: set autoindent set autowrite set wrapmargin=6 ab xen XENIX operating system ab unx UNIX operating system ab btl Bell Telephone Laboratories В данных примерах мы умышленно использовали трехсимвольные сокращения. Вы можете использовать и более короткие сокращения, но при этом возникает опас¬ ность набора вашего сокращения как части другого слова из-за случайной подмены в длинном тексте. Например, вы выбрали сокращениеил в качестве рассматривае¬ мого второго сокращения. Тогда если вы попробуете набрать слово run, то в ответ получите текст: rUNIX operating system вместо слова run.
Редактирование текста с помощью редакторов vi и ex 217 Определениеключей map Имеется также другой тип сокращения, который реализуется в редакторе vi. Допу¬ скается вводить соответствие между последовательностью команд (последова¬ тельности нажатий клавишей) и определенной клавишей на вашей панели дисплея (что иногда называют «отображением»). Введя такое соответствие, затем вы можете однократно нажать на данную клавишу вместо многократного нажатия на клавиши при наборе текста. Однако вы должны выбрать клавишу, которая не планируется для использования в других целях. В противном случае использование вашей коман¬ ды часто будет непредсказуемым. Наилучший выбор ключей — использовать либо функциональные клавиши, либо одну из следующих клавишей К, V, g, q, v, k,_, =,; (они не используются в редакторе vi). Выполнение временного предписывания ключей Для установки «отображения» во время редактирования вы должны только набрать команду :map в командном режиме vi и нажать клавишу RETURN. «Отображение» будет оставаться в силе до конца процесса редактирования. Сначала вы должны найти клавишу (ключ), которая не имеет какой-либо другой функции, уже предписанной ей. Для этого нажмите любую клавишу в командном pe- жиме vi. Если ваш терминал подаст звуковой сигнал, данная клавиша еще не предпи¬ сана какой-либо функции. Например, попробуйте нажать клавишу со знаком «звез¬ дочка». Возникнет звуковой сигнал, т. e. клавиша доступна для предписывания. Теперь, когда мы имеем доступную клавишу, необходимо предписать (присво¬ ить) ей нужную последовательность команд. Допустим, мы хотим делать отступ все¬ го раздела на следующую позицию табуляции с помощью одного ключа (клавиша *), предполагая, что работа начинается при расположении курсора где-то в пределах этого раздела. Просмотрим команды, которые нам необходимо ввести для выполне¬ ния указанного действия «вручную»: • Сместить курсор в начало раздела (. • Выполнить отступ всего раздела на следующую позицию табуляции >J. При наличии соответствующего ключа(клавиши) и последовательности команд, которые должны быть предписаны (присвоены) ему, мы готовы к созданию нашей команды (с разнесением символов для простоты восприятия): . map* Имя команды { Ключ, к которому приписана последовательность команд Шаг 1: Сместить курсор к началу раздела >} Шаг 2: Осуществить отступ раздела на следующую «ширину сдвига>» Рис. 17.1. Простая команда отображения.
218 Часть III Ниже показано, как действительно набирается команда (без пробелов): :map * {» RETURN Теперь при наличии установленного ключа вы готовы к проверке его действия. Давайте проведем ее по отношению к файлу, с которым мы только что работали. 1. Сохраните текст файлас^от и начните редактирование dpatinadisks. а) Наберите :w для сохранения текста в файлес^от. б) Для вызова файласУ/sfrs с установкой курсора в середине второго раздела набери¬ те :e + ISophistldisks и нажмите клавишу RETURN. б) На дисплее появится следующее изображение: Advanced technology makes it possible. Sophisticated marketing makes it incredible. Superior distribution makes it available. And state-of- the-art manufacturing makes it. 2. Проверьте действие нового ключа. а) Нажмите клавишу со звездочкой *, чтобы вызвать последовательность команд. б) Вы должны увидеть, что курсор переместится к буквеА в cnoseAdvanced, а весь раздел сместится вправо. Выполнение других типов временных предписываний ключей Наша последовательность команд была простой — всего три ключевых слова и две команды. Рассмотрим другой пример (с большим числом компонентов). Выберем в качестве ключа клавишу = и предпишем ей последовательность команд, которая со¬ держит перед текущим предложением следующие два слова: Note this: Ниже показано, как это выполнить «вручную»: • Переместите курсор к началу предложения ( • Выдайте требование на вставку i • Наберите текст, который должен быть вставлен Note this: • Закончите вставку текста ESC Эти действия подобны действиям, выполняемым в предыдущем примере, но в данном случае вводится большее число ключевых слов и возникает дополнительная проблема: как сообщить редактору, что набрали в конце текста управляющий сим¬ вол ESC? (Если нажать ключ (клавишу) ESC, то редактор vl сочтет это как «Конец тек¬ стового ввода».) Редактор vl имеет команду, которая предназначена для решения та¬ кой проблемы (вы увидите это сейчас). Теперь после того как мы располагаем при¬ емлемым ключом = и последовательностью команд, мы готовы создать команду (снова с разнесением символов для ясности, как показано на рис. 17.2). Ниже показа¬ но, как следует на самом деле ее набирать (без пробелов): :map S) (iNote this: Al RETURN Чтобы ввести ESC как текстовый символ, сначала наберите CTRL-V, а затем ESC. Когда вы сделаете это, увидите, что на экране появятся символы л[. Вы должны на-
Редактирование текста с помощью редакторов vi и ex 219 : map ( i Note this: STRL-V ESC Рис. 17.2. Более сложная команда отображения. брать при работе с редактором vi последовательность CTRL-V в любое время, когда необходимо ввести управляющий символ как текстовый символ. Например, чтобы ввести RETURN как символ (в качестве окончания ex команды), нажмите CTRL-V, за¬ тем нажмите клавишу RETURN. На экране вы увидите символы лМ. После присвоения ключу = командной последовательности вы готовы к провер¬ ке действия ключа. 1. Найдите приемлемое место для начала работы. а) Переведите курсор поближе к краю третьего раздела. б) На экране должно появиться следующее изображение:
220 Часть III No matter what you've read, no matter what you've heard, no matter what you've thought, our warranty stands: Every Spinrite diskette wiLl last until it wears out. That's quality, and that's our guarantee. 2. Проверьте ваш новый ключ. а) Для вызова последовательности команд нажмите клавишу =. б) Вы должны увидеть, что курсор переместится к букве N в слове matter и произойдет вставка текста в начало: Note this:_No matter what you've read, no matter what you've heard, no matter what you've thought, our warranty stands: Every Spinrite diskette will last until it wears out. That's quality, and that's our guarantee. Установление постоянного предписывания значений ключам Любые сокращения, которые вы планируете использовать в любое время, могут быть снова подсоединены к вашему файлу .exrc помимо ваших команд set и ab. На¬ пример, чтобы иметь доступными в любое время при работе с vi два предписанных ключа, которые только что были исследованы, необходимо включить их в файл .exrc (без двоеточия): set autoindent set autowrite set wrapmargin=6 ab xen XENIX operating system ab unx UNIX operating system ab btl Bell Telephone Laboratories map * {>} map = (iNote this: A[ Теперь в любой момент времени после начала работы с редактором vi ключи * и = будут иметь предписанные им последовательности рассмотренных команд. Краткое изложение главы 17 В этой главе вы изучили, каким образом можно изменять значение опций редактора, устанавливать сокращения длинных сегментов текста и как присваивать последо¬ вательность команд некоторому ключу (клавише) из состава клавиатуры. УстАновкА опций. Для установки опций в редактор vi во время текущей работы ис¬ пользуйте команду set, как показано в следующих примерах: :set aw :set report=3 :set wm=6
Редактирование текста с помощью редакторов vi и ex 221 ПРИСВОЕНИЕ сокРАЩЕний. Чтобы предписать сокращенное наименование (аббревиа¬ туру) длинному сегменту текста во время работы с редактором, используйте коман¬ ду ab, как показано в следующих примерах: :ab xen XENIX operating system :ab unx UNIX operating system :ab btL BeLL Telephone Laboratories ПРИСВОЕНИЕ комАндных послЕДОВАТЕЛьностЕй ключАМ. Чтобы предписать (присвоить) ключу (клавише), расположенному на клавиатуре, последовательность команд, во время работы по редактированию используйте команду map, как показано в следую¬ щих примерах: :map * *C>T :map = (iNote this: л] ОСУЩЕСТВЛЕНИЕ постоянствА в измЕНЕНиях. Для активизации любой из рассмотренных модификаций в любой момент времени после начала нового процесса редактирова¬ ния поместите эти команды в файл .exrc (без двоеточия), как показано ниже: set autowrite report=3 wrapmargin=6 ab xen XENIX operating system ab unx UNIX operating system ab btl Bell Telephone Laboratories map * {>} map a (iNote this: A[
Часть IV. Обработка и форматирование текста Глава 18. Обработка текста и чисел Теперь, когда вы знаете, как создавать и редактировать текстовые файлы, можно более подробно рассмотреть обработку текста, который уже находится в ранее со¬ зданном файле. В этой главе мы рассмотрим программы системы Юникс, которые позволят вам отыскивать текст в файле, сортировать строки текста и программиро¬ вать вывод текста. В главах 19 и 20 описаны программы, позволяющие форматиро¬ вать текст для вывода на печать. Поисктекста grep Вы уже знакомы со средствами поиска, встроенными в текстовые редакторы ed, vi и ex системы Юникс. Эти же средства поиска встроены также в другую команду си¬ стемы Юникс, называемую grep (globally find and replace regular expressions and print — глобальный поиск и замена регулярных выражений с выводом на печать), с кото¬ рой вы вкратце ознакомились в части I. Приведенное сокращение не очень удачно, однако оно характеризует расширенный поиск в командедгер, который позволяет легко подбирать то, что нужно. Для иллюстрации поиска с использованием команды grep создадим три новых файла, Ha3biBaeMbixdawsoA7. farms,jenkins. farmswparker. farms. Именауказываютна трех поставщиков фруктов (называемых в совокупности Fruit-of-the-Tree) для произ¬ водителей соков, джемов, желе и вяленых фруктов. Каждый файл содержит крат¬ кий список поставляемых фруктов и их цен. Перейдем к подкаталогуГех?_//7е$ и со¬ здадим эти файлы, используя клавишуТАВ для размещения в колонках цен и иден¬ тификаторов: _$Jcat > dawson.farms Bing cherries 0.51 D Concord grapes 0.48 D D'Anjou pears 0.13 D Comice pears 0.51 D $ _ [CTl $|cat > jenkins.farms Concord grapes 0.51 J Bartlett pears 0.12 J NaveL oranges 0.26 J [CTRL-D, чтобы закончить текст] $ [CTRL-D, чтобы закончить текст]
Обработка и форматирование текста 223 _$Jcat > parker.farms Bing cherries 0.48 P Thompson grapes 0.35 P Valencia oranges 0.29 P [CTRL-D, чтобы закончить текст] Простой поиск Имея в Kajanoretext_files три новых файла, содержащие информациюоразличных фруктах, мы можем начать простой поиск с помощью команды grep. В каждом при¬ мере команда grep выводит каждую строку, содержащую искомую цепочку символов1). 1. Является ли Паркер поставщиком винограда? а) Проверьте наличие цепочкиgrapes (виноград) в файперагкег. farms. $ grep grapes parker.farms] Thompson grapes $ 0.35 P б) Ответ: «Да, Паркер поставляет виноград Томпсона». 2. Является ли Даусон поставщиком апельсинов? а) Проверьте наличие цепочки oranges (апельсины) в файлedawson. farms. $ |grep oranges dawson.farms $ б) Ответ: «Нет». (Здесь не выводится никакой информации.) 3. Поставляет ли Дженкинс груши Бартлетта? а) Проверьте наличие цепочки Bartlettpears в файлejenkins. farms. $|grep "Bartlett pears" jenkins.farms Bartlett pears 0.12 J $ б) Ответ: «Да, Дженкинс поставляет груши Бартлетта». Так как мы искали два слова, разделенные пробелами, потребовались кавычки. 4. Кто поставляет вишню Бинга? а) Проверьте наличие цепочки Bing cherries во всех трех файлах: $ grep MBing cherri dawson.farms: Bing cherries parker.farms: Bing cherries $ 0.51 0.48 D P 6) Ответ: «Даусон и Паркер». 1) Далее для краткости мы будем писать просто цепочка. — Прим. ред.
224 Часть IV Мы использовали здесь звездочки *, чтобы сократить имена файлов dawson. farms, jenkins. farms, parker. farms. Этот пример иллюстрирует одно из самых важных свойств команды grep — способность выполнять поиск данной цепочки в несколь¬ ких файлах. Как видно из выводимой на экран информации, командадгер выдает имя каждого файла, который содержит данную цепочку. Использование при поиске вспомогательных средств Как и другие программы обеспечения поиска в системе Юникс, grep допускает спе¬ циальные символы, или метасимволы, которые облегчают подбор образцов. Выра¬ жения, образованные из этих символов, называются регулярными выражениями. Дадим краткое описание этих символов л Начало строки $ Конец строки Любой одиночный символ * Повторить любое число раз [] Любой из указанных в скобках символов \ Выключить специальное значение Ниже приведены несколько примеров регулярных выражений, образованных из этих символов, и цепочки, которые подбираются при использовании в командной строке, содержащей командудгер, указанных регулярных выражений. Регулярные выражения Некоторые из возможных подбираемых цепочек ”лЗ.” 30 31 За Зв 3+3 (в начале строки) ”t..$” too two ten t36 t/T t + 5 (в конце строки) ”[Ff]arm” Farm farm ”\$[0-9]\.[0-9][0-9]” $4.67 $8.32 $1.99 $3.71 ”[abc]x[i\]” a[i] b[i]c[i] ”л$” (Пустая строка) Рассмотрим два простых примера поиска с помощью регулярных выражений. 1. Поставляет ли Даусон груши Д’Анжу? а) Проверьте наличиeD’Anjoupears в dpaunedawson. farms. $|grep MD.Anjou pearsM dawson.farms D*Anjou pears 0.13 D $ _ б) Ответ: «Да, Даусон поставляет груши Д’Анжу». Точка в цепочке для организации поиска была использована потому, что апост¬ роф интерпретировался бы как одиночная кавычка (’), что привело бы к ошибке. (Оба знака на клавиатуре представлены одной клавишей.) 2. Превышают ли чьи-нибудь цены $0.50? а) Проверьте, имеются ли цены выше $0.50 во всех трех файлах: $ grep "[Q-9]4.[5-9][Q-9]" *farms dawson.farms.Bing cherries 0.51 D jenkins.farms.Concord grapes 0.51 J dawson.farms.Comice pears $ _ 0.51 D б) Ответ: «Да, цены на вишню Бинга, груши (у Даусона) и виноград Конкорда (у Джен¬ кинса)».
Обработка и форматирование текста 225 Использование опций для модификации вывода Команда grep имеет много опций, которые вы можете использовать для модифика¬ ции вывода. Ниже приведены наиболее часто используемые опции: Опция Действие -с Показать, сколько раз встретилась цепочка, без вывода текста на экран. -I Показать имя (имена) файла (файлов), в котором (которых) обнаружена цепочка без вывода текста на экран. -n Вывести на экран номера строк вместе с текстом. -у Для алфавитных символов подобрать прописные или строчные буквы, -v Инвертировать поиск (т. e. те строки, в которых не была найдена це¬ почка). В одной команде grep вы можете использовать несколько опций, но не можете связывать их (указывать более одной опции после отдельного знака минус). Рас¬ смотрим несколько примеров использования команды grep с указанными опциями. 1. Сколько разновидностей груш поставляет каждая ферма? а) Проверьте наличие во всех трех файлах последовательностиреаг, но выведите на экран только количество: grep -с pear *farms dawson.farms: 2 jenkins.farms: 1 parker.farms: 0 $ б) Ответ: «Даусон поставляет две разновидности, Дженкинс — одну, Паркер не по¬ ставляет ни одной». 2. Какие фермы поставляют виноград Томпсона? а) Проверьте во всех трех файлах наличие цепочки Thompson grapes, но на экран вы¬ ведите только имена: $[grep -I "Thompson grapes11 *farms parker.farms $ б) Ответ: «Только Паркер». Направление выходного потока в файл Как и в большинстве программ системы Юникс, вы можете переадресовывать вы¬ вод команды grep в некоторый файл вместо того, чтобы выводить результаты толь¬ ко на экран. Используйте для этого символ переадресации >. Рассмотрим два при¬ мера применения опции -v (invert — инвертировать) для удаления строки текста. В них ставится цель получить временную копию файла, затем обработать ее и запи¬ сать обратно в исходный файл (рис. 18.1). 8-771
226 Часть IV Рис. 18.1. Обработка из временного файла. 1. Удалите из файла все пустые строки. а) Сначала создайте временную копию jenkins. farms. $ $ cp jenkins.farms jenkins.temp б) Устраните все пустые строки из временного файла (т. e. перепишите в файл jen¬ kins. farm только непустые строки): $ $ В файл jenkins. farms будет помещена выходная информация команды grep. (Так какисходныйфайл/ел^/^. farms несодержал пустыхстрок,он вдействительности не будет изменен. На практике, однако, это могло бы быть удобной процедурой.) 2. Обновите ваши записи так, чтобы они отражали факт потери Даусоном всех раз¬ новидностей груш. а) Создайте временную копию файла dawson. farms. $ $ cp dawson.farms dawson.temp grep -v "А$" jenkins.temp > jenkins.farms б) Удалите все строки, которые относятся к грушам (т. e. перешлите из временного файла в файл dawson. farms только строки, не относящиеся к грушам). $ $ в) Проверьте результат. grep -v pear dawson.temp > dawson.farms $ |cat dawson.farms Bing cherries Concord grapes $ 0.51 D 0.48 D Использование программ относительного поиска Ниже приведены две программы из семейства grep, которые вас могут заинтересо¬ вать. • fgrep (ускоренная grep ) — сокращенная версия grep, которая допускает любые оп¬ ции, кроме метасимволов, для конструирования регулярных выражений. • egrep (расширенная grep) — версия команды grep, которая позволяет отыскивать и заменять повторяющиеся цепочки. Рассмотрим два небольших примера.
Обработка и форматирование текста 227 1. Поставляет ли Дженкинс груши Бартлетта? а) Проверьте файл jenkins. farms на наличие в нем цепочки Bartlett pears. $ fgrep "Bartlett pearsM jenkins.farms Bartlett pears $ 0.12 б) Ответ: «Да, Дженкинс поставляет груши Бартлетта». Этот пример аналогичен примеру, приведенному выше, если заменить fgrep на grep. При использовании команды fgrep работа выполняется немного быстрее. 2. Кто поставляет виноград Конкорда или виноград Томпсона? а) Проверьте все три файла на наличие цепочки Concord grapes или Thompson grapes. $ egrep "(Concord|Thompson) grapes" *.farms dawson.farms: Concord grapes 0.48 D jenkins.farms: Concord grapes' 0.51 J parker.farms: Thompson grapes 0.35 P $ б) Ответ: «Даусон и Дженкинс поставляют виноград Конкорда, а Паркер — виноград Томпсона». Сортировка файлов В главе 4 мы кратко описали команду sort. Рассмотрим теперь ее более подробно. Команда sort размещает строки файла в алфавитном порядке или по порядку номе¬ ров в зависимости от того, содержат эти строки буквы или цифры. Эта команда может быть ориентирована также на специальные символы текста в пределах каж¬ дой строки файла. Для иллюстрации такой возможности воспользуемся тремя фай- лами farms. Но прежде чем перейти к примерам, добавим к dpahnydawson. farms еще несколько строк теста: $ cat » dawson. farms Navel oranges 0.26 Kadota figs 0.42 Valencia oranges 0.29 Smyrna figs 0.48 D D D D $ [CTRL-D, чтобы закончить текст] Выборка поля (или полей) Если мы с помощью команды cat выведем содержимое файла dawson. farms на экран, увидим три колонки текста: список видов фруктов, список цен и идентифи¬ катор. Команда sort разбивает содержимое файла на четыре колонки [или поля (fields)] текста (которые показаны справа): 8*
228 Часть IV $ cat dawson.farms Field 1 Field 2 Field 3 4 Bing chern'es 0.51 D Bing cherries 0.51 D Concord grapes 0.48 D Concord grapes 0.48 D Navel oranges 0.26 D Navel oranges 0.26 D Kadota figs 0.42 D Kadota figs 0.42 D Valencia oranges 0.29 D Valencia oranges 0.29 D Smyrna figs 0.48 D Smyrna figs 0.48 D $ _ Команда sort рассматривает пробелы и знаки табуляции как разделители полей, если мы только не изменим этот порядок, пометив границы между различными по¬ лями. Итак, для команды sort поле 1 есть разновидность, поле 2 — общий тип, поле 3 — цена и поле4 — идентификатор. Если мы используем простую команду, не опре¬ деляя полей или опций, получаем следующий порядок (алфавитный с полями 1 —4): $|sort dawson.farms Bing cherries 0.51 D Concord grapes 0.48 D Kadota figs 0.42 D Navel oranges 0.26 D Smyrna figs 0.48 0 Valencia oranges 0.29 D $ _ В соответствии с тем, как команда sort сортирует поля, мы можем указать поле (или последовательность полей), по которомухотим произвести сортировку, исполь¬ зуя номера для представления различных полей: • Плюс перед номером означает: начать сортировку после этого поля. • Минус перед номером означает: прекратить сортировку после этого поля. С помощью таких соглашений мы можем применять нотацию +1 - 2 для обозна¬ чения: «Начать сортировку после поля 1 и прекратить сортировку после поля 2» (т. e. сортировать только по полю 2). Проверим эту возможность на примере: $|sort +1 -2 dawson. farms Bing cherries 0.51 D Kadota figs 0.42 D Smyrna figs 0.48 0 Concord grapes 0.48 D Navel oranges 0.26 D Valencia oranges 0.29 0 $ _ В этом примере мы сортировали только по одному полю. Но, как мы увидим ни¬ же, можно сортировать сначала по одному полю, затем по другому и т. д., чтобы со¬ здать определенный порядок в пределах группы объектов. Использование опций для модификации вывода Команда sort имеет ряд опций, которые вы можете включать в командную строку, чтобы модифицировать результаты работы этой команды.
Обработка и форматирование текста 229 Опция Действие -b Игнорировать первые пробелы (пробелы и знаки табуляции) при срав¬ нении полей (опция полезна, когда данное поле для различных объек¬ тов имеет различную длину). -n Сортировать по цифровому полю (допустима для необязательных про¬ белов, нулей или десятичных точек). Эта опция включает автоматиче¬ ски опцию -b. -r Сортировать в обратном порядке (Z-A, z-a, 9-0) (обычно используется при числовой сортировке для помещения наибольшего номера в начало списка). -f Превратить прописные буквы в строчные, например рассматривать при сортировке CASE, Case и case как одно и то же слово. -u Сортировать с исключением (т. e. если две и более строки идентичны, отбросить все строки, кроме одной). -m Слить несколько файлов (файлы уже упорядочены); требуется только их объединить. -tx Сделатьх (любой символ) разделителем полей. Наиболее пригодными на эту роль являются двоеточие (:) и вертикальная черта (I) (вертикаль¬ ная черта должна быть набрана как \1, чтобы ее правильно интерпре¬ тировать). -о file Поместить результат в file. Аналогично действию команды >file. Заметьте, что в данной командной строке sort можно использовать более одной опции, которые могут быть связаны. Проиллюстрируем использование некоторых из этих опций при сортировке фай¬ ла в порядке убывания цены. Для корректного выполнения сортировки надо ис¬ пользовать опции n (numeric — числовая) и r (reverse — обратная). Мы могли бы вве¬ сти следующую командную строку: $ В Smyrna figs 0.48 D Concord grapes 0.48 D [Фрукты Даусона упорядочены Kadota figs 0.42 D по цене в порядке убывания] Valencia oranges 0.28 D Navel oranges 0.26 D $ sort -nr +2 dawson.farms ing cherries 0.51 D Если мы наберем такую командную строку, это будет означать, что n и r применя¬ ются ко всем полям, по которым надо произвести сортировку. Так как мы упорядочи¬ ваем только по одному полю, в этом примере мы не увидим изменений. Но если бы мы упорядочивали по одному полю за другим, как в приведенном ниже примере, мы должны были бы связать n и r с индикатором поля цены. Опции n и r будут тогда от¬ носиться только к одному этому полю: $|sort +2nr +0 -1 dawson i.farms Bing cherries 0.51 D Concord grapes 0.48 D Smyrna figs 0.48 D [Фрукты Даусона, упорядоченные Kadota figs 0.42 D по цене и в алфавитном порядке Valencia oranges 0.28 D при одинаковой цене]
230 Часть !V Navel oranges 0.26 D $ _ Если вы сравните этот пример с предыдущим, то заметите одно незначительное отличиe:Concordgrapes помещается в списке перед Smyrna figs (figs перед grapes). Передача результатов в файл Как и в большинстве программ системы Юникс, вы можете переадресовывать ре¬ зультаты в некоторый файл вместо того, чтобы их выводить только на экран дис¬ плея. Вы можете использовать символ переадресации > или равнозначную опцию -о. Ниже рассмотрены два примера, в которых показано упорядочение составных файлов. 1. Занесите список, состоящий из трех поставщиков и упорядоченный по общему ти¬ пу фруктов, в файл fruit. sort а) Выполните сортировку: $ $ sort +1 -2 *farms > fruit.sort б) Выведите результаты на экран: $|cat fruit.sort Bing cherries 0.48 P Bing cherries 0.51 D Kadota figs 0.42 D Smyrna figs 0.48 D Concord grapes 0.48 D Concord grapes 0.51 J [Фрукты от всех Thompson grapes 0.35 P поставщиков Navel oranges 0.26 D в алфавитном Navel oranges 0.26 J порядке Valencia oranges 0.29 D по общему типу] Valencia oranges 0.29 J Bartlett pears 0.12 J 2. Занесите упорядоченный по цене список из трех поставщиков в файл price, sort. а) Выполните сортировку $ $ б) Выведите результаты на экран. $ cat price.sort Bing cherries 0.51 D Concord grapes 0.51 J Bing cherries 0.48 P sort -о price.sort +2nr +1 *farms
Обработка и форматирование текста 231 Smyrna figs 0.48 D Concord grapes 0.48 D Kadota figs 0.42 D [Фрукты от всех Thompson grapes 0.35 P поставщиков, упоря¬ Valencia oranges 0.29 D доченные по цене] Valencia oranges 0.29 P Navel oranges 0.26 D Navel oranges 0.26 J Bartlett pears 0.12 J $ _ В этом файле фг/'се. sort) указаны все фрукты в порядке убывания цен. Программирование вывода текста Программа awk, которая обрабатывает файлы, содержащие текст или числовые данные, позволяет перераспределять файлы, выполнять арифметические опера¬ ции и выборочно восстанавливать строки, используя программные операторы, ана¬ логичные операторам языка Си. Вы можете использовать эту команду в качестве средства для сопоставления с образцами или использовать как генератор отчетов для файлов, уже хранящихся в системе. (Название awk образовано из начальных букв фамилий ее разработчиков:^ ho, Weinberger и Kernighan. Полная командная строка для awk состоит из четырех частей: имени команды, необязательногооператора-образца, необязательногооператора-действия и имени (имен) файла (файлов). Оператор-образец, который используется для выбора строк из файла, и оператор-действие, который используется, чтобы решить, что делать с выбранными строками, могут быть опущены. Оператор-образец предшествует оператору-действию, который должен быть заключен в скобки, как показано ниже: awk pattern_statement *C action__statement > fiLe(s) И снова мы будем использовать три файла в нашей серии farms. Обращение к полям Как и команда sort, команда awk ориентирована на работу с полями и реализует про¬ стой метод обращения к полям по имени. Чтобы обратиться к полю, наберите только знак доллара перед номером. В соответствии с этим соглашением#? означает поле 1,#2 — поле2,$3 — полеЗ и т. д. Нотация#0 обозначает все поля (всю запись). С по¬ мощью приведенных нотаций мы можем легко переключить поля 1 и 2 (и затем поме¬ стить поле 3 в промежутке табуляций): $ awk Ч print $2 ", " $1 "TAB" $3 }' jenkins.farms grapes, Concord pears, Bartlett oranges, Navel $ таг 0.12 0.26 Оператор-действие обозначает следующее: напечатать в порядке следования поле 2 (общий тип фрукта), запятую и пробел, поле 1 (разновидность фрукта), TAB и затем полеЗ(цену). (Когда вы нажимаете клавишуТАВ, курсор, конечно, перемещает¬
232 Часть IV ся на следующую позицию табуляции на экране, оставляя в командной строке про¬ пуск. Если в операторе-образце и операторе-действии содержатся специальные символы, вы должны заключить эти символы в апострофы. Итак, мы переключили поля 1 и 2. Теперь сравните эту операцию с теми, которые необходимо выполнить в редакторе ed, чтобы получить тот же результат — вы¬ полнить переключение (switch). Выполнение команд из входного файла В приведенном выше примере командная строка была управляемой, но часто она становится слишком длинной для набора на экране. Один из способов устранить эту трудность (и в значительной степени уменьшить повторяющийся набор) — поме¬ стить операторы в отдельный файл, а затем активизировать этот файл в командной строке awk с помощью опции - f. Ниже приводится более легкий способ набора ко¬ мандной строки для переключения полей 1 и 2. 1. Поместите в файл операторы-действия (без апострофов). а) Введите текст с помощью команды cat. * б)$ cat > switch.awk {print $2 ", " $1 " TAB" $3> [Нажмите CTRL-D, чтобы закончить ввод] б) Теперь dpaunswitch. awk содержит команду, и нам нетребуется набирать ееснова в командной строке. 2. Когда выполняете команду awk, укажите этот файл. а) Используйте опцию -f, чтобы переадресовать ввод из файла switch, awk. $ awk -f switch.awk jenkins,farms grapes, Concord 0.51 pears, Bartlett 0.12 oranges, NaveL 0.26 $ б) Эта командная строка эквивалентна командной строке в предыдущем примере. Когда вам нужно повторно запускать одни и те же операторы, их легче разме¬ стить в файле, чем повторно набирать каждый раз в командной строке. В качестве упражнения переключите поля 1 и 2 в других файлах, содержащих описания ферм. Использование арифметических операторов Как уже упоминалось выше, одной из возможностей команды awk является выпо¬ лнение арифметических операций над файлами, которые содержат числовые дан¬ ные. Для проверки этой возможности выполните команду awk над всеми тремя фай¬ лами farms, чтобы определить среднюю цену всех поставляемых фруктов компании Fruit-of-the-Tree. При этом используем три новых объекта: • собственную переменную, называемую sum; • переменную команды awk, называемуюМР (число записей или число строк, считан¬ ных командой awk); • оператор команды awk, называемый END.
Обработка и форматирование текста 233 Мы используем собственную переменную sum, чтобы суммировать цены, когда awk считывает их из записей. После того как мы их просуммировали, используем пе¬ ременную, предусмотренную командой awk и называемую NR, которая указывает, сколько записей команда awk считала и, следовательно, сколько чисел мы сложили. Затем используем оператор-образец, предусмотренный командой awk и называе¬ мый END. Оператор END предписывает команде awk ожидать, пока не будут счита¬ ны все записи, а затем только выполнять следующее действие (вычисление средней цены). 1. Поместите в файл операторы-действия (без апострофов), а) На этот раз вызовите файл av. price. _SJcat > av.price {sum = sum + $3> END {print MAverage price: " у sum / NR> [Нажмите CTRL-D, 4To6bi закончить ввод] б) Это действие переадресует стандартный вывод команды cat в файл, называемый av. price. 2. При выполнении команды awk вызовите этот файл с помощью опции -f. а) Наберите командную строку с опцией -fav. price послeawk. $ awk -f av,price *farms Average price: $ 0.370833 б) Использование опции -f эквивалентно набору операторов в командной строке для получения средней цены. Условная выборка строк До сих пор мы рассматривали операторы-действия, используемые в командной строке awk, и выполняли их в каждой строке в названном файле (файлах). Теперь рассмотрим операторы-образцы — операторы, используемые для выбора строк. Они позволяют решить, какие строки обрабатывать, а какие игнорировать. Объеди¬ нение возможности выборки с различными операторами действия дает вам в руки очень гибкий инструмент. Начнем с нескольких простых примеров. Во-первых, выполним KOMaHflyawk для каждой строки (или записи) каждого из трех файлов farms, выберем те строки, кото¬ рые содержат цены выше 0.50 и выведем их на экран. (Так как этот пример очень прост, мы не будем создавать отдельный файл.) 1. Какие фрукты от всех поставщиков стоят дороже 0.50? а) Перечислите все строки, показывающие цену выше 0.50: $ awk '$3 > 0.50 {print $Q>1 *farms Bing cherries 0.51 D Concord grapes 0.51 J $ _ б) Ответ: «Получим две строки — вишни Бинга (от Даусона) и виноград Конкорда (от Дженкинса).
234 Часть iV Итак, мы имеем список всех фруктов, которые дороже 0.50. Оператор-образец ($3 > 0.50) выбирает эти строки, а оператор-действие ij^rint $0) выводит их на экран. Вы могли сохранить две эти строки в файле, добавив в конце командной строки пе¬ ред ее выполнением оператор переадресации (> exp. fruits). Вы можете также конструировать сложные операторы-образцы, используя сим¬ вол - (искать по образцу), косые линии для обозначения последовательностей из образцов, знаки &&, II, и !. Ниже приводится пример. 2. Какие сорта винограда стоят от 0.31 до 0.35 (включительно)? а) Поместите операторы во входной файл: $lcat > grapes.awk $2- /grapes/ && $3 >= 0.31 && $3 <= 0.35 {print $0> [Нажмите CTRL-D, чтобы закончить ввод б) Требуется перечислить все строки, содержащие сорта винограда по цене от 0.31 до 0.35 (а именно: 0.31, 0.32, 0.34 или 0.35). $ |awk -f grapes.awk *farms Thompson grapes 0.35 P $ в )Ответ: «Виноград Паркера и Томпсона». ПРИМЕЧАНИЕ. В конце гл. 20 рассмотрен пример, который иллюстрирует многие поня¬ тия, введенные в данной главе. Краткое изложение главы 18 В этой главе вы узнали, как искать текст с помощью команды grep, сортировать фай¬ лы с помощью команды sort и программировать вывод текста с помощью команды awk. Поиск текста ПРОВЕДЕНИЕ простого поискА. Для проведения простого поиска, цепочки в файле(или в файлах) наберите grep, пробел, последовательность, еще пробел и имя (имена) файла (файлов) в командной строке и нажмите RETURN. СРЕДСТВА поддЕРжки при поискЕ. Вместо набора реальной цепочки вы можете сфор- мировать регулярное выражение сметасимволами системы Юникс: * $ . * [ ] \ ИспользовАНИЕ опций для модиФикАЦИи выводА. Включая опцию (или комбинацию оп¬ ций) в командную строку, вы можете модифицировать вывод команды grep, чтобы показать, сколько раз была найдена цепочка, показать имя (имена) файла (файлов), в котором (в которых) была найдена цепочка, показать номера строк, подобрать про¬ писные или строчные буквы, инвертировать поиск и т. д. ПЕРЕСЫЛКА выходной инФОРМАЦии в ФАйл. Чтобы переслать выходную информацию в файл, переадресуйте стандартный вывод с помощью символа > и имени файла. ИспользовАНИЕ прогРАмм относитЕльного поискА. Для более быстрого поиска с по¬ мощью только фиксированных буквенных последовательностей используйте ко¬ манду fgrep; для расширенного поиска с обеспечением нахождения повторяющихся строк и чередующихся строк используйте команду egrep вместо команды grep.
Обработка и форматирование текста 235 Сортировка файлов с помощью команды sort ВыворкА поля (или полЕй). Чтобы выполнить сортировку полных строк текста, набе- ритesort, пробел и имя (имена) файла (файлов), которые подлежат сортировке, в командной строке и нажмите RETURN. Чтобы выполнить сортировку конкретного поля (или полей), используйте опции плюс и минус с номерами полей. ИспользовдниЕОПций для модиФИКАЦИИ выводА. Включая опцию (или комбинацию оп¬ ций) в командную строку, вы можете модифицировать действия команды sort, что¬ бы игнорировать первые пробелы, сортировать по числовому полю, производить сортировку в обратном порядке, переводить регистр, производить сортировку с ис¬ ключением, сливать файлы, назначать разделители, переадресовывать вывод ит.д. Программирование вывода текста с использованием команды awk ОПЕРАТОРЫ. Командная строка awk состоит из имени KOMaHflbi (awk), пробела, необя¬ зательного оператора-образца, необязательного оператора-действия, пробела и имени (имен) файла (файлов). СсылкА НА поля. Чтобы сослаться на поля в команде awk, используйте знак доллара и номер, набранные вместе (например, $3, чтобы указать на поле (3)). ВыполнЕНИЕ комАнд входного ФАЙЛА. Подобно многим другим командам системы Юникс, команда awk позволяет поместить операторы в отдельный файл, а затем ак¬ тивизировать их с помощью командной строки. Чтобы активизировать операторы с помощью команды awk, используйте опцию -f и имя файла. ИспользовАНИЕ АРИФМЕтичЕСКих ОПЕРАТОРОВ. Вы можете использовать имена полей с арифметическими операторами и встроенными переменными, чтобы выполнить вычисления. В этой главе мы использовали NR для получения номеров записей и END для прекращения обработки до тех пор, пока не будут считаны все записи. УсловнАЯ выворкА строк. Помещая оператор-образец перед каждым оператором- действием, вы можете выбрать строки для обработки. Такой оператор-образец мо¬ жет определять номера строк или использовать арифметические операции сравне¬ ния. Глава 19. Форматирование с использованием команды nroff. Использование макропакета ms Введение в форматирование Средства форматирования в системе Юникс Как уже говорилось выше, редактирование и форматирование текста в системе Юникс — два различных процесса. Вы вводите текст в файл с помощью одного из редакторов (ed или vi), а затем для его форматирования перед печатью используете другую программу. В системе Юникс ежемесячно появляются новые программы об¬ работки слов, объединяющие функции редактирования и форматирования. Наряду с несколькими вспомогательными программами и препроцессорами существуют
236 Часть IV две основные форматирующие программы, которые были разработаны на основе первых программ «подготовки к печати» системы MIT. Они называются nroff (эн- роф) (новая программа подготовки к печати) и troff (ти-роф) (программа, ориентиро¬ ванная на работу с полиграфическим оборудованием). Эти две программы имеют много общего. Основное различие состоит в том, что программа nroff предназначена для обычных печатающих устройств, тогда KaKtroff обслуживает полиграфическое оборудование. Так как nporpaMMatroff значительно сложнее, мы ограничимся рас¬ смотрением программы nroff. Чтобы помочь начинающим пользователям и обеспечить стандартные наборы форматов, проектировщики создали стандартные средства, называемые макропа¬ кетами. («Макро» здесь означает более сложные команды, полученные из менее сложных, примитивных «микро» команд). Наиболее известными пакетами являются ms, me и mm. Кроме того, существует несколько препроцессоров, которые обрабатывают специальные типы текстов: tbl для таблиц, eqn и neqn для математических выраже¬ ний и др. Наконец, существуют утилиты: checked для проверки работы препроцессо¬ ров eqn и neqn, а Ta^ederoff для удаления всех форматирующих команд (nroff, troff, tbl, eqn или neqn) из файла и др. В этой главе мы изучим пакет ms. Пример форматирования Макропакет ms предоставляет широкий выбор заранее определенных средств фор¬ матирования текста, которые вы можете активизировать и дезактивизировать, по¬ мещая встроенные команды (или запросы) в свой файл. Для иллюстрации восполь¬ зуемся текстом из предыдущей главы. 1. Подготовьте входной текстовый файл для форматирования. а) Перейдите в nopKajanortext_files и начните сеанс редактирования файла, назы- ваемогор//. deal: Dear Мг. Madi son: The purpose of this letter is to confirm Monday's agreement. Tupelo gets "Porkchop" Peterson, you get "Earthquake" Emerson, and we get "Rotunda" Robinson. Here are the players' names, heights, weights, and new teams: Emerson, Ezekiel R. 6'5" 273 Rochester Robinson, Charles F. 6'3" 287 Des Moines Peterson, Paul N. 5'9" 178 Tupelo You will be getting one of the finest players in the People's Football League Your Friend and Mine, Chuck 6) Вставьте семь встроенных команд, показанных ниже (без описаний, заключенных в скобки). (В том случае, если вы пропустили часть II книги и еще не набирали этот текст, наберите его теперь, как показано ниже.) .pl 30 . LP [Раздел блока] Dear Mr. Madison: .PP [Стандартный раздел] The purpose of this letter is to confirm Monday's agreement.
Обработка и форматирование текста 237 Tupelo gets "Porkchop" Peterson, you get and we get "Rotunda" Robinson. Неге are the players' names, heights, .DS Emerson, Ezekiel R. бЗ" 273 Robinson, Charles F. 63" 287 Peterson, Paul N. 5'9" 178 .DE .PP You wiLl be getting one of the finest .DS C Your Friend and Mine, Chuck .DE Earthquake" Emerson, weights, and new teams: [Начало вывода на экран] Rochester Des Moines Tupelo [Конец вывода на экран] [Стандартный раздел] players in the People's Football League. [Центрированный вывод на экран] [Конец вывода на экран] в) Сохраните текст и вернитесь к приглашению интерпретатора shell. 2. Форматируйте текст на экране с помощью команды nroff. а) Наберите ксманду nroff, которая включает опцию -ms1). $ nroff -ms pfl.deal Dear Mr. Madison: The purpose of this letter is to confirm Monday's agree¬ ment. Tupelo gets "Porkchop" Peterson, you get "Earthquake" Emerson, and we get "Rotunda" Robinson. Here are the players' names, heights, weights, and new teams: Emerson, EzekieL R. 6'5" 273 Rochester Robinson, Charles F. 63" 287 Des Moines Peterson, Paul N. 5'9" 178 Tupelo You will be getting one of the finest players in the People's Football League. Your Friend and Mine, Chuck September 2, 1985 6) Слова каждого раздела объединены вместе, правое поле установлено (выровне¬ но), в табличном материале сделан отступ и заключение центрировано. 1) В данном примере допущена ошибка: первый и второй разделы должны начинаться от¬ ступом на 5 позиций. — Прим. ред.
238 Часть IV Использование макропакета ms При форматировании этого текста, которое можно рассматривать как краткое вве¬ дение в nroff и ms, мы воспользовались одной из команд программы nroff: .pl 30 Установить размер страницы 30 строк (без этого запроса nroff текст ис¬ чез бы с экрана прежде, чем вы успели бы рассмотреть его); и пятью командами макропакета ms: .LP Раздел без отступа выровнен по левому краю .PP Стандартный раздел (отступ в первой строке) .DS Начало иллюстрации (текст иллюстрации целиком сдвинут, т. e. сделан отступ, в других отношениях текст оставлен без изменений) .DE Конец иллюстрации .DS С Начало вывода на экран (центрированное) Каждая встроенная команда ms (или запрос) состоит из точки в колонке 1, за кото¬ рой следует одна или две прописные буквы (этим отличаются данные команды от команд nroff, которые записаны строчными буквами). Например, команда ms для обозначения стандартного раздела есть .PP. Помещая (или встраивая) эту команду непосредственно перед строками текста, вы можете их форматировать и образо¬ вать раздел. Некоторые встроенные команды также требуют дополнительной информации. Например, начало команды вывода иллюстрации .DS может быть использовано са¬ мостоятельно с одним или более чем одним добавочным символом (в приведенном выше примере для центрирования мы добавляли символ С, чтобы получить команду .DSC). Ниже мы опишем эти и другие форматирующие команды более подробно. Для простоты мы будем пользоваться «короткими» примерами, в которых показан вход¬ ной текст слева и печатаемый результат — справа. Формирование разделов Стандартный раздел Чтобы сместить первую строку на пять пробелов и выровнять все строки по правому краю, поставьте перед первой строкой команду .PP. Она используется в начале тек¬ стового файла при его инициализации: Input Output . PP sssssssssssssssssssssssssssss sssssssssssssssssss ssssssssssss ssssssssssssssssssssssss sssssssssssssssssssssss ssssssssssssssssssssssss ssssssssssssssss. sssssssssssss. Раздел без отступа Чтобы сформировать раздел без отступа со строками, выровненными слева и спра¬ ва (кроме последней), поставьте перед первой строкой команду .LP: . LP bbbbbbbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbb bbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbb. bbbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbbb.
Обработка и форматирование текста 239 Раздел цитат Чтобы выделить цитату(т. e. образовать раздел, который выделен пятью пробелами слева и справа, причем все строки выровнены по левому краю (кроме последней) и по правому краю, поместите перед первой строкой команду .QP: .PP ssssss s s s s s s s s s s s s s s s s s s s s s s ssssssssssss ssssssssssssssss. .QP qqqqqqqqqqqqqqqqqqqqq qqqqqqqqqqq qqqqqqqqqqqqqqq. sssssssssssssssssss s s s s s s s s s s s s s s s s s s s s s s s s sssssssssssss. qqqqqqqqqqqqqq qqqqqqqqqqqqqq qqqqqqqqqqq. Смещенный раздел Чтобы сформировать раздел, который выделяется пятью пробелами слева, а все строки выровнены по левому (кроме последней строки) и правому краям, поставьте перед первой строкой команду .IP . LP bbbbbbbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbb bbbbbbbbbbbbbbbb. .IP i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i . bbbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbbb. i i i i i i i i i i i i i i ^ i i i i i i i i i i i i i i i i i i i i i i i i i . Чтобы поместить короткую строку (например, «число», «буква», «метка») перед первой строкой раздела, оставьте один пробел после команды .IP и наберите необ¬ ходимую строку: . LP bbbbbbbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbb bbbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbb. bbbbbbbbbbbbb. .IP (1) 1111 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 i i i i i i i i i i i i i i i i i i i i i i i i i i . .IP (2) i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i . i i i i i i i i i i i . (1) 1 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i т . (2) i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i . .PP .LP .QP .IP Чтобы поместить более длинную строку перед смещенным разделом, оставьте один пробел после команды ./P, а затем наберите строку, за которой следует число (которое должно быть по крайней мере на единицу больше длины строки). Это число показывает, на сколько колонок следует сдвинуть (т. e. отступить) раздел. Если стро¬ ка содержит пробелы, заключите ее в кавычки:
240 Часть IV . L P bbbbbbbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbb bbbbbbbbbbbbbbbb. . IP "Part 1 " 8 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i . . IP "Part 2" i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i . bbbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbbb. P a r t 1 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i . P a r t 2 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i . Когда задано число, указывающее отступ, это указание остается в силе до тех пор, пока не будет изменено. Сдвиг разделов Чтобы сдвинуть раздел на пять позиций вправо, используйте команду .RS; чтобы сдвинуть следующий раздел назад на пять позиций1), используйте команду .RE. Ко¬ манда .RS подобна команде .IP, за исключением того, что .RS используется совмест¬ но с .RE для сдвига разделов вправо и влево (как показано на примере выведенной на экран информации): . PP s s s s s s s s s s s s s s s s s s s s s s s ssss s s s s s s s s s s s s s s s s s s s s s s s s s s s s s . .RS г r г r r r r r r r r r r r г r r r r r r r r r Г г г г г г .RE 1 L L 1 1 1 L L L L 1 1 L 1 1 1 L L L L L L 1 L 1 L 1 L L 1 L 1 1 1 L L 1 1 1 1 1 1 1 1 1 L 1 . .RE 1 1 1 L 1 1 1 1 1 L L L 1 1 L L L L L 1 1 L 1 1 L 1 1 1 1 . s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s . г r r г r r r г r г L L 1 L 1 1 L L L 1 L L L 1 1 1 1 L 1 1 1 1 1 1 L 1 1 1 1 L L t L L 1 1 L 1 L 1 t 1 L 1 . I L t 1 t 1 1 1 1 1 1 1 1 1 1 L L 1 L 1 1 L 1 1 1 L 1 L 1 L 1 1 1 L L L L L 1 L L 1 . Запрос .RS также позволяет вставлять строку перед первой строкой раздела. 1) Сдвиг текста текущего раздела осуществляется относительно текущего местоположе¬ ния предыдущего раздела. — Прим. ред.
Обработка и форматирование текста 241 Вывод иллюстрации Стандартный вывод иллюстрации Чтобы вывести иллюстрацию в виде текста (т. e. чтобы сделать отступ и выровнять строки по левому краю), поставьте перед первой строкой команду .DS, а вслед за по¬ следней строкой — команду .DE. Вы можете использовать команды .DS и .DE, чтобы выводить на экран стихи, где строки должны быть выровнены слева. При стандарт¬ ном выводе иллюстрации текст снабжается отступом на пять позиций: .PP s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s . s s s s s s s s s s s s s . .DS dddddddddddddddddd , dddddddddddddddd . dddddddddddddddddd, dddddddddddddd. .DE dddddddddddddddddd, dddddddddddddddd. dddddddddddddddddd, dddddddddddddd. Сблокированная иллюстрация Имеется еще одна возможность — центрировать текст и выровнять его по левому краю. Чтобы вывести текст с отступом и так, чтобы иллюстрация располагалась в центре экрана, добавьте к команде .DS опцию В: . PP s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s . s s s s s s s s s s s s s . .DS В dddddddddddddddddd, dddddddddddddddddd, dddddddddddddddd. dddddddddddddddd . dddddddddddddddddd, dddddddddddddddddd, dddddddddddddd. dddddddddddddd . .DE Центрированная иллюстрация Иногда желательно показать группу строк, каждая из которых центрирована по го¬ ризонтали (как, например, в заголовке или стихотворной строфе). Чтобы центриро¬ вать при выводе каждую отдельную строку текста, добавьте к команде .DS опциюС: . PP s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s . s s s s s s s s s s s s s . .DS С dddddddddddddddddddd, dddddddddddddddddddd , dddddddddddddddd. dddddddddddddddd. dddddddddddddddddd, ddaddddddddddddddd, dddddddddddd. dddddddddddd.
242 Часть IV Сохранение непрерывности следования строк текста Стандартное сохранение Обычно мы не придаем значения смене страниц в тексте. Однако есть строки текс¬ та, которые желательно хранить вместе на одной странице, и вы хотите получить га¬ рантию, что они не будут разъединены при смене страницы. При работе с пакетом ms вы должны заключить текст между двумя запросами «сохранить» (.KS и .KE), и тогда команда nroff сохранит их вместе. В следующих двух примерах раздел состоит из шести строк, которые надо отпечатать, но имеются только три доступные для это¬ го строки в конце страницы 5. (Штриховая строка обозначает смену страниц, а ци¬ фры 5 и 6 являются номерами страниц.) Без «сохранения» непрерывного следова¬ ния текста раздела на строках: . pp s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s sssssssssssssssssss. sssssssssssss. ssssssss 5 s s s s s s s s s s s s s s s s sssssssssssssssssssss ssssssssssssssssssssssss 6 ssssssssssss . sssssssssssssssssss . С «сохранением» непрерывного следования текста раздела на странице: bbbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbb. 5 bbbbbbbbbbbbbbbbbbbbbb. . KS . pp s s s s s s s s s s s s s s s s ssss s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s . s s s s s s s s s s s s s s s s sssssssssssssssssssss s s s s s s s s s s s s . . KE sssssssssssssssssss 6 s s s s s s s s s s s s s s s s s s s s s s s s sssssssssssss. ssssssss s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s . Плавающее сохранение Стандартное сохранение непрерывного следования текста раздела на странице играет большую роль, но некоторые пользователи не хотят, чтобы в конце страницы оставались пустые места. Одним из способов устранения этого недостатка являет¬ ся «плавающее сохранение». «Сохраняемый» текст по-прежнему перемещается не¬ тронутым на следующую страницу, как и при стандартном «сохранении». Однако команда nroff будет использовать текст, который следует за «сохраняемыми» стро¬ ками, чтобы заполнить пустые строки в конце предыдущей страницы. Например: .PP s s s s s ssss s s s s s ssss s s s s s s s s s s s s s s s s s s s s s s s s s s ssss s s s s s s s s s s s s s s s s s s s s s s s sss s s s s s. ssssssss . .KF bbbbbbbbbbbbbbbbbbbbbbbb .QP bbbbbbbbbbbbbbbbbbbbbbbb 7
Обработка и форматирование текста 243 qqqqqqqqqqqqq qqqqqqqqqqq qqqqqqqqqqqqqqqqqqqqq . .KE . LP bbbbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbbbbbb. 8 qqqqqqqqqqqqqq qqqqqqqqqqqqqq qqqqqqqqqqq. bbbbbbbbbbbbbbbbbbbbbbbb bbbbbbbbbbbb. Так как на странице 7 нет места для трех строк цитаты, цитата переносится на страницу 8, причем на странице 7 остаются две пустые строки. Две строки раздела отступа1) перемещаются перед цитатой в конец страницы 7. Оставшиеся две строки раздела без отступа остаются за цитатой на странице 8. Заметьте, что вы никогда не должны «сохранять» иллюстрацию, так как он «сохраняется» автоматически. Использование сносок Установка сноски Если вы набираете документ со сносками, средства nroff и ms существенно упроща¬ ют эту работу. Вы должны только набрать сноску справа от символа ссылки на нее. Сноска должна быть окружена командами сноски .FS и .FE. Средства пакета ms вы¬ делят место для примечания в конце страницы и напечатают разделитель между сноской и последней строкой основного текста в конце страницы. Например: .QP "Гт not а crook."* .FS ★ Report, 1974 .FE oPP In an interview this afternoon, three members of the House Judiciary Committe told . . . . "I'm not a crook."* In an interview this afternoon, three members of the House Judiciary Committee told . . . . ★ Report, 1974 Использование нумерованных сносок Если вы планируете ссылаться на сноски по номерам, можете использовать эти но¬ мера на месте звездочек. Если выше печатающее устройство не допускает подстроч¬ ную или надстрочную печать, вы можете применять номера, заключенные в скобки: [1], [2], [3] и т. д. Если ваше печатающее устройство допускает подстрочную или над¬ строчную печать, вы можете получать номера, отпечатанные как пометки, окружив их командами «вверх» (\и) и «вниз» (\d). Ниже приводится пример ссылки на над¬ пись: .PP sssssssssssssss sssssss.C7] . F S . IP " 7." s s s s s s s s s s s s s s s s s s s SSS . [7] ssssssssssss s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s . [ 8 ] 1) Раздел, состоящий из букв «в». — Прим. ред.
244 Часть IV fffffffffffffffffff .FE sssssssssssssssssss s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s sssssssssss sssssssssss. sssssssssssss.[8] .FS .IP " 8." 7. fffffffffff ggggggggggggggggggg fffffff. .FE 8. ggggggggggg •рр ggggggg. s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s . Этот пример также иллюстрирует использование смещенного раздела в качест¬ ве сноски с тем, чтобы выделить номер из примечания. Использование заголовков Ниже вы узнаете, как использовать ненумерованные и нумерованные заголовки раз¬ дела. Ненумерованные заголовки Чтобы получить обыкновенный ненумерованный заголовок длиной менее одной строки, поставьте перед ним команду .SH (заголовок раздела), а за ним — команду .PP или .LP, чтобы отметить начало следующего текста. Заголовок будет подчерк¬ нут, выровнен по левому краю и отделен от обычного текста сверху и снизу пустыми строками. Например: .pp s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s ssssssssss s sssss sssss s sssssssssssssssssss . sssssssssssss . .SH С о n с 1 u s i о n С о n с 1 и s i о n .pp s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s sss s ssssss ss ss sss ssss s ssssssssssssss. ssss. Если вы хотите оставить более одной пустой строки над заголовком, вставьте команды .LP или .PP между концом предшествующего раздела и командой .SH: . РР s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s ss s s s s s s s s s s s s s s s s s s s s ssss sss s s s s s s s s s s s s s s s s s s s sssssssssssssssssss . sssssssssssss . . рр . рр .SH
Обработка и форматирование текста 245 Conclusion С о n с 1u s i о n .PP s s s s s s s s s s s s s s s s s s s s s s s sss s s s s s s s s s s s s ssssssssssss ssssssssssssssssssssss ssssssssssssss. ssss. Нумерованные заголовки Нумерованные заголовки образуют также, как и ненумерованные, за исключением того, что каждому заголовку предшествует номер раздела. При использовании ко¬ манды .NH (нумерованный заголовок) оставьте пробел после .NH и наберите число, указывающее уровень подчиненности (до пяти уровней). В заголовке первого уровня номер можно опустить. Тогда средство ms приписывает следующий допустимый но¬ мер на любом данном уровне, но ms не может автоматически сгенерировать оглав¬ ление из ваших заголовков, тогда как некоторые программы могут это выполнить: .NH The Main Thing .NH 2 Where to Start .NH 2 When to Start .NH 3 The Best Time .NH 3 The Worst Time 1. The Main Thing 1.1. Where to Start 1.2. When to Start 1.2.1. The Best Time 1.2.2. The Worst Time .NH Other Things to Consider 2^ Other Things to Consider . LP Выделение текста и отмена выделения Выделение текста Если вы хотите выделить текст в разделе путем подчеркивания его, то вставьте ко¬ манду .1. Для этого поместите .1 в отдельной строке, за которой следует выделяемый текст. Хотя такое выделение подразумевает разбивку раздела, средства ms будут за¬ полнять раздел без прерывания: Now we are coming to the Now we are coming .1 to the most important most important item of the agenda. .R item of the agenda. Другой способ выделить текст — использовать .1 в сочетании с командой .R, при¬ чем .1 набирается в предшествующей тексту строке, а .R — в строке, следующей за выделяемым текстом. Здесь опять средства ms будут восстанавливать автоматиче¬ ски непрерывность текста раздела: .PP Now we are coming to the Now we are coming .1 most important to the most important item of the agenda. item of the agenda.
246 Часть IV I Отмена выделения текста Лучшим способом отменить выделение текста в вашем документе является выход из него. Никакой команды форматирования не требуется. Разметка страниц Стандартная разметка Обычно nroff размечает страницу, как показано на рис. 19.1. При стандартной разметке страницы по макрокоманде ms печать осуществляется в области размером 12x22,5 см на каждой из страниц размером 17x27,5 см. Номер страницы располагает¬ ся в центре вверху страницы и окружен дефисами. Текущая дата помещается в цент¬ ре внизу страницы. В области размером 12x22,5 см помещается текст, содержащий 54 строки, причем в каждой строке размещается 65 знаков. Изменение даты Если вы хотите полностью удалить дату, поместите команду .ND (нет даты) рядом с началом текстового файла. Если вы хотите использовать некоторую дату, отличную от текущей, введите команду .DA, набрав желательную дату после .DA, как показано ниже: .DA September 15, 1981 Верхнее поле LH CH RH Левое поле 55 строк текста (65 колонок в каждой) LF CF RF Правое поле Нижнее поле Рис. 19.1. Стандартный формат страницы при использовании макропа¬ кета ms.
Обработка и форматирование текста 247 Изменение заголовка Заголовок (особая строка над текстом вверху страницы) обычно остается в докумен¬ те фиксированным. Вы можете поместить текст заголовка на всех страницах в лю¬ бую из трех позиций этой строки: в левый край, по центру, в правый край. Для каж¬ дой из этих позиций команда nroff имеет соответствующую строковую переменную: LH (левый заголовок), CH (центрированный заголовок) и RH (правый заголовок). По умолчанию CH содержит номер страницы, а две другие переменные ничего не со¬ держат. Чтобы изменить любую из этих переменных, используйте команду nroff.ds (опре¬ делить строку). Например, вы могли бы использовать следующие команды, чтобы поместить в заголовок текст Draft Сору слева и Revision 3 справа (оставляя номер страницы в середине): .PP .ds LH Draft Сору .ds RH Revision 3 Изменение футера Футер — особая строка под текстом внизу страницы. Как и в случае заголовка, вы можете поместить свой собственный текст в любую из трех позиций этой строки: в левый край (LF), по центру (MF), в правый край (RF). По умолчанию переменная CF со¬ держит только дату. Чтобы изменить любую из этих переменных и составить вашу собственную стро¬ ку, используйте команду nroff. ds (определить строку). Например, вы могли бы ис¬ пользовать следующие команды, чтобы разместить Confidential в конце каждой страницы слева и Internal Use Only справа (от даты, находящейся в середине): .PP .ds LF Confidential .ds RF Internal Use Only Перемещение номера страницы Хотя команда nroff помещает номер страницы в середине заголовка по умолчанию, вы вправе поместить его в другое место и в другом формате. Используйте символ % (номер страницы), как и в приведенном ниже примере, в котором номер страницы помещается с правой стороны футера и ему предшествует слово Page: .PP .ds RF Page % Краткое изложение главы 19 В этой главе вы узнали, как форматировать текст с помощью команды nroff. Введение в форматирование СРЕДСТВА ФОРМАТИРОВАНИЯ в систЕМЕ юникс. Основные форматирующие программы в системе Юникс — nroff для печати и troff для работы с наборным оборудованием. Они сопровождаются макропакетами (которые обеспечивают стандартные, зара¬
248 Часть IV нее определенные запросы на форматирование) и препроцессорами (которые управляют специализированными типами текста). Макропакеты, такие, как ms, me и mm, активизируются с помощью опций в ко¬ мандной строкеnroff. Препроцессоры, такие, как tbl (для таблиц), eqn и neqn (для ма¬ тематических выражений), активизируются отдельными командами, которые посы¬ лают текст в nroff через конвейер. МдкропАКЕТ ms. Чтобы использовать макропакет ms, поместите встроенные коман¬ ды в текст, который нужно форматировать, затем выполните команду nroff, которая включает опцию - ms и имя форматируемого файла. Чтобы отпечатать результаты, пошлите текст через конвейер на печать с помощью команды lpr. ФОРМАТИРОВАНИЕ РАЗДЕЛОВ. Встроенные запросы ms для формирования разделов представлены ниже: Стандартный раздел .PP Раздел без отступа .LP Раздел цитат .QP Смещенный раздел .IP Сдвигвправо .RS Сдвиг влево .RE Вывод ТЕКСТА НА экрАн. Ниже приведены встроенные команды ms для вывода текста на экран. Тексту должна предшествовать одна из перечисленных ниже команд, а за текстом должна находиться команда завершения (.DE): Стандартный вывод .DS (.DE) Сблокированный вывод .DS В (.DE) Центрированный вывод .DS С (.DE) СОХРАНЕНИЕ НЕПРЕРЫВНОГО слЕДОВАния строк ТЕКСТА. Ниже приведены встроенные команды ms для сохранения непрерывного следования строк текста на странице. Тексту, который нужно «сохранить», должна предшествовать одна из следующих команд, а за ним должна следовать команда завершения (.KE): Стандартное сохранение .KS (.KE) Плавающее сохранение .KF (.KE) ИспользовАНИЕ сносок. Встроенные команды ms для печати сносок в конце страни¬ цы приведены ниже. Тексту сноски должна предшествовать команда .FS, за ним должна следовать команда .FE: Установка сноски .FS (.FE) Использование подчеркивания \u (\d) ИспользовАНИЕЗАГОЛОВКОВ. Встроенные команды ms для печати заголовков приведе¬ ны ниже. (Не требуется использовать специальные команды — терминаторы): Ненумерованные заголовки .SH Нумерованные заголовки .NH ВыдЕЛЕНИЕ ТЕКСТА и отмЕНА выдЕЛЕния. Запрос ms .1 производит подчеркивание для выделения; символ .R может быть использован для прекращения подчеркивания: Выделение .1 (.R) Отмена выделения Не требуется использования каких-либо ко¬ манд
Обработка и форматирование текста 249 Разметка страниц СТАНДАРТНАЯ РАЗМЕТКА. Стандартная разметка страницы для ms есть область печати размером 12x22,5 см на странице размером -17x27,5 см, причем в центре вверху страницы помещается ее номер, а в середине строки в конце страницы помещается дата. Используя следующие команды, вы можете сделать некоторые изменения в разметке: Удалить дату .ND Изменить дату .DA r .ds LH Изменить заголовок .ds CH ^ .ds RH ^ .ds LF Изменить футер .ds CF Lds RF Переместить номер страницы % Глава 20. Некоторые способы форматирования текста с использованием nroff В главе 19 вы узнали, как использовать программу nroff для форматирования текста, причем особое внимание было обращено на макропроцессор ms. В этой главе мы рассмотрим различные способы инициации форматирования, несколько основных запросов nroff, методы создания таблиц и печати в две колонки и некоторые другие программы, относящиеся к форматированию. Инициация форматирования Выполнение командной строки nroff В главе 19 для быстрого введения в форматирование мы использовали только про¬ стейшую форму команды nroff, которая посылает выходные данные на экран. Эта команда имеет вид: $ nroff text Если используется макропакет ms, эта команда имеет следующий вид: $ nroff -ms text $ _ Чтобы отформатированный текст отпечатать на построчном печатающем уст¬ ройстве, следует направить выходную информацию от nroff через конвейер с по¬ мощью команды lpr: $ $ Если вы предпочитаете, чтобы эта работа была выполнена в фоновом режиме, добавьте к концу командной строки символ обработки в фоновом режиме &. Ядро nroff text | Lpr
250 Часть IV системы Юникс тогда припишет заданию идентификатор процесса, как показано ниже: $ | nroff text | lpr & 1763 $ Если вы разбиваете очень большой файл на меньшие файлы с использованием команды split, можете получить выигрыш при использовании средств поиска по об¬ разцам в системе Юникс и последовательно обрабатывать меньшие файлы с по¬ мощью nroff: $ $ nroff jumbo.[a-d] [ lpr Определение макропакета Как уже говорилось выше, вы можете включить макропакет с помощью опции - ms в командной строке nroff: $ $ nroff -ms text Макропакет ms — один из многих макропакетов, хранящихся в каталоге, на¬ зываемом lusrllib/tmac. Полное имя файла, который содержит ms, — lusrllibltmacltmac.s. Ниже приводится перечень некоторых имен макропакетов и полных имен файлов, в которых содержатся эти макропакеты: Имя Опция ms -ms mm -mm me -me Полное имя файла /usr/Ub/tmac/tmac.s /usr/lib/tmac/tmac.m /usr/lib/tmac/tmac.e Запрос на форматирование с заданного номера страницы Если вы напечатали с помощью nroff первые Юстрок документа, у вас может возник¬ нуть желание продолжить печать на следующей странице. Чтобы начать формати¬ рование на требуемой странице документа (например, на странице 11), вы можете включить в командную CTpoKynroff опцию -n11: $ $ nroff -n11 text l Lpr [Начать печатать на странице 11] Запрос специальных страниц Чтобы произвести форматирование только одной страницы документа (например, страницы 7), вы можете включить опцию -o7 в командную строку nroff: nroff -o7 text | Lpr [Напечатать только страницу 7]
Обработка и форматирование текста 251 Вы можете таким образом управлять одновременно более чем одной страницей, используя запятые для перечисления номеров отдельных страниц или дефисы для указания диапазонов номеров страниц: [Напечатать страницы 3, 9 и 18] nroff -o3,9,18 text | lpr $ |nroff -o11-13,22 text | lpr|[Напечатать страницы 11—13 и 22] $ nroff -o-5 text j Lpr $ $ nroff -o14- text |Пэг $ [Напечатать страницы 1—5] [Напечатать страницы от 14 до конца документа] Установка промежутков между страницами Если вы печатаете на стандартной или другой бумаге, которую нужно заправлять в печатающее устройство по одному листу, можете останавливать печать после каж¬ дой страницы с помощью опции -s (stop) в командной строке nroff: [Останавливать печать после каждой стр.] $ ^roff -s text 1 CpF Если необходимо, вы можете также набирать после - s номер, чтобы остановить выполнение команды nroff после данного числа страниц. Например, чтобы остано¬ вить nroff после третьей страницы, вы можете использовать следующую запись: $ nroff -s3 $ text 1 lpr [Останавливать печать каждой 3-|й стр.] Выбор печатающего устройства Обычное печатающее устройство выполняет простые задачи печати. Чтобы выпо¬ лнять такие работы, как подчеркивание, надписи, обратное движение бумаги и т. д., требуется специальное печатающее устройство. Если в вашей системе имеется та¬ кое устройство, вы можете сообщить об этом программе nroff с помощью опции -T(type). Если вы этого не сделаете, специальные функции печати не будут выпо¬ лняться. Например, если ваша система имеет рулонное печатающее устройство NEC 5520, можете использовать следующие записи: [Печатать на рулонном печата¬ ющем устройстве] $ 1 nroff -T5520 text | lpr| $ nroff text | spr [Печатать на рулонном печата¬ ющем устройстве] Так как подобное печатающее устройство можетуправлятьраспределением про¬ странства, можно было бы включить опцию -e (even) (чтобы установить равные
252 Часть IV промежутки между словами в строке), называемую пропорциональным распределе¬ нием пространства: $|nroff -e -T5520 text $ lpr [Печатать с равными промежут¬ ками на рулонном печатающем устройстве] или nroff -e text | spr [Печатать с равными промежут¬ ками на рулонном печатающем устройстве] Ниже приводится неполный список печатающих устройств, которые могут быть ука¬ заны в опции -T: Имя- T Полноеимя 37 Модель 37 фирмы Teletype (по умолчанию) lp Обычное печатающее устройство tn 300 Термопечатающее устройство GE 300 (или любое терминальное устройство, исключающее возможность надстрочной или под¬ строчной печати) 300 DASI 300 300 S DASI 300S DASI 450 5510 Рулонное печатающее устройство NEC 5510 5520 Рулонное печатающее устройство NEC 5520 Некоторые основные запросы nroff В этом разделе кратко рассмотрены некоторые базовые встроенные в nroff команды (или запросы) — базовые элементарные инструкции, используемые при pa6oTenroff. Каждый макропакет, спроектированный для управления nroff, сконструирован из этих команд. Установка размера страницы Запрос .pl (page length — размер страницы) устанавливает размер каждой страницы, которая печатается построчно (высота каждой строки составляет - 0,4 см). По умол¬ чанию страница содержит66 строк(- 28 см)(рис. 20.1). Если вы печатаете на конвер¬ тах или на чем-нибудь другом с размером - 21,5x28 см, вы должны уменьшить значе¬ ние .pl. Например, вы печатаете на конвертах шириной - 10 см. Тогда вы должны ис¬ пользовать следующий запрос: .pl 24 [Установить размер страницы 24строки] Вы можете использовать абсолютное значение, как в приведенном выше приме¬ ре, или относительное значение, как показано ниже: .pl -12 [Уменьшить размер страницы на 12строк] В этом случае под новым значением .pl понимается относительное (по отноше¬ нию к предыдущему) значение. Чтобы восстановить принятое по умолчанию значе¬ ние (66), укажите .pl без номера: .pi [Восстановить размер страницы 66 строк]
Обработка и форматирование текста 253 Рис. 20.1. Стандартный формат страницы при использовании nroff. Установка размера строки Запрос .ll (line length — размер строки) устанавливает размер каждой строки в колон¬ ках символов (где ширина каждого символа составляет -2,5 мм). По умолчанию строка содержит 65 символов (или ее длина равна - 16,5 см) (рис. 20.1). (В макроко¬ манде ms по умолчанию 60 символов.) Если вы печатаете на бумаге размером, отлич¬ ном от 21,5x28 см, вы должны увеличить или уменьшить значение .11. Предположим, вы печатаете на бумаге, ширина которой -38 см. Тогда вы должны использовать следующую запись: . IL 132 [Установить размер строки 132 символа] Вы можете пользоваться абсолютным значением, как в приведенном выше при¬ мере, или относительным значением, как показано ниже: Д1 +12 [Увеличить длину строки на 12символов] В этом случае подразумевается новое значение .11 относительно предыдущего значения. Чтобы восстановить принятое по умолчанию значение (65), используйте .11 без номера: .ll [Восстановить размер строки 65 символов]
254 Часть IV Установка отступа от края страницы Запрос .po(page offset — отступ страницы) устанавливает расстояние от левого края бумаги до первой печатаемой колонки символов, где каждый символ занимает - 2,5 мм. По умолчанию отступ страницы равен 0 (печать прямо на краю страницы), который вы, возможно, никогда не захотите использовать (рис. 20.1). Макропакет, подобный ms, обычно устанавливает .po до 10, что как раз размещает текст посреди¬ не листа бумаги, когда длина строки убтановлена 60. Чтобы установить .po равным 8, используйте следующую запись: .po 8 [Установить отступ страницы8символов] Вы можете использовать абсолютное значение (как в приведенном выше приме¬ ре) или относительное значение: . po -2 [Уменьшить отступ страницы на 2 символа] В этом случае под новым значением запроса .po понимается значение относи¬ тельно предыдущего. Чтобы восстановить значение, которое было перед послед¬ ним изменением .po, наберите .po без номера: .po [Восстановить прежнее значение страницы] Изменение номера страницы Каждый раз, когда программа nroff начинает форматирование нового файла, она устанавливает в 1 свой регистр номера страницы и затем увеличивает содержимое этого регистра для каждой отпечатанной страницы. Обычно вам не требуется нару¬ шать эту последовательность в нумерации. Однако предположим, что вы имеете большой файл, который разбит на два меньших — section 1.a и sec¬ tion l.b, и section 1.b яляется продолжением section 1.a. Ecnusection 1.a содержит26 страниц, то у вас может возникнуть желание продолжать последовательно нумера¬ цию страниц в файле section 1.b, начиная с номера 27: .pn 27 [Установить номер страницы 27] Как и в случае предыдущих команд, вы можете использовать относительноезна- чение. Например, чтобы увеличить номер страницы на два, можно использовать следующий запрос: . pn +2 [Увеличить номер страницы на 2] Если вы используете запрос .pn без последующего номера, то nroff будет игнори¬ ровать этот запрос. .pn [Игнорируется программой nroff] Принудительная смена страницы Обычно неважно, где nroff заканчивает одну страницу и начинает другую. Но воз¬ можны случаи, когда вам необходимо, чтобы конкретный текст появлялся только в начале новой страницы. Чтобы установить принудительную смену страницы в тре¬ буемом месте, вы можете использовать запрос .bp(break page — сменить страницу). Например, если вы хотите начать документ с заголовка — можете перед ним поста¬ вить следующую команду: .bp [Начать новую страницу здесь]
Обработка и форматирование текста 255 Эта команда гарантирует, что nroff отпечатает заголовок в начале новой страницы независимо от того, сколько текста размещено на предыдущей странице. Вы можете также приписывать новой странице номер. Например, чтобы начать новую страни¬ цу и присвоить ей номер 21, вы можете выполнить следующую команду: .bp 21 [Начать новую страницу и назвать ее «стр. 21»] Вы можете также использовать относительный номер. Например, предположим, что текущая страница есть страница 15, и вы хотите сделать так, чтобы следующая страница имела номер 17 (номер обычно помещается на лицевой стороне двусторон¬ него листа). Вы могли бы тогда использовать следующий запрос: .bp +2 [Начать новую страницу и увеличить номер страницы на 2] Сохранение целостности группы строк текста Возможны случаи, когда нежелательно разбивать на части некоторый текст, т. e. ес¬ ли текст целиком умещается на текущей странице, то так и следует его располагать. Но если не умещается — тогда вы захотите переместить весь текст на следующую страницу. Запрос .ne (need — следовать) с числом, которое следует за ним, позволяет хранить определенное число непрерывно следующих строк на одной и той же стра¬ нице. Например, предположим, что вы имеете заголовок, за которым следуют пять строк текста (в общейюложности семь строк). Чтобы быть уверенным, что эти стро¬ ки никогда не будут разделены при смене страниц, перед заголовком наберите сле¬ дующий запрос: .ne 7 [Сохранить на странице следующие семь строк] Другие команды nroff Существует несколько запросов nroff, которые «настраивают» и наполняют текст, оснащают его дефисами, размещают, центрируют, подчеркивают, вырезают строки. К сожалению, мы не сможем рассмотреть здесь все эти средства. Они включены в краткое содержание данной главы. Форматирование таблиц Пример Чтобы рассмотреть основные характеристики препроцессора для получения таб¬ лиц tbl, еще раз форматируем текст письма, который мы использовали в гл. 19. На этот раз будем использовать tbl вместо ms, чтобы форматировать табличный мате¬ риал. Это сводится к замене двух команд вывода на экран (.DS и .DE) командами формирования таблиц (.TS и .TE) и добавлению еще нескольких команд для улучше¬ ния представления текста. 1. Снова подготовьте текст для форматирования. а) Начните еще один сеанс редактирования файлар//. deal. б) Измените .DS на .TS (строка 8) и .DE на .TE (строка 12), затем добавьте еще пять строк, показанных внизу, и вставьте двоеточия, оставляя остальной текст без изменений:
256 Часть IV .TS center ; с с с с 1 n n L . Name Height Weight Team [Начать таблицу] [Центрировать таблицу] [Центрировать каждый заголовок] [Оставить четыре колонки] [Заголовки, разделенные клавишей TAB] .sp 1 [Оставить пробел после заголовков] Emerson, Ezekiel R. 6'5" 273 Rochester Robinson, Charles F. 63" 287 Oes Moines Peterson, PauL N. 5'9" 178 TupeLo . TE [Конец таблицы] [Колонки 1 и 4 выровнены по левому краю, а колонки 2 и 3 содержат только числа.] в) Сохраните текст и верните на экран приглашение интерпретатора shell системы Юникс. 2. Форматируйте текст на экране с помощью nroff. а) Наберите командную строку, которая передает стандартный вывод tbl через кон¬ вейер в nroff с опцией -ms: tbl pfl.deal | nroff -ms Dear Mr. Madison: The purpose of this letter is to confirm Monday's agree¬ ment. Tupelo gets "Porkchop" Peterson, you get "Earthquake" Emerson, and we get "Rotunda" Robinson. Here are the players' names, heights, weights, and newteams: Name Height Weight Team Emerson, Ezekiel R. 6'5" 273 Rochester Robinson, Charles F. 63" 287 Des Moines Peterson, Paul N. 5'9" 178 Tupelo You will be getting one of the finest players in the People's Football League. Your Friend and Mine, Chuck September 2, 1985 6) В примере процессор tbl применен для форматирования табличного материала в середине текста и показаны результаты его работы. Использование препроцессора tbl В предыдущем примере вы использовали одну команду программы nroff с точкой (.sp 1), две команды с точкой препроцессораШ1 (.7"S и.ТЕ)и ряд символов, описываю¬ щих желаемый вид таблицы. Ниже приводится подробный разбор команд и симво¬ лов, которые вы только что использовали в примере.
Обработка и форматирование текста 257 .TS Начать таблицу. center Центрировать таблицу относительно границ таблицы. Закончить описание схемы размещения таблицы; начать описание схемы размещения для отдельных строк. с с с с Центрировать каждый из четырех заголовков над соответствую¬ щими колонками (может быть также два и большее число заголов¬ ков). I n n I Установить позиции колонок информации, как показано (в дан¬ ном случае выровнены по левому краю, цифровые, цифровые, выровнены по левому краю). Конец описания схемы размещения отдельных строк, начало информации, которая помещается в таб¬ лицу. [Заголовки колонок в пределах таблицы, разделенные зна¬ ками табуляции.] .sp 1 Оставить один пробел (пустую строку) между заголовками и ко¬ лонками внизу (команда nroff). [Содержимое введенной таблицы, разделенное знаками табуляции.] .TE Конец таблицы. Использование двухколонного формата Установка текста Если вы хотите разместить текст в более узких колонках, можете отпечатать доку¬ мент в двухколонном формате с помощью команды .2C из текста ms. Затем исполь¬ зуйте команду .1C, чтобы вернуться к одноколонному формату: .2C .LP 2222222222222222222 2222222222222222 22222222222222222222222. .1C .LP 111111111111111111111111 11111111111111111111111. 222222222 2222222222 222222222 2222222222 222222222 2222222. 11111111111111111111111 11111111111111111111111 1111111111. Подготовка вывода для печатающего устройства Обычно печатающее устройство печатает документ в более чем одной колонке толь¬ ко в том случае, если бумага в нем протягивается в обратном направлении. Так как большинство печатающих устройств не обладают такими возможностями, вы должны передавать текст из программы nroff в программу фильтрации, называе¬ мую col (columns — колонки), и затем в программу lpr. Программа col перераспреде¬ ляет текст таким образом, что не требуется печатающее устройство с обратным дви¬ жением бумаги. (Это относится и к тексту, который вы планируете выводить на экран дисплея.) При использовании программы col, желательно предварительно определить тип печатающего устройства, на которое вы посылаете текст. Это можно сделать, вклю¬ чив опцию -T (type) для команды nroff. Так, чтобы описать печатающее устройство, наберите в командной строке -t, за ним lp (line printer — построчное печатающее 9-771
258 Часть IV устройство) или - Tlp. Например, чтобы напечатать файл, называемыйзГогу, в двух¬ колонном формате, вы можете использовать такую запись: $ $ Вы должны также использовать col каждый раз, когда при работе с tbl применя¬ ете опции box или allbox. Эти опции продолжают ту же строку, что и опция center. nroff -ms -Tlp story | coL | lpr Пример двухколонного форматирования Чтобы быстро получить пример двухколонной печати, сделайте копию файласУ/s^s, называемую disks. 2C, затем начните сеанс редактирования с disks. 2C и добавьте в файл шесть запросов на форматирование. В результате первые 9 строк текста фай¬ ла будут выглядеть следующим образом: .PP .pl 32 .DS С Advertisement ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ * ★ ★ * ★ ★ ★ ★ .DE .2C .LP Spinrite diskettes have а lifetime Когда запросы на форматирование вставлены в соответствующее место, выпо¬ лните следующую командную строку: nroff -ms disks.2C | col Advertisement ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ Spinrite diskettes have а lifetime guarantee. That's right, every Spinrite diskette is guaranteed for life. Not two years, not three years, not five years, but life. Advanced technology makes it possible. Sophisticated marketing makes it incredi¬ ble. Superior distribution makes it available. And state-of-the-art manufac¬ turing makes it. No matter what you've read, no matter what you've heard, no matter what you've thought, our warranty stands: Every Spinrite diskette will last until it wears out. That's quality, and that's our guarantee. Don't settle for anything less. Don't waste your time with the amateurs. Step up to the pro- fessionals. Step up to Spinrite. September 4, 1985
Обработка и форматирование текста 259 Другие средства Мы смогли рассмотреть только некоторые средства nroff. Помимо рассмотренных существуют и дополнительные команды, макропакеты, препроцессоры, а также средства переключения файлов, использования различных единиц длины, созда¬ ния собственных макрокоманд и изменения значений, принятых по умолчанию в nroff. К препроцессорам версии 7 системы Юникс относятся refer (генерирует ли¬ стинг библиографических ссылок), eqn и neqn (обеспечивают обработку математи¬ ческих выражений), pic (управляет составлением рисунков). Для более полного озна¬ комления с дополнительными средствами вы можете воспользоваться Руководст¬ вом программиста системы Юникс. Пример: создание алфавитного указателя Ниже мы рассмотрим пример создания предметного указателя в книге средствами системы Юникс. Эти средства облегчают работу, но не являются полностью автоматическими. Предположим, вы хотите получить следующий предметный указатель: anteLope 23, 24, 51 bear, grizzLy 37, 38 coyote 75 deer 82, 84, 85 Вы можете использовать команду sort, чтобы упорядочить список по алфавиту, за¬ тем присоединить некоторые команды обработки текста, ко,торые вы уже изучили. Вы должны, конечно, ввести исходный список слов, но вы будете избавлены от уто¬ мительной работы. Одна из опций команды sort гарантирует, что прописные буквы следуют за соот¬ ветствующими строчными. Начало нового каталога Начнем с создания в вашем исходном каталоге нового подкаталога, который будет содержать алфавитный указатель. Затем перейдем в созданный каталог, чтобы сформировать этот указатель: $ mkdir index $ cd index $ pwd /usr/robi n/i ndex $ [Создайте подкаталог index] [Перейдите в этот подкаталог] [Проверьте, что теперь вы находитесь в нем] [Вы находитесь в созданном подкаталоге] Создание предварительного списка На практике вы обычно имеете дело с законченной книгой, в которой предметный указатель может содержать сотни слов и названий. Для иллюстрации процесса со¬ здания указателя мы используем книгу о дикой природе, содержащей 5 страниц. Ба¬ зовые процедуры здесь те же и не зависят от объема книги. Мы покажем обработку текста с использованием редактора ed, но вы можете использовать и другой редак¬ тор.
260 Часть IV 1. Начните редактирование файла, называемого/Zsf. prelim: $ ed list.prelim 7list.prelim 2. Начиная с первой страницы книги, наберите каждое слово или фразу1*, которую надо внести в указатель, двоеточие, пробел, затем номер страницы: а geese: 1 fox: 1 fox: 2 deer: 2 elk: 3 antelope: 3 Fox, George P.: 4 coyote: 4 deer: 4 wolf, grey: 5 coyote: 5 deer: 5 [Записи, содержащие несколько имен] 3. Запомните этот список и вернитесь в интерпретатор shell системы Юникс: fwl t18 m $ _ Порядок, в котором вы вводите слова, не имеет значения. Их пЬследовательный ввод, вероятно, наиболее удобен. Если вы пропустили слово на одной странице и включили его в другую страницу, при этом не возникает проблемы: все слова будут отсортированы. Упорядочение списка по алфавиту Теперь, когда вы имеете предварительный список слов для формирования указате¬ ля, следующий шаг — упорядочение его по алфавиту. Для этого используйте коман¬ ду sort.TaK как список содержит слова, начинающиеся с прописной буквы, то, чтобы объединить эти слова в списки, используйте опцию -f. 1. Упорядочите список по алфавиту командой sort и выведите результаты на экран: $ |sort -t: +0 -1 +1n -f list,prelim antelope: 3 1) Далее для краткости эти элементы будущего алфавитного указателя названы объекта¬ ми, или просто словами. — Прим. ред.
Обработка и форматирование текста 261 coyote: 4 coyote: 5 deer: 2 deer: 4 deer: 5 elk: 3 Fox, George P.: 4 fox: 1 fox: 2 geese: 1 wolf, grey: 5 $ _ Так как мы хотим получить результаты в файле, а не выводить их на экран дис¬ плея, то мы можем использовать опцию - о, чтобы переслать выходную информа¬ цию в другой файл. Опция -о здесь работает так, как символ переадресации для вывода (>). 2. Упорядочите по алфавиту список с помощью команды sort и перешлите результа-' ты в файл, называемый//^/. sort. $ $ sort -t: -f +0 "1 +1n -о list.sort list.prelim Ниже приводятся краткие пояснения к KOMaHflesort: -t: -f +0 -1 + 1n -о list, sort Использовать двоеточие (:) как символ табуляции или раздели¬ тель полей. Для каждой записи1) поле 1 будет представлять объект, введенный в алфавитный указатель, а поле 2 — номер страницы или номера страниц. Перевести прописные буквы в строчные. Когда номера страниц упорядочены (+ 1n), требуется рассорти¬ ровать объекты указателя (+0- 1). Это средство позволяет вводить слова в любом порядке. Поместить вывод в файл, называемый/гё/. sort. Форматирование списка Теперь, когда вы имеете упорядоченный по алфавиту список слов, вы близки к полу¬ чению окончательного указателя. Но остается еще объединить номера страниц, ко¬ торые содержат одни и те же слова. Для этого мы используем сначала средство awk, чтобы удалить описание объединяемых объектов (слов) во всех записях в спи¬ ске после первого. (Мы заменим также с помощью awk двоеточия на пробелы.) Ис¬ пользуйте команду cat, чтобы ввести операторы awk в файл, называемый combine, затем выполните awk с опцией - f, чтобы присвоить этому файлу имя. 1. Введите операторы awk. а) Наберите с помощью cat следующее, используя клавишу TAB для размещения: 1) Каждый отдельный элемент в алфавитном указателе или предварительном списке на¬ зван записью. — Прим. ред.
262 Часть IV $ cat > combine BEGIN { FS = ":"; subject = " "; n = 0 > S1=subject { entry[n] = entryCn] "," S2; break > { n++; entry[n] = $1 M " S2; subject = S1 > END { for (*i = 1; i <= n; i++ ) print entry[i]> * 6[CTRL-D] 6) Ниже приводится краткое пояснение операторов. BEGIN FS = ”:” subject = ”” $1 = = subject < entry[n]= < entry[n]V $2 break n+ + entry[n] = $1””$2 subject = $1 END Оператор-образец, аналогичный END, позволяет устанав¬ ливать действия, которые необходимо выполнить перед тем, как прочитаны записи. Используйте двоеточие в качестве разделителя полей, чтобы упростить обработку; теперь можно забыть о запя¬ тых и пробелах, которые встречаются в записях обраба¬ тываемого списка (например, ”wolf, grey”); описание каж¬ дого объекта (слова) помещается в поле 1, а номер стра¬ ницы — в поле 2 записи. Эта переменная используется, чтобы сохранить описа¬ ние объекта для предыдущей записи в списке. Проверить, соответствует ли текущее описание объекта предыдущему; если да, выполнить два оператора- действия, которые следуют за ним. Вставить запятую, затем добавить новый номер страни¬ цы $2 к текущей записи. Пропустить операторы-действия, которые следуют за ним. Если текущее описание объекта не соответствует преды¬ дущему, выполнить следующие три оператора-действия: Увеличить номер записи на 1 Удалить двоеточие, если оно присутствует, из новой за¬ писи, в противном случае оставить запись без изменения. Сделать новый объект «предыдущим объектом» для сле¬ дующей записи. Выполнить следующий оператор-действие после того, как все записи считаны и обработаны: {for(i = 1; i < = n; i+ + ) print entry [i]j Отпечатать все запи¬ си с начала (i = 1) до конца (i = n). Логика выполнения команды awk script очень проста: • Если объект текущей записи отличается от объекта предыдущей записи, счетчик элементов (n) увеличивается на единицу и запись остается без изменения (за ис¬ ключением удаления двоеточия). • Если объект в текущей записи такой же, как и в предыдущей записи, текущий номер страницы добавляется к существующему списку номеров страниц, разделенных запятой. Затем печатаются все записи по порядку. (Необязательно знать точно, как рабо¬ тает команда script; вы можете использовать ее, чтобы создать указатель и сэконо¬ мить время.)
Обработка и форматирование текста 263 2. Используйте операторы awk в командной строке. (Наблюдая результаты на экране): $ awk -f combine list.sort antelope 3 coyote 4, 5 deer 2, 4, 5 elk 3 Fox, George P. fox 1, 2 geese 1 wolf, grey 5 $ _ Итак, указатель создан. Объединение команд Объединим команды sort и awk в одну простую команду. 1. Устраните промежуточные файлы. а) Чтобы устранить промежуточные файлы, используем конвейеры для соединения команд вместе (они будут помещены в одну строку): $ |sort -t: -f +0 -1 +1n list.prelim | awk -f combine antelope 3 coyote 4, 5 deer 2, 4, 5 elk 3 Fox, George P. 4 fox 1, 2 geese 1 wolf, grey 5 $ _ 6) Это один путь. Но мы можем сделать это еще проще. 2. Присвойте этой командной строке собственное имя. а) Используйте команду cat, чтобы ввести командную строку в файл, называемый index: г1 IS0 _cat > index sort -t: -f +0 -1 +1n $1 l awk -f combine [CTRL-D] $ 6) ИспользуйтесИтос!, чтобы сделать/лсУех выполняемым: chmod u+x index
264 Часть IV Вы только что создали свою собственную команду index, которую можете ис¬ пользовать для формирования указателя из любого списка вводимых слов, как опи¬ сано выше в этом разделе. С этого момента вы можете просто набирать команду, как это показано ниже: index list.prelim или $ index Li Qt ПГРI' [Вывод на экран] [Вывод в файл] Более подробное объяснение использованного выше выражения вы можете по¬ лучить в данной книге в части V «Программирование на языке shell в системе Юникс». Форматирование Наконец, чтобы отпечатать алфавитный указатель в две колонки, как это принято, вы можете поместить в начале файла/&?, final запросы ms: .PP .2C Затем вы можете отпечатать указатель в две колонки, выполнив следующую ко¬ манду: $ $ Краткое изложение главы 20 В этой главе вы научились выполнять форматирование с помощью nroff, используя различныеопции, осуществлять форматирование таблице помощькПЫ и печатать в двухколонном формате с помощью ms. nroff -ms -TLp list.final |соL| lpr] Проведение форматирования Выполнение командной строки nroff. Чтобы проиллюстрировать форматирова¬ ние на экране вашего дисплея, наберите командную строку с именем команды (nroff), пробел и имя файла, который надо форматировать. Для получения твердой копии результатов перешлите через конвейер выходной поток программы nroff для программы печати lpr. Определение макропакета. Чтобы использовать макропакетгпБ, включитеопцию - ms мeждynroff и именем файла. Этот пакетхранится в dpannelusrllibltmacltmac.s. Другие макропакеты также хранятся в этом каталоге. Ниже перечислены дополни¬ тельные опции: Начало номера страницы -np Специальные страницы -оp Остановка вывода между страница¬ ми -sn Определение печатающего устройст¬ ва — T name
Обработка и форматирование текста 265 Некоторые основные запросы Запросы, рассмотренные в данной главе: Pl Длина страницы .11 Длина строки .po Отступ страницы .pn Номер страницы .bp Смена страницы .ne Дополнительное требование (сохранение целостности строк) Другие запросы: .fi Включить заполнение выводимых строк .nf Отметить режим заполнения строк: I выровненных по левому краю r .ad выровненных по правому краю. с Настроить центрирование: b на оба края n нормальный режим на левый и на правый край .na Настройка не требуется .hy n Оснастить n дефисами .nh Оснащение дефисами не требуется .br Перейти на следующую строку .ls n Заполнить n пробелами .ce n Центрировать следующие n строк .ul Подчеркнуть .cu Непрерывное подчеркивание .in n Сделать отступ на n позиций .ti n Временный отступ % Номер страницы \и Подчеркивание сверху \d Подчеркивание снизу формАтировАНИЕТАВлиц. Чтобы форматировать таблицу, поместите .TS над заголов¬ ками и информацией, а .TE — внизу под соответствующими описаниями, набранны¬ ми между .TS и телом таблицы. Затем выполните команду, подобную следующей: tbl file | nroff -ms | lpr ИспользовАНИЕ двухколонного ФОРМАТА. Чтобы напечатать текст в две колонки, по¬ ставьте перед этим текстом .2C. Затем выполните командную строку, подобную при¬ веденной ниже: $ nroff -ms -Tlp file | col | Lpr
Часть V. Программирование на языке shell системы Юникс Глава 21. Введение в B-shell Введение До сих пор shell в системе Юникс нам был известен как интерпретатор команд, который не является частью операционной системы, но обеспечивает интерфейс между пользователем и ядром с помощью выполнения вводимых с терминала команд. Shell служит и в качестве языка программирования, который позволяет создавать собственные программы, называемые shell-программами, или shell- файлами. Эти возможности рассмотрены в гл. 24. Стартовый shell-файл .profile В вашем начальном каталоге, вероятно, имеется файл, который предоставляет интерпретатору shell необходимые параметры для проведения процедуры ини¬ циализации при вхождении в систему. Этот файл носит имя .profile и содержит информацию, используемую интерпретатором shell для определения таких харак¬ теристик вашей рабочей среды, как тип терминала, знаки-подсказки (которые бу¬ дут выводиться на ваш экран), имена каталогов системы Юникс (содержащие ис¬ пользуемые вами команды), имя файла для организации вашей электронной по¬ чты, права доступа (которые будет получать новый файл при создании), а также характеристики вашего терминала. Если ваш начальный каталог содержит файл с именем.ргоМе, при каждом ва¬ шем вхождении в систему интерпретатор shell будет исполнять этот файл перед выдачей знака-подсказки. Если же в вашем начальном каталоге такого файла нет, интерпретатор shell для инициализации будет использовать свои собствен¬ ные задаваемые по умолчанию значения. Ниже приведено содержимое типично¬ го файла .profile: TERM=VTT00 [Установка типа терминала] PS1 = '% ' [Установка первичной подсказки] PS2=1> ' [Установка вторичной подсказки] PATH=/bi n: /usr/bi n:$HOME/bi n:: [Установка последовательности поиска команды] MAIL=/usr/spool/mail/ basename $НОМЕ [Установка имени почтового ящика] umask 022 [Установка маски создания файла] : set tty [Установка характеристик вашего stty erase "дН" -tabs терминалагподавлениевывода на stty cr0 ff0 экранСТЯЬ-Н;замена при выводе export MAIL HOME PATH TERM знаков табуляции пробелами; подавление задержки при возвра¬ те каретки или переводе формата; передача четырех переменных интерпретатора shell(cM. ниже)]
Программирование на языке shell системы Юникс 267 Переменные интерпретатора shell Обычно администратор системы создает файл .profile, а также определяет пере¬ менные типа TERM, PS1, PS2, PATH, НОМЕ и MAIL при включении в систему ново¬ го пользователя. Однако с помощью редактора текста вы сами можете отредак¬ тировать файл .profile и, если необходимо, переопределить любую из этих пере¬ менных. В табл. 21.1 приводится краткое описание переменных; более подробно они рассматриваются в следующем разделе. Таблица 21.1 Переменные интерпретатора shell Переменная Описание НОМЕ Входной каталог. Программа входа в систему присваивает переменной НОМЕ имя каталога, который становится вашим текущим каталогом после входа в си¬ стему. При выполнении команды cd без аргумента интерпретатор shell всегда автоматически возвращает вас в этот каталог. MAIL Почтовый файл. Если эта переменная определена, она указывает интерпрета¬ тору shell на файл, который служит в качестве вашего почтового файла, и с помощью переменной MAIL система информирует вас, когда вам приходит но¬ вое почтовое сообщение. PATH Последовательность поиска файла команды. Эта переменная используется ин¬ терпретатором shell для поиска в последовательности каталогов файла коман¬ ды, если вы задаете частичное составное имя файла. Переменная PATH уста¬ навливается путем ввода списка имен файлов, разделяемых двоеточиями. Ес¬ ли значение этой переменной не устанавливается, оно считается равным :/bin:/usr/bin, что означает обращение сначала в текущий каталог, затем в ката¬ лог lbin и, наконец, в каталог lusrlbin. PS1 Первичная подсказка. С помощью этой переменной определяется подсказка, которую выводит интерпретатор shell, когда он готов принимать входное сооб¬ щение. PS2 Вторичная подсказка. С помощью этой переменной определяется подсказка, которую выводит субинтерпретатор subshell1) для получения дополнительного входного сообщения. 1) Субинтерпретатор — копия основного интерпретатора; создается по его инициативе и вызывается для исполнения им в форме подпрограммы. — Прим. ред. Установка переменных Первичная подсказка PS1 Когда интерпретатор shell готов принимать команду с вашего терминала, он вы¬ водит подсказку. По умолчанию в качестве нее используется знак $. Изменением переменной PS1 вы можете задать собственный вид подсказки, например: [Установка в качестве первичной подсказки $l PS1 = 'Ready Ready Ready с пробелом] [Это ваша новая первичная подсказка] Обратите внимание на пробел, который следует за Ready. Он отделяет подсказку от вашей последующей командной строки. С этого момента и до тех пор, пока вы не закончите работать с системой или переопределите значение переменной PS1, вашей первичной подсказкой будет Ready, а не знак $. Для определенности в ка¬ честве первичной подсказки во всей этой главе мы будем использовать знак $.
268 Часть V Вторичная подсказка PS2 Переменная PS2 используется интерпретатором shell для указания того, что он ожидает продолжения ввода. По умолчанию значением переменной PS2 является знак >, например: $ > > > $ ( cd /bin Ls -1 ) Интерпретатор shell рассматривает скобку ( как символ группирова¬ ния команд. В этом случае интерпретатор shell создает субинтерпретатор sub¬ shell, который выводит знак-подсказку > для указания своей готовности к вводу команд. Интерпретатор shell не выполняет ни одной из команд до тех пор, пока вы не сообщите ему о завершении ввода нажатием клавиши со скобкой ()). Если вы случайно нажмете неправильную клавишу и увидите вторичную подсказку, то, нажав клавишу DEL, вы снова вернетесь к первичной подсказке. Приведенный выше пример иллюстрирует один из возможных случаев, когда интерпретатор shell выводит на экран вторичную подсказку, задаваемую значением переменной PS2. Более подробно группирование команд рассматривается в гл. 22. Вид вто¬ ричной подсказки вы можете изменить так же, как вы изменяли вид первичной подсказки, например: $ PS2='more pLease 1 [Установка в качестве вторичной подсказ¬ ки more please] Теперь вторичной подсказкой у вас становится словосочетание more please (пожалуйста, еще). Тип терминала TERM Чтобы правильно отобразить информацию на ваш терминал, необходимо уста¬ новить переменную TERM. Значение, присвоенное этой переменной, должно со¬ впадать с одним из имен терминалов, содержащихся в файлe/etc/termcap. Пере¬ менные TERM, PATH и MAIL устанавливаются так же, как и переменные, связан¬ ные с подсказками, например: $ $ $ $ PATH=:/bi n:/usr/bi n:$HOME/bi n TERM=adm3a MAIL=/usr/spool/mai L/'basename $HOME' Начальный каталог НОМЕ Переменная НОМЕ обычно не изменяется. Однако в некоторых случаях после входа в систему вам может потребоваться вновь инициализировать эту перемен¬ ную, чтобы впредь иметь возможность возвращаться в нужный каталог, не вводя его длинного полного имени, как в следующем примере: $ $ HOME=/usr/j im/project/planni ng/report
Программирование на языке shell системы Юникс 269 Напомним, что команда cd без аргументов возвращает вас в ваш начальный ката¬ лог, который соответствует значению переменной НОМЕ. Так, если вы установи¬ ли значение переменной НОМЕ таким, как показано в предыдущем примере, то ввод команды cd без аргументов будет эквивалентен выполнению следующей команды: $ $ cd /usr/j im/project/planning/report Передача переменных интерпретатора shell Выше в этой главе было показано, что переменные TERM, PATH, MAIL, PS1 и PS2 вместе с командой stty определяются в файле .profile, поэтому нет необходимо¬ сти их устанавливать при каждом входе в систему. Чтобы любые порожденные процессы (процессы-потомки) могли унаследовать эти переменные, обычно их необходимо передавать. (Понятие о процессах-потомках поясняется в этой главе ниже.) Если же переданные переменные должны модифицироваться в процессе- потомке, область действия этих новых значений будет распространяться только на этот процесс-потомок, а предыдущие значения будут автоматически восста¬ навливаться, когда управление от процесса-потомка возвращается к родитель¬ скому процессу. Поместите команду export в конце вашего файла .profile, как это показано выше в этой главе. Чтобы интерпретатор shell вывел все передаваемые переменные, наберите команду export, как в следующем примере: $ export MAIL HOME PATH TERM $ С помощью команды echo можно запросить у интерпретатора shell вывод зна¬ чений его переменных (команда echo рассматривается в гл. 23): $ echo $HOME /usr/joe $ Команды и аргументы Интерпретатор shell как интерпретатор команд берет командные строки, введен¬ ные с терминала или из файла, и рассматривает первое слово в них как имя ко¬ манды, а оставшиеся слова как аргументы. Затем, используя имя команды, интер¬ претатор shell отыскивает выполняемый файл команды, вызывает его и переда¬ ет ему все относящиеся к нему параметры. Аргументы, которые имеют для интер¬ претатора shell специальный смысл (такие, как &, I, >>, $, *), не передаются про¬ грамме обрабатываемой команды, а сохраняются для анализа самим интерпрета¬ тором shell. Эти специальные символы, называемые метасимволами, рассматри¬ ваются в этой главе ниже. Рассмотрим следующий пример: $ mv fi le1 file2 & $ Интерпретатор shell отыскивает выполняемый файл команды с именем mv, вызывает его, передает файлу mv в качестве аргументов file 1 и file 2, но оставля¬
270 Часть V ет аргумент &, чтобы самому интерпретировать его как требование на выполне¬ ние этой командной строки в виде фонового процесса. (Фоновые процессы под¬ робно рассматриваются ниже в этом разделе.) Одни команды требуют единствен¬ ного аргумента, другие — нескольких (как в предыдущем примере), но есть ко¬ манды, вообще не требующие каких-либо аргументов, например: $1 pwd /usr/ji m/zebra $ _ Команда pwd (print working directory — печать текущего каталога) выводит полное составное имя вашего текущего каталога. В любом случае даже простей¬ шая команда требует по крайней мере одного символа, как в случае команды /, которая формирует список всех имен файлов в текущем каталоге. Вызов команд интерпретатором shell При входе в систему Юникс вам передается копия интерпретатора shell в качест¬ ве нового родительского процесса. Это позволяет использовать все ресурсы опе¬ рационной системы, к которым вы имеете право доступа. Из этого родительского процесса вызывается файл команды путем создания дубликата процесса shell, называемого «процессом-потомком», или «порожденным процессом». После этого родительский процесс shell ожидает завершения выполнения порожденного про¬ цесса при условии, что файл команды является скомпилированной и скомпоно¬ ванной программой. Если же файл команды является shell-процедурой, интерпре¬ татор shell будет просто читать файл и запускать из него команды. (Процедуры интерпретатора shell описываются в гл. 24.) На рис. 21.1 показана связь между ро¬ дительским процессом и процессом-потомком. Рис. 21.1. Пример порождения процесса. Создание процесса-дубликата называется порождением, а процесс-потомок — порожденным процессом. Процесс-потомок может порождать другой новый про¬ цесс, становясь тем самым процессом-родителем для своего процесса-потомка, а его родительский процесс становится «прародителем».
Программирование на языке sheil системы Юникс 271 Поиск команд интерпретатором shell Если вы знаете точное местоположение файла команды, вы можете его вызвать, задав полное составное имя. В этом случае интерпретатор shell не будет искать этот файл в каких-либо других каталогах. Пусть, например, в каталоге /usr/jim/ print есть команда с именем greeting (greeting — приветствие), которая выводит сообщение WELCOME TO UNIX. Тогда вы можете точно указать интерпретатору shell местоположение этой команды: $ /usr/j im/print/greeting WELCOME TO UNIX $ Если же вы не задаете интерпретатору shell полное составное имя, для поис¬ ка команды он будет использовать либо значение переменной PATH, определяе¬ мое в вашем файле.рго///е, либо значение, устанавливаемое интерпретатором по умолчанию. Как показано выше в этой главе, переменная PATH может быть уста¬ новлена с помощью знаков двоеточия :, отделяющих имена каталогов, в которых следует осуществлять поиск, например: PATH=/bi n:/usr/bi n::$HOME/bin Если переменная PATH в вашем файле .profile имеет указанное значение, интер¬ претатор shell в первую очередь будет искать команду greeting в каталоге /bin. Если ее там нет, он продолжает поиск в катапоге/usr/bin. Если и там требуемой команды нет, интерпретатор shell попытается использовать ваш текущий каталог (дополнительный знак двоеточия). Наконец, если он не найдет команду greeting в вашем текущем каталоге, он обратится к подкаталогу вашего начального каталога ($HOME) с именем /bin. Если, например, вы хотите узнать, кто в текущий момент обратился к системе, а сами вы входили в систему под именем Jim, наберите команду who j im $ В данном случае интерпретатор shell нашел команду who в каталоге/Ь/л. Изме¬ няя порядок имен каталогов при установке значения переменной PATH, вы може¬ те заставить интерпретатор shell начинать поиск с вашего текущего каталога, для чего поместите знак двоеточия : справа от знака равенства, например: PATH=:$HOME/bi n:/bi n:/usr/bi n При таком порядке поиска вы можете сохранять в своем каталоге собствен¬ ные копии общедоступных или обычных команд, даже если ваши команды имеют те же имена, что и обычные команды. Лучше всего хранить все ваши команды в одном каталоге, чтобы вам не приходилось запоминать много путей поиска этих команд, когда собираетесь вызвать одну из них. Обычно пользователи системы Юникс хранят собственные команды в своем подкаталоге bin (binary). Название bin используется потому, что большинство файлов в этом каталоге являются объектными файлами, которые хранятся в двоичной форме. Корневой каталог двоичных файлов (lbin) содержит системные команды, а каталог /usr/bin — команды пользователя. Каждый пользователь обычно может использо¬ вать команды любого из этих двух каталогов. Если переменная PATH имеет такое же значение, как в приведенном выше примере, интерпретатор shell сначала осу¬ ществляет поиск в вашем текущем каталоге, затем в вашем подкаталоге с именем bin и только потом уже в других каталогах bin.
272 Часть V При установке значения переменной PATH будьте внимательны к заданию по¬ рядка расположения каталогов. Если вы не позаботитесь об этом, заставите си¬ стему зря тратить драгоценное время, выполняя безрезультатный и ненужный поиск. Предположим, например, что переменной PATH присвоено следующее зна¬ чение: $ PATH=:/usr/di йд/bi n:$HOME/bi n:/usr/j ohn/bi n:/usr/bi n:/bi n Каждый раз, когда вы вводите команду, находящуюся в каталоге/Ь/'л, интерпре¬ татор shell вынужден проходить через все эти шесть шагов, прежде чем найдет и выполнит введенную команду: (Ваш текущий каталог) /usr/diag/bin $HOME/bin /usr/john/bin /usr/bin /bin Если наиболее часто используемые вами команды находятся в каталогах lbin и lusr/bin, то вы заставите систему выполнять лишнюю работу, если не перерас¬ пределите более эффективно каталоги при установке переменной PATH; напри¬ мер, так: PATH=/bin:/usr/bin::$HOME/bin:/usr/j ohn/bin:/usr/diag/bi n Теперь интерпретатор shell будет искать команды в следующем порядке и может делать это быстрее: /bin /usr/bin (Ваш текущий каталог) $HOME/bin /usr/john/bin /usr/diag/bin Стандартный ввод, вывод и диагностика Когда начинает выполняться команда системы Юникс, открываются три файла, каждый из которых связан с числом, называемым дескриптором файла: • Стандартный ввод (дескриптор файла 0) с терминала или из файла-аргумента. • Стандартный вывод (дескриптор файла 1) на терминал или в файл. • Стандартный вывод диагностических сообщений (дескриптор файла 2) на тер¬ минал или в файл. В каждом из этих случаев терминал является устройством ввода или вывода, задаваемым по умолчанию. Предположим, например, что в вашем текущем ката¬ логе есть файл с именем message, который содержит сообщение WELCOME TO UNIX. Когда вы вводите команду $ cat message WELCOME TO UNIX $
Программирование на языке shell системы Юникс 273 эта команда cat обращается к своему стандартному вводу (т. e. читает содержи¬ мое файла message), затем направляет это содержимое файла на стандартный вывод (т. e. на ваш терминал). Каждое диагностическое сообщение команды cat тоже направляется на тер¬ минал. Если файла с именем message в вашем текущем каталоге нет или у вас нет прав на чтение этого файла, на диагностический вывод (т. e. на ваш терми¬ нал) будет выдано сообщение об ошибке, например: $ cat message cat: can't open message $ Кроме того, если в команде cat вы не указываете в качестве аргумента имя файла, она будет вводить текст, который вы набираете на клавиатуре, а затем выводить его на ваш экран: $fcat this is а test <cr> [Команда cat воспринимает это как ввод] <AD> [Конец ввода] this is а test [Отображениевыводанаэкран] $ В этом примере <cr> соответствует клавише RETURN, а <AD> — CTRL-D. Команду cat можно использовать и для ввода текста в файл, направляя резуль¬ тат ее работы (вывод) в файл: $J cat > text.fi Le I am using cat to create my own This is the second line of text <AD> $ li tt Le fi Le. in my LittLe <cr> fi Le. <cr> Теперь у вас есть файл с именем text, file, содержимое которого представляет со¬ бой то, что вы вводите с клавиатуры. (CTRL-D завершает текст.) Переадресация ввода и вывода В предыдущем разделе вы ознакомились со стандартным вводом и выводом. Од¬ нако у вас может возникнуть потребность выполнить в команде ввод или вывод, отличный от стандартного. Это можно сделать с помощью переадресации, ис¬ пользуя следующие символы: < file Переадресация ввода в команде из file > file Переадресация вывода в команде на file > > file Добавление вывода команды к файлу file Переадресация ввода Стандартным вводом команды mail является то, что вы набираете на своем тер¬ минале. В качестве сообщения в команде mail можно посылать содержимое су¬ ществующего файла, а не набираемое на клавиатуре, используя для этого переад¬ ресацию ввода на этот файл, например: $ mai L j im < Letter $
274 Часть V Теперь команда mail будет читать содержимое файла letter и пересылать его пользователю с именем Jim. Переадресация вывода Если вы имеете право записывать на устройство или в файл, можете использо¬ вать последние для вывода в любой команде, которая пересылает данные на стандартный вывод, например: $ $ cat message > fiLe 1 В этом примере команда cat читает содержимое файла message и записывает свой вывод в файл с именем file 7. Если file 7 не существует, он будет создан интерпретатором shell; если этот файл уже существует, его содержимое будет из¬ менено. Если же вы не имеете права записывать в файл file 7, увидите на экра¬ не следующее сообщение: $ cat message > file_1 cat: can't create fiTe_1 $ С помощью команды cat можно вывести файл на печать, например: cat message > /dev/Lp или переслать файл на другой порт вывода: $ $ cat message > /dev/tty05 При работе с интерпретатором shell у вас может возникнуть потребность со¬ здать пустой файл. Это можно сделать с помощью символа переадресации, как в следующем примере: > empty.file [Создание файла с именем empty, file] Переадресация вывода с использованиемдескрипторов файлов Путем добавления соответствующих дескрипторов файлов можно направить стандартный или диагностический вывод в различные файлы или на различные устройства, например: $ $ cat message 1>&file.out 2>&file.error Содержимое файла message будет записано в file.out, а любые сообщения об ошибках, которые могут появиться, будут пересылаться в файл с именем file.error. Таким же способом можно переадресовать стандартный и диагностиче¬ ский выводы в один и тот же файл: $ $ cat message 1>&file.alL 2>&1
Программирование на языке shell системы Юникс 275 С помощью сдвоенных символов > > можно добавить к концу файла содер¬ жимое другого файла, не переписывая при этом первый файл: $ $ $ Теперь файл file.both включает все содержимое файла message плюс все содер¬ жимое файла greeting. cat message > file.both cat greeting » file.both Замечание по переадресации Переадресованным может быть только стандартный ввод или вывод команды. Например, команда date всегда обращается к системе, а затем отображает теку¬ щую дату и время на вашем экране, т. e. ввод этой команды не является стан¬ дартным и поэтому его нельзя переадресовать. Другим примером является вы¬ вод команды lpr, который всегда направлен на устройство печати, т. e. не являет¬ ся стандартным и поэтому не может быть переадресован. Если вы не уверены относительно конкретной команды, то прежде чем переадресовать ее ввод или вывод, обратитесь к Руководству пользователя системы Юникс. Краткое изложение главы 21 В этой главе вы ознакомились с интерпретатором shell системы Юникс. Были рассмотрены стартовый файл интерпретатора shell (profile), переменные интер¬ претатора shell, команды и аргументы, стандартный ввод, вывод, диагностика и переадресация ввода и вывода. Введение Вначале shell системы Юникс рассмотрен как язык программирования. Стдртовый ФАйл интЕРПРЕТАТОРА shell. Этот файл (profile) выполняется сразу же по¬ сле вашего входа в систему и находится в вашем начальном каталоге. Его соде¬ ржимое предоставляет системе Юникс информацию о вашем терминале и уста¬ навливает вашу первичную и вторичную подсказку, последовательность поиска команды, имя вашего почтового ящика, способ создания файла и другие характе¬ ристики, которые относятся к работе вашего терминала. ПЕРЕМЕННЫЕ интЕРПРЕТАТОРА shell. Ниже приведены переменные интерпретатора shell, обычно определяемые в файле .profile: PS1 Первичная подсказка PS2 Вторичная подсказка TERM Тип терминала PATH Последовательность поиска файла команды MAIL Почтовый файл НОМЕ Входной каталог Для получения значения переменной укажите перед ее именем знак $, напри¬ мер: $ echo $HOME /usr/robin
276 Часть V Установка переменных интерпретатора shell Чтобы установить значение любой переменной интерпретатора shell, после его подсказки можно выполнить командную строку. По своему действию это эквива¬ лентно записи той же строки в файл .profile. Процесс распространения области действия значений переменных интерпретатора shell на все процессы-потомки, запускаемые с вашего терминала, называется передачей переменных. Она выпол¬ няется командой export. Команды и аргументы Подлежащая обработке интерпретатором shell командная строка должна содер¬ жать имя команды и может включать аргументы и специальные символы, кото¬ рые называются метасимволами и указывают интерпретатору shell на специаль¬ ные операции. Например, в командной строке mv fi le.1 fi le.2 & mv — имя файла команды, file.1 и file.2- аргументы, а & указывает интерпрета¬ тору shell, что команда mv выполняется как фоновый процесс. Вызов комАНДЫ интЕРПРЕТАТОРОм shell. При каждом вашем входе в систему Юникс вам назначается копия интерпретатора shell в качестве нового родительского процесса. Когда интерпретатор вызывает скомпилированную программу, для вы¬ полнения этой программы он создает новый процесс, называемый процессом- потомком. Это действие называется порождением процесса, а процесс- потомок — порожденным процессом. При выполнении shell-процедуры интерпретатор просто вводит файл проце¬ дуры и запускает команды, находящиеся в этом файле. Поиск комАнды интЕРПРЕТАТОРОм shell. Если вы не указываете интерпретатору shell полное составное имя файла команды, при поиске команды он будет ис¬ пользовать значение переменной PATH. Значение PATH — это список составных имен каталогов, в которых могут быть найдены команды. Стандартный ввод, вывод и диагностика Когда интерпретатор shell начинает выполнять команду, он открывает три фай¬ ла, каждый из которых связан с числом, называемымдескриптором файла: стан¬ дартный ввод (0), стандартный вывод (1) и стандартный вывод диагностики (2). ПЕРЕАДРЕСАЦИЯ вводА и выводА. Переадресацию с целью изменения направления ввода или вывода можно задать с помощью одного из следующих символов: < Переадресация ввода в команде из файла > Переадресация вывода в команде на файл > > Добавление вывода команды к файлу Для переадресации стандартного вывода команды или вывода диагностики пе¬ ред символом переадресации укажите дескриптор файла, например: $ cat msg 1>&out 2>&error Переадресация ввода или вывода возможна не для каждой команды системы Юникс. В некоторых из них отсутствует ввод, другие не создают вывода. Переад¬ ресация ввода или вывода применима только для стандартного ввода или стан¬ дартного вывода. В случае сомнения обращайтесь к Руководству пользователя системы Юникс.
Программирование на языке shell системы Юникс 277 Глава 22. Процессы интерпретатора B-shell Фоновые команды Чтобы обеспечить возможность запуска с вашего терминала более одного про¬ цесса, после последнего операнда своей командной строки добавьте амперсанд &. Это позволит вам сразу же вводить следующую команду, не дожидаясь завер¬ шения предыдущей. Например: $ cc program.c & 308 $ По этой команде вызывается компилятор языка Си для компиляции в фоновом режиме исходного модуля программы из файла program.c. Интерпретатор shell инициализирует этот процесс, а ядро системы назначает ему номер процесса (в данном примере 308). Число процессов, которое вы можете запустить одновре¬ менно, ограничивается системой. Если вы выходите за этот предел, на ваш тер¬ минал выводится предупреждение. Чем большее число процессов выполняется в любой заданный момент времени (привилегированных или фоновых), тем хуже реакция системы. Выполнение команды как фонового процесса не изменяет организации ее ввода и вывода. Так, если стандартный ввод такого процесса осуществляется с вашего терминала, он может быть прерван вводом с клавиатуры для текущего привилегированного процесса. Аналогично, если стандартный вывод фонового процесса тоже выполняется на ваш терминал, он нарушит отображение на экран информации от текущего привилегированного процесса. Чтобы избежать этого, лучше всего переадресовать ввод и вывод фоновых процессов. Для изменения стандартного вывода фонового процесса применяйте команду nohup (no hangup — с защитой от прерываний), например: nohup cmp file1 fUe2 & 320 Sending output to *nohup.out' $ Вывод команды cmp (compare — сравнивать) будет передан в файл nohup.out. Если этот файл не существует, он будет создан интерпретатором shell; если же существует, вывод этой команды будет добавлен к концу файла nohup.out. В случае отсутствия разрешения на запись в ваш текущий каталог интер¬ претатор shell направит вывод в файл nohup.out в вашем начальном каталоге ($HOME/nohup.out). Команда nohup делает ваш процесс невосприимчивым к разрыву связи с ва¬ шим терминалом при его отключении, а также к сигналам завершения, вводимым с вашего терминала. По этой причине команда nohup является наилучшим средст¬ вом продолжить фоновый процесс после отключения вашего терминала. Фоновые процессы ps Иногда у вас может возникнуть потребность узнать, завершились ли (или ненор¬ мально прекратились) ваши фоновые процессы. Для определения состояния этих процессов используйте команду ps (process status — состояние процесса). Эта
278 Часть V команда выводит на экран информацию об активных процессах и может иметь несколько различных опций. Если команда ps задается без каких-либо опций, вы¬ водится только список активных процессов, связанных с данным терминалом, например: $ cc screen.c & 283 *ra рГбТТУ TIME CMD 283 02 0:02 cc screen.c 037 02 0:11 -sh 290 02 0:01 ps $ В первой строке под заголовком PID (идентификатор процесса) появляется число, назначенное вашему фоновому процессу (283), и это говорит о том, что вы¬ званный вами фоновый процесс начал выполняться. Колонка с именем TTY опре¬ деляет номер терминала, с которого вы вошли в систему, а колонка TIME — сум¬ марное время выполнения процесса. Наконец, в колонке CMD представлены об¬ рабатываемые в текущий момент команды. (В данном примере -sh соответствует интерпретатору shell.) Если вы не обнаруживаете в списке номер своего фоново¬ го процесса, он может быть уже завершен. Если вы вызываете команду ps с опцией а, выводится информация обо всех активных процессах в системе, что показано в следующем примере: $| ps -а PID TTY TIME CMD 36 со 0:07 -sh 386 02 0:02 ps 37 $ _ 02 0:12 -sh Как вы можете увидеть, ваш текущий терминал (с номером 02) имеет дело с двумя процессами: ps -а и -sh, а терминал со (консоль) не занят (-sh). Чтобы получить более подробную информацию об активных процессах, в ко¬ манду ps следует включить опцию /, например: $ ps -al F S UID PID PPID CPU 1 s 0 36 1 0 1 s 203 37 1 0 1 s 0 367 1 0 1 s 0 368 1 0 1 s 203 283 37 0 1 $ R 12 421 37 117 PRI N1 СЕ ADDR SZ WCHAN 28 20 67 16 5a20 30 20 49 16 6fd4 28 20 9b 16 193e 28 20 80 16 1970 30 20 96 44 703а 59 20 66 28 TTY TIME CMD со 0:07 -sh 00 0:13 -sh 01 0:01 - 2 02 0:01 - 2 00 0:01 cc screen.c 00 0:08 ps -aL Ниже мы обсудим только те параметры, которые входят в круг вопросов, рас¬ сматриваемых в книге. • В колонке F выводится флаг процессов: 01 — в оперативной памяти 02 — системный процесс
Программирование на языке shell системы Юникс 279 04 — процесс заблокирован в оперативной памяти 10 — процесс вытеснен на диск (подвергнут свопингу) 20 — процесс находится под управлением другого процесса. • В колонке S выводится состояние процесса: 5 — процесс задержан Я — процесс выполняется W — процесс ожидает завершения другого процесса. • В колонке UID выводится идентификатор пользователя ID. Ваш идентификатор указывается для всех процессов, вызванных с вашего терминала. В некоторых системах вместо ID выводится имя пользователя. • В колонке PPID выводится номер родительского процесса. Из приведенного примера видно, что процесс с номером 37 является родителем процессов с номе¬ рами 283 и 421. • В колонке PRI выводится приоритет процесса, вычисленый по значению пере¬ менной NICE. Большее число означает более низкий приоритет. • В колонке A//CE, как сказано выше, выводится значение, которое используется для вычисления приоритета процесса. Это значение можно увеличить с помощью команды nice, рассматриваемой в следующем разделе. • В колонке SZ (SIZE) выводится объем занимаемой оперативной памяти текущего процесса. • В колонке WCHAN, которая связана с колонкой F, выводится имя события, до возникновения которого процесс задержан, что в примере определяется значени¬ ем флага S в колонке S. Для активного процесса значением WCHAN является пробел. • В колонке TIME выводится суммарное время выполнения процесса. Приоритет процесса nice Система Юникс является многопользовательской мультизадачной системой, т. e. в любой момент времени в систему могут входить несколько пользователей и каждый из них может одновременно вызывать более одного процесса. Посколь¬ ку время процессора должно разделяться между активными процессами, любой процесс, имеющий более высокий приоритет, будет получать больше процессор¬ ного времени. Когда процессы запускаются первый раз, все они начинают выпол¬ няться с одного и того же уровня приоритета. Однако это подразумевает, что каждый процесс получает одинаковую «долю внимания» центрального процессо¬ ра и часто может приводить к замедлению работы системы в целом. Чтобы избе¬ жать этого, для назначения менее важным процессам более низкого прйоритета планирования можно воспользоваться командой nice (установить пониженный приоритет). Например: F S UID PID PPID CPU 1 S 203 30 1 0 1 S 0 31 1 0 1 S 203 212 30 50 1 R 12 217 30 161 $ PRI NICE 30 28 30 30 65 44 6ff6 62 20 8e 28 CMD cc 0:09 -sh 00 0:01 - 2 со 0:01 cc screen.c со 0:09 ps -al ADDR SZ WCHAN TTY TIME 20 44 16 6f4c 20 49 16 190с
280 Часть V В случае отсутствия аргумента команда nice увеличивает числовое значение приоритета на 10 (что понижает его приоритет). Вот почему вы видите 30 в треть¬ ей строке колонки NICE (строка для команды cc screen.c с идентификатором про¬ цесса, равным 212). Если вам необходимо задать число, отличное от 10, в качест¬ ве аргумента команды nice можете взять любое значение в диапазоне от 1 до 19. Например, увеличить числовое значение приоритета для cc program.c на 12 мож¬ но с помощью командной строки: $ $ nice -12 cc program.c & При этом устанавливается значение NICE, равное 32 (20+12). Назначить про¬ цессу значение NICE, меньшее 20, может только привилегированный пользова¬ тель (в результате чего приоритет процесса повышается), поскольку команда nice позволяет такому пользователю задавать отрицательные аргументы, как, напри¬ мер, в следующем примере: $|nice —10 cc screen.c & 285 $ Эта команда назначает процессу с номером 285 числовое значение приорите¬ та, равное 10 (более высокий приоритет). Завершение фоновых процессов kill Если вам когда-нибудь придется завершать фоновый процесс (и вы знаете его идентификатор PID), для этого используйте команду kill (уничтожить) со значени¬ ем идентификатора PID в качестве аргумента. Вам уже известно, что интерпрета¬ тор shell выводит идентификатор PID при вызове фонового процесса. Если же вы забыли значение PID, выведите его с помощью команды ps. Предположим, у вас есть фоновый процесс с PID, равным 283, и вы хотите его прекратить. Выпол¬ ните следующую команду: kill 283 Чтобы убедиться, что процесс с номером 283 больше не появляется, опять можно использовать команду ps. Если же его номер появляется в результате выполне¬ ния команды ps, этот процесс не прекратился. Для гарантированного прекраще¬ ния процесса в команде kill укажите опциюЭ, например: $ kill -9 283 Сигнал прекращения, создаваемый командой kill -9, не может быть перехва¬ чен или игнорирован указанным в этой команде процессом. Если вы применяете команду kill с опцией 9, а аргумент равен 0 или номеру процесса при вашем входе в систему, вы сами себя выведете из системы. Если у вас нет статуса привилеги¬ рованного пользователя, вы имеете возможность прекращать только процессы, связанные с вашим терминалом. Связи между процессами Одно из преимуществ использования системы Юникс состоит в том, что вам предоставляется достаточно большое число различных способов установления связи между процессами. Ниже рассмотрены три способа.
Программирование на языке shell системы Юникс 281 Конвейеры Конвейер — это механизм, который позволяет связывать два процесса путем ис¬ пользования вывода одного в качестве ввода другого. В командной строке кон¬ вейер обозначается вертикальной чертой I. Например, чтобы подсчитать число файлов в текущем каталоге, используйте следующую команду: $ 20 $ ls -1 1 wc -L Команда Is -I формирует в длинном формате список имен всех файлов теку¬ щего каталога, причем каждое имя файла на отдельной строке. Команда wc -I подсчитает число строк в выводе команды Is -I и выдаст результат на экран (в данном случае 20). Для объединения двух этих команд интерпретатор shell вы¬ зовет функциюр/ре (рис. 22.1). Стандартный ls-l ► вывод 0 Стандартный Рис. 22.1. Конвейер. Вывод команды Is -I становится вводом для команды wc, что эквивалентно следующей последовательности команд: Ls -1 > tempfile; wc -1 < tempfiLe; rm tempfiLe 20 $ Преимуществом конвейера является то, что временный файл tempfile стано¬ вится ненужным. С помощью конвейера можно объединять и более двух команд, например: Ls -L | grep text | Lpr Эта последовательность включенных в конвейер команд выводит на печать имена файлов, содержащих шаблон text. Конвейер может связывать только стандартный вывод одной команды со стандартным вводом другой команды. Так же как не имеет смысла пытаться сое¬ динить закрытые концы двух труб, так не имеет смысла связывать процесс, не имеющий стандартного вывода, с процессом без стандартного ввода. Некоторые команды, такие, как mall и lpr, используют стандартные ввод и вывод не так, как другие команды. Если вы попытаетесь применить команду lpr в левой части кон¬ вейера, то не получите результат на его выходе. Программы фильтрации Большинство команд системы Юникс читает со стандартного ввода и затем обра¬ батывает данные перед их передачей на стандартный вывод. Эти команды, та¬ кие, как grep, sort, spell и diff, называются программами фильтрации (или просто фильтрами). Как фильтр команда grep отыскивает строки входного файла, соде¬ ржащие шаблон1), например: Ls -1 grep intro з 1)Здесь термин «шаблон» используется как эквивалентный термину «цепочка символов для организации поиска». — Прим. ред.
282 Часть V Здесь команда grep берет вывод команды Is -I и выделяет для вывода на экран только строки, содержащие intro. В этом смысле команда grep «процеживает» строки текста, пропуская одни и задерживая другие. Некоторые команды не мо¬ гут рассматриваться как фильтры, например, команды Is, kill и mail. Дублирование стандартного вывода Команда tee позволяет просматривать данные на экране во время их записи в файл. Если ввести команду ls -L | tee dfi Le $ то все имена файлов текущего каталога будут записаны в файл dfile, а также вы¬ ведены на экран (рис. 22.2). Поскольку данные посылаются и на терминал (т. e. на стандартный вывод), для обработки этого вывода можно использовать конвейер, например (рис. 22.3): $1 Ls -L | tee dfiLe | wc -1 20 $ Рис. 22.2. Дублирование стандартного вывода. Рис. 22.3. Дублирование стандартного вывода с конвейером. Задание директив интерпретатору shell Группирование команд Для ввода и выполнения сгруппированных с помощью круглых скобок команд ин¬ терпретатор shell создает субинтерпретатор subshell, который запускает заклю¬ ченные в скобки команды, не изменяя значений переменных основного интерпре¬ татора shell. Эта возможность позволяет пользователю, например, перейти в дру¬ гой каталог, выполнить несколько команд, а затем автоматически вернуться в те¬ кущий рабочий каталог. Если вашим текущим каталогом является начальный ка¬ талог, вы можете выполнить командную строку (cd /usr/james/man.spec; nohup nroff doc1 | lpr &)
Программирование на языке shell системы Юникс 283 которая эквивалентна следующей строке: cd /usr/james/man.spec; nohup nroff doc1 | lpr & ; cd Круглые скобки могут указываться в любом месте командной строки. Если ин¬ терпретатор shell ожидает правую круглую скобку, но не находит ее до конца командной строки, он выведет вторичную подсказку (PS2) для указания вам, что он ожидает от вас продолжения ввода. Группирование списка команд внутри фигурных скобок предписывает интер¬ претатору shell читать и выполнять заключенные в скобки команды, которые со¬ здают объединенный вывод. Этот метод позволяет использовать вывод несколь¬ ких команд как вход другой команды, например: { nroff -mm text1; nroff -mm text2; > | col | Lpr В отличие от круглых скобок фигурные скобки должны быть отделены пробе¬ лами от команд, которые они содержат. Кодом завершения набора команд, сгруп¬ пированных с помощью круглых или фигурных скобок, является код завершения последней команды, выполненной в этом наборе. Условное выполнение Интерпретатор shell позволяет вызывать список команд в зависимости от выпол¬ нения условий. Списком команд является одна или несколько команд, разделен¬ ных точкой с запятой, например: Ls -l; who -rw-r—i— 1 john -rwxr-xr-x 1 john -rwxr-xr-x 1 john john tty20 $ 27832 Jan 12 16:09 fiLe1 5358 Jan 15 14:16 file2 13993 Feb 16 14:04 file3 Feb 16 11:34 Интерпретатор shell сначала вызывает команду Is -I, а затем, когда она заверше¬ на, команду who. Если объединить две команды с помощью оператора AND-IF (& &) или операто¬ ра OR-IF (II), можно использовать дополнительные возможности интерпретатора shell. Оператор OR-IF имеет следующий формат: command1 |[ command2 Интерпретатор shell вызывает command1 и проверяет код ее завершения. Если command1 не выполняется, код ее завершения будет ненулевым, и интерпретатор вызовет command2. Например: [Создание каталога sample] [Удаление каталога sample] [Удаление каталога sample] fai Lure $ mkdi r sampLe $ rmdi r sampLe > $ rmdi r sampLe > /dev/nu L L /dev/nuL L и и echo fai Lure echo fai Lure $
284 Часть V При выполнении второй командной строки сообщение не выводится потому, что команда удаления каталога (rmdir sample) завершается успешно. Однако при вы¬ полнении третьей командной строки сообщение выводится. Поскольку каталог уже был удален как результат работы второй командной строки, команда rmdir sample завершается аварийно (не может быть выполнена) и интерпретатор вы¬ полняет команду echo failure. Оператор AND-IF имеет формат: $ $ В этом случае command2 будет вызвана только тогда, когда command1 заверша¬ ется $ $ Команда test -f .profile проверяет, есть ли файл .profile в текущем каталоге. (Подробно команда test описывается в гл. 24.) Если вы выполняете данную ко¬ мандную строку, находясь в своем начальном каталоге, в котором содержится файл .profile, интерпретатор shell создаст копию этого файла с именем backup. Если же вы вызываете командную строку, находясь в одном из своих подкатало¬ гов (который не содержит файл .profile), копия не будет создана. успешно. Например: » test -f .profile && cp .profile backup command1 && command2 Генерация имен Интерпретатор shell имеет средства для генерации собственного списка имен файлов, которые используют регулярное выражение1), задаваемое в качестве ар¬ гумента. Например: $ | ls -1 *7c Эта команда заставит интерпретатор shell генерировать список имен файлов, ко¬ торые заканчиваются на с, чтобы использовать их в качестве аргументов этой команды (т. e. подлежащих включению в список). Символы, подобные * и опреде¬ ляющие способ генерации имен файлов, иногда называются метасимволами. К ним относятся: * Генерация любой строки имени произвольной длины ? Генерация любого единственного символа [] Генерация любых символов из заданного набора Например, по команде lpr * выбираются все имена файлов в текущем каталоге, за исключением тех, которые начинаются с точки, например .profile. Команда ls -1 tabcd]* выбирает все имена в текущем каталоге, которые начинаются на а, Ь, с или d. 1) В литературе употребляются также эквивалентные термины «шаблон», «модель». — Прим. ред.
Программирование на языке shell системы Юникс 285 Команда Ls -1 [a-z]* выбирает все имена в текущем каталоге, которые начинаются на любую букву ла¬ тинского алфавита. Команда ls -1 ch??k выбирает в текущем каталоге имена из пяти букв, которые начинаются с ch и за¬ канчиваются на к, например check, chick, ch12k и т. д. Поскольку метасимволы и некоторые другие символы имеют для интерпрета¬ тора shell специальное назначение, они никогда не должны применяться в имени файла или каталога. К таким символам относятся: < •> >> * ? & i п Если же вы пытаетесь применить эти символы в имени, то скорее можете со¬ здать трудности интерпретатору shell при их интерпретации, чем заставите его рассматривать их как аргументы. Например, пусть у вас есть файл с именем files1. Если вы попытаетесь изменить его имя на///е?7, то произойдет следующее: $ynv fi les1 fi 1е?1 mv: $ files1 and files1 are identical Почему? Поскольку вопросительный знак является метасимволом, под ним под¬ разумевается любой отдельный символ. Теперь попытайтесь изменить имя того же файла: $ mv files1 file&1 148 1: not found $ Как вы можете видеть, интерпретатор shelj рассматривает знак амперсанда & как специальный символ запуска фонового процесса, изменяющего имя files1 на file, затем он отвечает, что не может найти команду с именем 1 (один). (Интерпре¬ тируя знак амперсанда & как требование на запуск фонового процесса, интерпре¬ татор shell считает, что знак 1 является следующей командой.) Краткое изложение главы 22 В этой главе вы ознакомились с интерпретатором shell системы Юникс. Были рассмотрены фоновые команды, связывание процессов с помощью конвейеров, фильтров и дублирования стандартного вывода, вопросы группирования ко¬ манд, их условного выполнения и генерации имен файлов. Фоновые команды Интерпретатор shell позволяет запускать с терминала несколько процессов. Если вы добавляете в конце командной строки знак амперсанда &, интерпретатор shell выполняет командную строку как фоновый процесс, тем самым позволяя сразу же вводить следующую команду, не дожидаясь завершения первой. Интер¬
286 Часть V претатор shell выведет идентификационный номер процесса, который вы мо¬ жете использовать для управления процессом. Чтобы сделать процесс невосприимчивым к прерыванию и сигналам заверше¬ ния, командную строку начинайте командой nohup (no hangup — с защитой от прерываний). Контроль Фоновых ПРОЦЕССОВ. Для контроля фоновых процессов используйте команду ps (process status — состояние процесса). Если использовать команду ps без аргументов, на экран будет выведена информация в четыре колонки со сле¬ дующими заголовками: Если в команде ps вы добавите аргумент -I, получите десять дополнитель¬ ных колонок (некоторые из них в книге не рассматриваются). ПРИОРИТЕТ ПРОЦЕССОВ. Одна из 14 колонок, выводимых по команде ps, называ¬ ется NICE и указывает уровень приоритета каждого процесса. Приоритет процес¬ са можно уменьшать, вставляя в начале командной строки команду nice. ЗАВЕРШЕНИЕ Фоновых ПРОЦЕССОВ. Чтобы завершить фоновый процесс, исполь¬ зуйте команду kill с идентификатором процесса. Рассмотрены три способа установления связей между процессами: КонвЕйЕРЫ. Конвейер позволяет связывать стандартный вывод одного процес¬ са со стандартным вводом другого. Символом для обозначения конвейера явля¬ ется вертикальная черта I. фильтры. Некоторые команды системы Юникс читают данные со стандартно¬ го ввода и затем выбирают некоторую их часть для передачи на стандартный вывод. Эти команды (например, команды grep, sort, spell и diff) называются про¬ граммами фильтрации (или фильтрами). Входные данные они часто получают че¬ рез конвейер. ДУБЛИРОВАНИЕ стАндАРТного выводА. Команда tee, которая позволяет просмат¬ ривать на экране данные в процессе их записи в файл, используется совместно с конвейером. ГРУППИРОВАНИЕ комАНД. Группирование команд внутри круглых скобок заставит ин¬ терпретатор shell при вводе и выполнении этих команд создавать субинтерпрета¬ тор subshell. Используя эту возможность, вы можете перейти в другой каталог, выполнить несколько команд и затем вернуться в свой текущий каталог. Группирование команд внутри фигурных скобок заставит интерпретатор shell ввести и выполнить заключенные в эти скобки команды. Этот метод позволяет использовать вывод нескольких команд как вход некоторой другой команды. УсловноЕ выполнЕНИЕ. Список команд — последовательность команд, разделя¬ емых точкой с запятой. Список команд можно вызывать в соответствии с выпол¬ нением некоторого условия. Конструкция OR-IF предписывает интерпретатору shell вызвать вторую коман¬ ду только тогда, когда первая не выполняется нормально, например: PID TTY TIME CMD Идентификатор процесса Номер терминала Суммарное время выполнения Имя команды Связи между процессами Задание директив интерпретатору shell $ command 1 || command 2
Программирование на языке shell системы Юникс 287 Конструкция AND-IF предписывает интерпретатору shell вызвать вторую ко¬ манду только в том случае, если первая завершилась успешно, например: $ command 1 && command 2 ГЕНЕРАЦия имЕН ФАйлов. Интерпретатор shell может использовать для генера¬ ции имен при выборе имен файлов следующие метасимволы: * Генерация любой строки имени произвольной длины ? Генерация любого единственного символа [] Генерация любых символов из заданного набора Глава 23. Переменные интерпретатора B-shell В главах 21 и 22 вы узнали, каким образом интерпретатор shell обрабатывает ко¬ манду, введенную с терминала. Эту главу мы начнем с рассмотрения процедур интерпретатора shell, а затем обсудим подстановку результатов выполнения ко¬ манд. Процедуры интерпретатора shell Shell-файл (известный так же как shell-процедура или shell-сценарий) содержит одну или несколько команд интерпретатора shell, подлежащих выполнению одна за другой, когда имя файла используется как имя команды. Наличие такого фай¬ ла позволяет вам создавать свои собственные команды. Например, пусть имеет¬ ся алгоритм, который подсчитывает число символов в файле из текущего катало¬ га. Ниже показано, как создать соответствующий файл с помощью редактора: ed: [Получение списка имен файлов и его передача команде wc —с] Теперь у вас есть простой командный файл с именем counter, который может быть вызван командой sh (shell). Эта команда вводит содержимое файла- аргумента counter и выполняет входящие в него команды: $ sh counter 20 $ [Число символов файла counter] В данном случае ваш файл содержит одну командную строку, но исполнить ее непосредственно нельзя. Следующий шаг — с помощью команды chmod (change mode — изменить режим) (гл. 3) изменить способ выполнения файла:
288 Часть V $ $ chmod u+x counter [Установка файла counter выполняемым] Теперь, чтобы вызвать counter как полноправную команду, вам не надо ис¬ пользовать команду sh, а следует просто ввести counter таким же образом, как вы вводите имя любой стандартной команды системы Юникс. Последний шаг состоит в перемещении counter в ваш каталог bin, в котором находятся ваши команды, и добавлении $HOME/bin к значению вашей перемен¬ ной PATH. Если вы пропустите этот шаг, команду counter сможете выполнять только тогда, когда будете находиться в том же каталоге, что и она. В противном случае вы должны задавать полное составное имя типа lusr/john/newcomd/counter или $HOME/bin/counter. Вспомогатепьные команды Прежде чем перейти к разделу переменных интерпретатора shell, рассмотрим команды echo и read, которые используются ниже в качестве примеров. Команда echo echo Команда echo (эхо) в качестве аргумента использует цепочку символов, которая завершается знаком новой строки \п, и направляет ее на стандартный вывод (ваш терминал). Чаще всего команда echo используется в shell-процедуре для вывода сообщений на экран, например: $1 echo This is а message This is а message $ Единственной опцией команды echo является -n, по которой из выводимой строки исключается знак перехода на новую строку. Это позволяет на одной строке помещать одно сообщение за другим, например: $ echo -n This is а message This is а message$ Обратите внимание, что знак-подсказка $ находится в конце сообщения, а не на следующей строке. В shell-программах опция -n часто используется для указания пользователю о необходимости ввода. Пусть, например, имеется shell-файл с именем getkey, который содержит следующие две строки: $| cat getkey echo -n 'Please press any key, read inkey $ then <cr> to continue:1 Для создания такого файла выполните действия, указанные в начале этой главы (Процедуры интерпретатора shell). Создав таким образом однажды файл, дальше вы его вызываете как команду системы Юникс: $ getkey Please press any key, then <cr> to continue: __ Теперь программа ожидает от вас ввода с клавиатуры. Любой вводимый с клавиатуры символ будет отображаться на месте курсора. Как только вы нажме-
Программирование на языке she!l системы Юникс 289 те RETURN, программа завершится и на следующей строке появится знак- подсказка. Это означает, что команда read ожидает нажатия клавиши RETURN в конце вводимой цепочки символов. Команда read read Команда read (читать) вводит строку со стандартного ввода и назначает первому слову первое имя, второму слову — второе и т. д.1) Если в команде указано только одно имя, то команда read назначает это имя всей строке. В файледеМеу команда read присваивает переменной inkey в качестве ее зна¬ чения строку символов, вводимую вами с клавиатуры. Если после ввода с клави¬ атуры вы хотите отобразить введенную информацию на экране, добавьте в кон¬ це файла getkey еще одну команду echo, например: $|cat getkey echo -n *Please press any key, then <cr> to continue: read inkey echo $inkey $ [Дополнительная строка] Теперь, когда вы вызываете программу getkey, а затем вводите слово KEYBOARD и нажимаете клавишу RETURN, на экране вы увидите следующее: $[ getkey PLease press any key, then <cr> to continue: [Здесь набирайте KEYBOARD] KEYBOARD [Программа getkey повторяет его на экране] $ _ В гл. 24 приведены примеры использования команд echo и read в shell- файлах. Переменные интерпретатора shell Переменные интерпретатора shell (или shell-переменные) предоставляют интер¬ претатору основную информацию и могут быть установлены как им самим, так и пользователем. С некоторыми из shell-переменных вы уже ознакомились в гл. 21. Обычно интерпретатор shell устанавливает значения переменных по умолчанию, а пользователь по своему усмотрению может затем присвоить им новые значе¬ ния. Имя переменной может быть любой последовательностью букв, цифр и сим¬ волов подчеркивания, но всегда должно начинаться с буквы или символа под¬ черкивания. Для присваивания значения shell-переменной используется знак ра¬ венства = без пробелов с обеих от него сторон. Ниже в этой главе рассмотрены дополнительные правила и ограничения. Присваивание значений переменным Ниже показано, как осуществляется присваивание значения STRING переменной с именем VARIABLE: $ VARIABLE=STRING 1)Строка разбивается на слова. Каждое слово записывается в свою собственную пере¬ менную с собственным именем. Имена переменных указываются в качестве аргументов в команде read. — Прим. ред. 10-771
290 Часть V Чтобы обратиться к значению переменной, перед ее именем следует поста¬ вить знак доллара $. С помощью команды echo легко проверить значение пере¬ менной: $ echo $VARIABLE STRIN6 $ Как показано ниже, в операторе присваивания можно присваивать значения нескольким переменным. Обратите внимание на пробелы между отдельными присваиваниями значений переменным: $ a=T b=H c=I d=S $ echo $a$b$c$d THIS $ [Присвоение значений нескольким переменным] [Вывод переменных,которым присвоены значения] В следующем примере переменнойЬ присваивается значение переменнойа, в результате чего переменные а и b приобретают одинаковые значения: [Присвоение а значения, равного 723] [Присвоение b значения переменной а] [Отображение значений обеих переменных с пробелом между ними] 123 123 [Выведенные значения а и b] $ $ a=123 $ b=$a $ echo $a $b Чтобы получить тот же результат, можно объединить приведенные выше опе¬ раторы в один более сложный оператор: $ z=$y у=123 $ echo $z $y 123 123 $ [Установка z равной у (723)] [Вывод обоих значений через пробел] [Оба выведенных значения] Поскольку интерпретатор shell присваивает значения переменным справа на¬ лево (а не наоборот), нужно быть внимательным при использовании операторов, в которых осуществляется присваивание значений нескольким переменным, как в только что приведенном примере. Поэтому в примере, приведенном ниже, ин¬ терпретатор shell присваиваетг предшествующее значение переменной у (123), а не новое значение abc, как ожидает пользователь: $ y=abc z=$y $ echo $z 123 $ | echo $y | abc $ [Присвоение z значения 723, а не аЬс] [Вывод 723 как значения z] [Однако вывод аЬс как значения у] Присваивание значений переменным часто используется в shell-процедурах. Однако это действие может быть полезным и при обычном взаимодействии с ин¬ терпретатором shell. Например, вместо длинных имен команд, аргументов и имен
Программирование на языке shell системы Юникс 291 файлов можно использовать переменные, сокращая при этом процесс набора на клавиатуре. В следующем примере интерпретатор shell присваивает переменной HERE длинное составное имя: $ HERE=/usr/james/selection/car/camaro Теперь можно ввести команду $ cd $HERE и получить тот же результат, что и при наборе команды cd /usr/j ames/seLecti on/car7camaro В примере, приведенном ниже, для обозначения длинной командной строки со многими опциями nroff -h -rTI -T450 -mm <file> мы будем использовать переменную form. Присвоим переменной form значение этой командной строки (здесь требуются апострофы из-за наличия пробелов между отдельными аргумен¬ тами): $ form='nroff -h -rTl -T450 -mm' ^ Теперь при каждом выполнении команды вместо ее полного набора на клави¬ атуре можно вводить, например, следующее: Использование кавычек До сих пор мы рассматривали присваивание переменным простых значений, ко¬ торые не содержали пробелов, знаков табуляции, точек с запятыми и знаков но¬ вой строки. При появлении одного из этих знаков в значении, присваиваемом пе¬ ременной, мы должны заключить присваиваемое значение (в правой части) в апострофы ’, например: $ $ This string has both; semicolon and space $ string='This string has both; semicolon and space' echo $string Если вы не заключите присваиваемое выше значение в апострофы, на экране появится сообщение об ошибке. Но, если вам необходимо включить в присваивае¬ мую строку значение переменной, следует использовать двойные кавычки (“ ”). Это заставит интерпретатор shell отыскивать и включать в присваиваемую стро¬ ку значения входящих в нее переменных, а не их имена: $ $ $ This $ S=space M=semicolon string=" This includes both; $S and $M echo $string includes both; space and semicolon 10*
292 Часть V Кроме того, три специальных символа $, ‘ и “ будут сохранять свой специаль¬ ный смысл, если содержащие их строки заключаются в двойные кавычки; но, ес¬ ли они заключаются в апострофы, интерпретатор shell будет их рассматривать как обычные символы, например: string=' This string has three; $S,", echo $string $ $ This string has three; $S, "/[Значениепеременнойневыводится] $ Получение значения в командной строке eval С помощью команды eval (evaluate — оценивать) интерпретатор shell можно заста¬ вить повторно сканировать строку. Команда eval осуществляет повторный про¬ смотр аргументов команды, чтобы либо выполнить команду, либо заменить име¬ на переменных их значениями, например: a=1234 b=*$a* eval echo $a $b $ $ $ 1234 1234 $|echo $a $b 1234 $a $ [Присвоение a значения 1234] [Присвоение b значения переменной a] [Повторно сканировать строку и подставить значение для b] [Команда echo без замены переменной ее значением] Достоинство повторного сканирования командной строки состоит в том, что до выполнения этой строки можно подставить вместо имен переменных их зна¬ чения, например1): peek=finger port=1 >/dev/tty01' eva 1 $peek $port $ $ $ finger >/dev/tty01 $ [Присвоение peek значения finger] [Присвоение port значения в апострофах] [Вывод обеих переменных] Команда eval создает такой вид приведенного выше оператора для интерпре¬ татора shell, как будто вы набрали следующую строку: finger >/dev/tty01 Конечно, вы могли всю командную строку установить в качестве значения од¬ ной переменной и без команды eval, но эта команда, когда в этом есть необходи¬ мость, обеспечивает большую гибкость. Выделение имени переменной Как вы уже видели, значение, присваиваемое переменной, может быть значением другой переменной. Кроме того, значение переменной можно использовать для определения этой переменной, например: 1) В приведенном примере после команды eval должна быть команда echo. — Прим. ред.
Программирование на языке shell системы Юникс 293 [Присвоение word значения character] [Использование word при собственном задании] metacharacter $ _ Если вы попытаетесь приписать дополнительные символы к концу имени пе¬ ременной, например: $ $ $ $ то интерпретатор shell присвоит переменной TV значение пустой строки, посколь¬ ку он не может найти переменную с именем farvision. Решить данную проблему можно, если заключить имя переменной в фигурные скобки: $ $ television $ _ Те переменные, которые по вашему желанию должны автоматически инициа¬ лизироваться при каждом вашем входе в систему, вы можете включить в свой файл .profile. Для облегчения чтения имен переменных используйте прописные буквы. TV=*C$far>vi sion echo $TV far=tele TV=$farvision echo $TV $ word=character $ word=meta$word echo $word Подстановка результатов выполнения команд Интерпретатор shell позволяет устанавливать результаты выполнения вызыва¬ емой команды в качестве значения переменной, если заключить эту команду в знаки ударения (чкомандная строка4 ), например: $ fnames= 'ls' [Присвоение fnames результата команды ls] По этой команде интерпретатор shell вызовет команду Is, присваивая резуль¬ таты работы этой команды переменной fnames^. Предположим, что в текущем ка¬ талоге находятся четыре файла с именами file 7, file 2, file 3 и file 4. Исполь¬ зуя для вывода значения переменной fnames команду echo, вы увидите на экра¬ не: $ echo $fnames file 1 file 2 file 3 file 4 $ 11) Напомним, что результатом работы команды Is будет список имен файлов в текущем каталоге. — Прим. ред.
294 Часть V Подстановку результатов выполнения команд можно использовать только с командами, имеющими стандартный вывод. Поскольку команда lpr выводит не на стандартный вывод, следует избегать, например, такой команды: $ VAL= Lpr file1 [Не рекомендуется] Выходная информация команды lpr file1 посылается на печать, а переменной VAL присваивается пустое значение. Подстановки результатов выполнения команд часто полезны в shell-файлах, например: [Получение текущего каталога] [Переход в другой каталог] [Действия в этом каталоге] [Возврат в первоначальный каталог] Переменная CURRENT используется для сохранения составного имени текущего каталога, пока в другом каталоге выполняется некоторая задача. Последний опе¬ ратор позволяет вам вернуться к первоначальному каталогу, не утруждая себя за¬ полнением его имени. CURRENT= 'pwd 4 cd /usr/dennis/plan/goal $ cd $CURRENT Вычисление арифметических выражений Команда expr (express — выражать) рассматривает свои аргументы как выраже¬ ние (арифметическое или логическое). Результат вычисления такого выражения передается на стандартный вывод. С командой expr могут использоваться следу¬ ющие арифметические операции: + сложение - вычитание * умножение / деление % взятие остатка Поскольку команда expr трактует каждую операцию или значение как отдель¬ ный аргумент, их необходимо отделять друг от друга пробелами. Чтобы предот¬ вратить интерпретацию метасимволов (например, *, &, ?, Л, []), вы должны отме¬ нить специальный смысл, заключая их в апострофы (например, ’*’) или двойные кавычки (“*”) или устанавливая перед ними знак обратной косой черты \. В чет¬ вертой строке последующего примера специальный смысл символа звездочки * отменяется с помощью апострофов. [Установка начального значения ау равного 2] [Добавление к а числа 7 и присвоение а результата] [Деление значения а на 2 (9/3 = 3) и присвоение результата b] [Умножение а - 1 на b (8 x 3 = 24) и присвоение результата с] [Деление с на 5 (24%5) и присвоение остатка d] [Вычитание b из d(4-3)и присвоение результата e]
Программирование на языке shell системы Юникс 295 Результат присваивается переменной e. Проверим все значения: $lecho $a $b $c $d $e 9 3 24 4 1 $ Сравнение цепочек символов expr Команда expr с помощью операции сопоставления, обозначаемой двоеточием :, позволяет сравнивать цепочки символов. Результатом выполнения такой коман¬ ды является число совпадающих символов в обеих цепочках символов. Если ре¬ зультат равен 0, совпадение отсутствует. Например: [Сопоставление двух цепочек символов и присвоение результата переменной^] [Вывод значения переменной R] Схема сопоставления цепочек символов команды expr такая же, как и в ре¬ дакторе ed, т. e. вторая цепочка символов сопоставляется с первой, начиная с первого символа. Поэтому даже один несовпадающий символ во второй цепочке приведет к неудачному сопоставлению, вследствие чего в качестве результата устанавливается 0, что показано в трех последующих примерах: [Отсутствие d во второй цепочке] [Отсутствие a во второй цепочке] [Вторая цепочка символов длиннее первой] [Все три сопоставления неудачны] Такое же сравнение можно выполнить и с использованием переменных, на¬ пример: $ C='expr $M ; $H Учитывая возможность команды expr сопоставлять цепочки символов и свой¬ ство интерпретатора shell генерировать имена, сравнение цепочек символов можно использовать для определения длины цепочки. Давайте присвоим пере¬ менной А цепочку символов, а затем подсчитаем число символов в цепочке: A=*This is an experiment1 [Присвоение цепочки символов переменной А ] Поскольку переменная А является цепочкой символов, внутри которой есть пробелы, в приведенном выше примере она должна быть заключена в двойные кавычки; в противном случае будет выдано сообщение о синтаксической ошибке. Чтобы указать интерпретатору shell на специальный смысл звездочки *, второй аргумент заключается в апострофы: $ count='expr $A : 1.** $lecho $count 2' [Обратите внимание на звездочку * ] [Вывод значения count] [Длина цепочки символов]
296 Часть V Другой возможностью команды expr является ее способность выделять толь¬ ко часть цепочки символов, например: B= expr $A : 1 \(.*\)' Пять точек перед знаком \ соответствуют пяти символам, которые следует про¬ пустить (включая пробел) с начала цепочки символов. Теперь, если отобразить значение переменной В на экране, получим $ echo $B is an experiment $ [Первые пять символов пропущены] Перед обработкой команда expr проверяет операторы на наличие ошибок. Ни¬ же приведены некоторые возможные ошибки: • Синтаксическая ошибка будет фиксироваться всегда, когда пропущен или недо¬ пустим оператор или операнд. • Если вы пытаетесь применить арифметическую операцию к символу или цепоч¬ ке символов, будет выведено сообщение: нечисловой аргумент. Условная замена переменных Вы можете проверить, присвоено или не присвоено переменной значение. Если переменной было присвоено значение, вы можете либо использовать это значе¬ ние в выражении, либо заменить его на другое. Эта процедура называется услов¬ ной заменой переменных. Интерпретатор shell реализует четыре варианта услов¬ ной замены с помощью четырех символов для указания вида сравнения (-, =, ?, + ): #fVARIABLE-OTHER] Если переменной VARIABLE было присвоено значение, используется это значе¬ ние; в противном случае используется цепочка символов OTHER, а переменная VARIABLE остается без изменения. В приведенном ниже примере мы предполага¬ ем, что значение переменной VAL не установлено, поэтому получаем следующий результат: $Ucho ${VAL-123> 123 [Проверка, установлена ли переменная VAL] [Так как не установлена, используется цепочка символов 123] Ниже рассмотрен подобный пример с переменной (в правой части текста в фи¬ гурных скобках) вместо цепочки символов, которая используется в качестве объ¬ екта для замены: [Присвоение 456 переменной SUB] [Предполагаем,что переменная VAL не установлена] 456 [Вместо значения VAL используется значение SUB] $ SUB=456 $ echo ${VAL-$SUB>
Программирование на языке shell системы Юникс 297 $jVARIABLE = OTHER) Если переменной VARIABLE было присвоено значение, используется это значе¬ ние; в противном случае перед использованием переменной VARIABLE присваи¬ вается значение OTHER, как в следующих примерах: [Переменной VAL не присвоено значение, поэтому ее значением становится xyz] [Теперь переменная VAL имеет значение xyz] xyz $[VARIABLE7EMPTYj Если переменной VARIABLE присвоено значение, используется это значение; в противном случае на экран выводится сообщение VARIABLE: EMPTY, а процедура прекращается. Вновь предположим, что значение переменной VAR не присвоено; тогда получим $ error='variable unset, procedure is aborted' $ echo ${VAR7$error> VAR: variable unset, procedure is aborted $ При отсутствии сообщения справа от знака вопроса выдается стандартное сооб¬ щение, например: $ echo ${VAR7> VAR: $ parameter not set $(VARIABLE+OTHER) Если переменной VARIABLE присвоено значение, используется значение перемен¬ ной OTHER. Если же значение переменной VARIABLE не присвоено, в качестве ее значения используется пустая цепочка символов, при этом переменной VARIABLE значение не присваивается. Например: 123 $ [Присвоение переменной THIS значения 145] [Присвоение переменной77£4Г значенияябс] [Выполнение проверки] [Вывод значения переменной THAT] [Переменная THIS сохраняет значение] Позиционные параметры Для идентификации позиций элементов (или аргументов) в командной строке ин¬ терпретатор shell устанавливает позиционные параметры. Чтобы он мог отличать элементы друг от друга, они должны разделяться пробелами. Интерпретатор
298 Часть V shell идентифицирует элементы командной строки с помощью номеров, начиная с нуля. Первый элемент (имя процедуры интерпретатора shell) всегда обозначает¬ ся как $0; первый аргумент — как $1, второй — как $2 и т. д. до $9, например: $0 $1 $2 ... $9 [Позиционный параметр] $ dlff file 1 file 2 ... file 9 [Командная строка] Присваивание значений позиционным параметрам set Рассмотрим взаимосвязь команды set с позиционными параметрами. Эта коман¬ да часто используется для присваивания позиционному параметру значения це¬ почки символов аргумента, например: $ $ set arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 По этой команде интерпретатор shell присваивает первому позиционному па¬ раметру^ значениearg 1, второму параметру$2 — значениearg 2, третьему пара¬ метру&? — значени earg 3 и т. д. Значения этих аргументов можно проверить, вы¬ ведя их значения на экран: echo $1 $3 $4 $2 $4 $5 $6 $7 $8 $9 arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 $ Доступ к отдельным аргументам Когда команда set применяется одновременно с подстановкой результата выпол¬ нения команды, каждый из элементов вывода при подстановке команды присва¬ ивается отдельному позиционному параметру. Для задания подстановки резуль¬ тата выполнения команды в следующем примере команда date заключена в знаки ударения': $ set date Выход команды date становится последовательностью аргументов для команды set и на экране ничего не появится. Но если вы вызовете саму команду date, то должны увидеть, например, следующее: $l date) Wed Feb 15 21:49:20 1984 $ После вызова команды set 'date' каждый элемент цепочки символов, являющей¬ ся результатом выполнения команды date, присваивается соответствующему по¬ зиционному параметру $1, $2, $3, $4, $5. Если вас интересует только время, то вы можете вывести его следующим образом: $ echo $4 21:49:20 $
Программирование на языке shell системы Юникс 299 Вы можете задать эти элементы и в другом формате: $|echo 'DATE: $1 $2 $3 $5 TIME: $41 DATE: $ Wed Feb 15 1984 TIME: 21:49:20 Доступ к другим позиционным параметрам shift Позиционным параметром с наибольшим номером является $9. Для обращения к аргументам с номерами, большими 9, используется команда shift (сдвигать), кото¬ рая сдвигает аргументы на одну позицию влево. После выполнения этой коман¬ ды позиционный параметр $4 сдвигается на место $3, $3 — на место $2, $2 — на место $1, а $1 исчезает (имя команды в позиции $0 остается, однако, без измене¬ ния). Например: $ _ После такого сдвига arg2 находится в первой позиции, а arg10 — в последней. Генерация номеров аргументов с помощью метасимвола Интерпретатор shell воспринимает звездочку * как метасимвол для генерации номера любого позиционного параметра. Путем ввода следующей команды мож¬ но получить доступ ко всем позиционным параметрам: $lecho $* arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10 arg.11 $ _ Данная команда echo и такая же команда, использованная в предыдущем разде¬ ле, не являются эквивалентными. Предыдущая команда выводит девять парамет¬ ров из позиций с первой по девятую, а данная команда — вплоть до последнего имеющегося позиционного параметра. Передача аргументов команде Перед передачей аргументов вызванной команде интерпретатор shell всегда при¬ сваивает их значения позиционным параметрам. Пусть, например, у вас есть ис¬ полняемый командный файл с именем bounce, который содержит команду echo $1 $3 $5 $2 $4 $6. Если вы вызываете файл с шестью аргументами, то происходит следующее: $|bounce one two three four five six [ one three five two four six $ Как видно из этого примера, выводимая строка отражает порядок аргументов в файле bounce.
300 Часть V Зарезервированные переменные Перечисленные ниже специальные переменные устанавливаются самим интер¬ претатором shell, а не пользователем: # Число АРГУМЕНТОВ. Число позиционных параметров (не считая $0), которые использованы для записи аргументов. Посмотрим, например, какое число аргументов было сохранено интерпретатором shell при выполнении коман¬ ды set: $ set 'date' $ echo $# 5 [Установлено 5 позиционных параметров] $ Код возвРАТА. Код состояния, возвращаемый интерпретатору shell послед¬ ней выполненной командой. В общем случае при успешном выполнении команды возвращается 0; при другом результате выполнения команды — ненулевое значение. echo $? [Код возврата команды echo: успешно] $ ИДЕНТИФИКАЦИОННЫЙ номЕР1) ТЕКУЩЕго ПРОЦЕССА. Поскольку этот номер уни¬ кальный, иногда он используется в качестве временного имени файла, на¬ пример: [Присваивание значения переменной tempfile] [Вывод в переменную tempfile] ! ИДЕНТИФИКАЦИОННЫЙ НОМЕР ФОНОВОГО ПРОЦЕССА, ВЫЗВАННОГО ПОСЛЕДНИМ. ЭТОТ номер сохраняется, даже если процесс завершен. $|echo $! 243 [Номер фонового процесса, вызванного последним] $ tempfile=fi Le$$ sort fi te1 -о $tempfile mv $tempfile file1 — СостояниЕ ФЛАГов интЕРПРЕТАТОРА shell. Эта переменная определяет все те¬ кущие флаги интерпретатора shell, которые могли быть установлены или сброшены командой set. Для проверки текущей установки флагов введите команду: $| echo $- S [Флаг s установлен; все остальные — сброшены] $ _ Эти переменные могут быть установлены только интерпретатором shell. Если вы попытаетесь присвоить этим переменным какое-либо значение, будет выведе¬ 1) Подразумевается числовой идентификатор процесса. — Прим. ред.
Программирование на языке shell системы Юникс 301 но сообщение об ошибке, например: [Попытка вручную присвоить значение переменной #] not found [Выводимое сообщение] $ Краткое изложение главы 23 В этой главе вы ознакомились с процедурами и переменными интерпретатора shell. Вы узнали о присваивании значений переменным интерпретатора shell, ис¬ пользовании апострофов и кавычек, именовании переменных, подстановке ре¬ зультатов выполнения команд, условной замене переменных, позиционных пара¬ метрах и зарезервированных переменных. ПРОЦЕДУРЫ интЕРПРЕТАЮРА SHELL. Чтобы создать shell-процедуру, введите требу¬ емые команды в файл и объявите этот файл выполняемым с помощью команды chmod. ВспомогАТЕльныЕ комАНДы. Команда echo берет цепочку символов аргумента и передает ее на стандартный вывод (отображает на вашем экране). Команда read берет значения со стандартного ввода и присваивает их переменной (или не¬ скольким переменным). ПЕРЕМЕННЫЕ ИНТЕРПРЕТАТОРА SHELL. Переменным интерпретатора shell, как и дру¬ гим используемым в программировании переменным, можно присваивать значе¬ ния. Для вывода значения переменной на экран используйте команду echo со знаком доллара $ перед именем переменной. Для сокращения ввода с клавиату¬ ры вы можете применять shell-переменные. ИспользовАниЕ Апострофов. Для включения в цепочку символов пробелов, зна¬ ков табуляции, знаков точки с запятой и знаков новой строки (но без разрешения замены переменных) используйте апострофы. Чтобы включить в цепочку символов те же знаки и разрешить замену перемен¬ ных, используйте двойные кавычки. ПолучЕНИЕ знАЧЕНия в комАНДНОй строкЕ. Команда eval работает так же, как ко¬ манда echo, за исключением того, что команда eval может взять всю командную строку, вычислить переменные и заменить присвоенные им значения на вычис¬ ленные. ВыдЕЛЕниЕ ИМЕНИ ПЕРЕМЕНной. Чтобы отделить имя переменной от других сим¬ волов, заключите имя в фигурные скобки. ПодстАновкА РЕЗУЛЬТАТОВ выполнЕния комАНД. Чтобы присвоить переменной значения стандартного вывода, полученного в вызванной командной цепочке, за¬ ключите командную цепочку в знаки ударения. ВычислЕНИЕ выРАЖЕНий. Для вычисления арифметических выражений исполь¬ зуйте командуехрг и операции сложения +, вычитания -, умножения *, деления / и взятия остатка (%). СРАВНЕНИЕЦЕПОЧЕКсимволов. Для сравнения двух цепочек символов используй¬ те команду expr со знаком операции сопоставления (:). Результатом будет число совпадающих символов в обеих цепочках символов. Сравнение цепочек символов можно использовать для определения длины це¬ почки (сравнивая цепочку с .*) или выделения части цепочки символов (исполь¬ зуя для каждого исключаемого символа точку и заключая затем .* в скобки \( И \)). УсловнАЯ ЗАМЕНА ПЕРЕМЕННЫХ. Чтобы проверить, присвоено ли переменной зна¬ чение или не присвоено, и затем выполнять свое следующее действие в зависи¬ мости от результата проверки, используйте один из четырех типов выражений: $ #=256 #=256:
302 Часть V ${var-other] ${var = other] ${var7empty] $[var + other] Если переменной маг присвоено значение, используется это значение; если нет, используется значение переменноwother, а переменная маг остается в прежнем состоянии — без значения. Если переменной маг присвоено значение, используется это значение; если нет, переменной маг присваивается значение other. Если переменной маг присвоено значение, используется это значение; если нет, выводится сообщение Mar:empty и процесс прекращается. Если переменной маг присвоено значение, вместо него исполь¬ зуется значение переменной other\ если нет, используется пу¬ стая цепочка символов и переменная маг остается в прежнем состоянии. ПозиционныЕ ПАРАМЕТРЫ. Для сохранения имени команды и ее аргументов ин¬ терпретатор shell устанавливает позиционные параметры, используя $0 для име¬ ни команды, $1 для первого аргумента, $2.для второго и т.д. ПРИСВАИВАНИЕ ЗНАЧЕНИЙ позиционным ПАРАМЕТРАМ. Для присваивания значений позиционным параметрам используйте команду set. Доступ к отдЕЛЬНЫМ АРГУМЕНТАМ. Чтобы выбрать определенный аргумент, ис¬ пользуйте команду set с позиционным параметром в качестве ее аргумента. Доступ к другим позиционным ПАРАМЕТРАМ. Чтобы получить доступ к аргумен¬ там с номерами, большими 9, используйте команду shift. ГЕНЕРАция номЕРОв АРГУМЕНТОВ с помощью МЕТАСимволА. Для генерации номера любого позиционного параметра используйте после знака доллара метасимвол *. ИзмЕНЕНИЕ порядкА АРГУМЕНтов ПЕРЕД выполнЕниЕМ комАнды. Путем установки позиционных параметров в желаемом порядке вы можете изменить порядок аргу¬ ментов, а затем выполнить команду. ЗАРЕЗЕРВИРОВАННЫЕ ПЕРЕМЕННЫЕ интЕРПРЕТАТОРА SHELL. Следующие специальные переменные могут быть установлены только интерпретатором shell, но могут быть использованы и пользователем: # Число аргументов в командной строке ? Код возврата после завершения команды $ PID (идентификатор) текущего процесса ! PID фонового процесса, вызванного последним — Состояние флагов интерпретатора shell Глава 24. Управление программами в языке B-shell В sheU<paHnax (или shell^7poL/e^ypax) интерпретатор shell действует как язык програм¬ мирования. Подобно другим языкам, он имеет следующие средства: • Команды управления (if... then ... else, while, for и т. д.). • Управления прерываниями (trap), присваивания значений переменным и передачи параметров (гл. 23). • Вызовы других команд или shell-процедур как подпрограмм. Так как shell-процедура написана на языке высокого уровня, ее легко модифициро¬ вать. Кроме того, ее не надо компилировать. Поскольку при модификации shell- процедуры не требуется создавать новый объектный файл, ее легче поддерживать.
Программирование на языке shell системы Юникс 303 Интерпретатор shell обладает и средствами для отладки shell-процедуры, которые позволяют контролировать каждый шаг выполнения вашей программы с выдачей со¬ общений об ошибках, когда интерпретатор shell обнаруживает недопустимые выраже¬ ния. В этой главе рассмотрены общие команды управления, команды управления пре¬ рываниями и многие другие особенности программирования на языке shell. Построение циклов При программировании на различных языках общим является наличие повторно выполняемого сегмента программы, в который обычно вносятся некоторые изме¬ нения перед каждым последующим выполнением. Такой сегмент называется про¬ граммным циклом. Данный раздел посвящен различным способам построения цикла при программировании на языке shell системы Юникс. Прежде чем перей¬ ти к рассмотрению самих циклов, обратимся к командам true и false, которые мы будем использовать для упрощения обсуждения команд циклов. Команды true и false true false Когда завершается выполнение какой-то команды системы Юникс, родительско¬ му процессу (вызывающей программе) передается некоторое число (обычно не¬ большое), называемое кодом завершения. По принятому соглашению число, рав¬ ное нулю, обозначается true (успешное выполнение), а число, отличное от нуля, обозначается false (неуспешное завершение). False может иметь несколько значе¬ ний и конкретное значение часто указывает причину, по которой процесс завер¬ шился неуспешно. Для установления требуемого кода завершения интерпретатор shell имеет две команды с именами true и false. По команде true код возврата устанавливается равным true, а по команде false — равным false. Ниже эти ко¬ манды мы будем использовать для того, чтобы иллюстрировать работу некото¬ рых команд, применяемых для построения циклов (команды while и untll). Рас¬ смотрим сами команды true и false: $ $ $ 0 1 $ true;A=$? faLse;B=$? echo $A $B [Получение кода возврата команды true] [Получение кода возврата команды false] [Вывод кода возврата каждой команды] Цикл типа While True while Команда while (пока) образует цикл, который подлежит выполнению до тех пор, пока команда while определяет условие как true, например: whi le <Список команд> do [Выполнение команд между do и done] done Команда while проверяет код возврата списка команд, которым может быть как отдельная команда, так и группа команд. Затем в зависимости от этого зна¬ чения она предпринимает соответствующее действие. Если значение кода воз¬
304 Часть V врата равно 0, все команды между do и done выполняются. Этот процесс продол¬ жается до тех пор, пока команда while не зафиксирует ненулевое значение кода возврата (или не выполнится команда break). В представленном ниже примере команда while никогда не зафиксирует ненулевое значение. Поскольку возврат команды true всегда нулевой, эта программа зациклится: whi le true do echo THIS IS AN ENDLESS LOOP done Чтобы остановить эту программу, нажмите клавишу DEL. Цикл типа until until Формат и действие команды until (до) такие же, как и у команды while, за исклю¬ чением того, что условием входа внутрь цикла является ненулевое значение (false). Следующая программа дает тот же результат, что и программа, использую¬ щая команду while, в предыдущем разделе: unti1 faLse do echo THIS IS AN ENDLESS LOOP done Нажатие клавиши DEL останавливает выполнение программы, как и в случае цикла с командой while. Оператор done закрывает цикл. Вложенные циклы Один программный цикл можно размещать внутри другого, обеспечивая некото¬ рое число повторений внутреннего цикла при каждом повторении внешнего. Та¬ кая структура называется вложенным циклом и иллюстрируется следующим при¬ мером: $ cat Loop out=1 while out='expr $out - 1' do echo out loop $out unti 1 in='expr $in - 1 do echo in loop $in done done Внутренний цикл Внешний цикл Так как переменной out присвоено значение 1, при вычислении выражения $out -1 значение этой переменной уменьшается до 0, т. e. код возврата для опе¬ ратора while равен true. Это вызывает переход к выполнению оператора do внеш¬ него цикла. Поскольку переменная in в результате инициализации получает значение 3, внутренний цикл будет выполняться дважды, пока выражение#/л -1 не умень¬ шит значение переменной in до 0, при котором внутренний цикл завершается и управление передается во внешний цикл. В этот момент в результате вычисления выражения$оц? -1 в заголовке внеш¬ него цикла значение переменной out уменьшается до -1, т. e. становится ненуле¬ вым, что завершает внешний цикл (и программу). Если выполнить файл loop, на экране вы увидите следующее:
Программирование на языке shell системы Юникс 305 $ Loop out loop 0 in loop 2 in Loop 1 $ Прерывание цикла break Команда break (прерывать) позволяет выходить из содержащего эту команду цик¬ ла, который построен с помощью одной из уже рассмотренных команд (while и until) или двух команд (for и case), обсуждаемых в этой главе ниже. Чтобы выйти за пределы более чем одного цикла, необходимо определить требуемое число уровней цикла. Если в примере, приведенном ниже, вы выполните программу, по¬ казанную слева, то увидите результат, представленный справа. При отсутствии команды break внутренний цикл (цикл 3) должен выполняться бесконечно. Но команда break приводит к возврату в средний цикл (цикл 2), поэтому циклы 2 и 3 чередуются. (Этот пример иллюстрирует полезность команды echo, когда жела¬ тельно провести трассировку программы.) cat multi Loop $ while true do echo LOOP 1 untilfalse do echo LOOP 2 whi le true do echo LOOP break done done done Цикл 3 Цикл 2 $|multi Loop LOOP 1 LOOP 2 LOOP 3 LOOP 2 Цикл 1 LOOP LOOP LOOP LOOP LOOP Синтаксис процедур языка shell требует, чтобы каждой из команд цикла while, for или until соответствовал оператор done, завершающий цикл. После вывода со¬ общения LOOP3 командой break прекращается самый внутренний цикл и снова выполняется цикл until. Этот процесс может продолжаться бесконечно, что при¬ водит к поочередному выводу сообщений LOOP2 и LOOP3. Замена команды break на break 2 вынудит программу возвращаться во внеш¬ ний цикл (цикл 1) и поочередно выводить сообщения LOOP1, LOOP2, LOOP3: $ cat multi Loop whi le true do echo LOOP 1 unti1false do echo LOOP 2 whi le true do echo LOOP break 2 done done done multi loop Цикл 3 Цикл 2 LOOP 1 LOOP 2 LOOP 3 LOOP 1 Цикл 1 LOOP LOOP LOOP LOOP LOOP '/.11-771
306 Часть V Наконец, оператор break 3 должен привести к выходу за пределы всех трех циклов и завершению программы. Например: $|cat multi Loop whi Le true do echo LOOP 1 unti 1 faLse do echo LOOP 2 while true do echo LOOP break 3 done done done Цикл 1 Цикл 2 Цикл 3 multi Loop LOOP 1 LOOP 2 LOOP 3 $ Возобновление выполнения цикла continue Команда continue (продолжать) приводит к возобновлению выполнения програм¬ мы с оператора цикла for или while, ближайшего к циклу, в котором находится са¬ ма команда continue. Если в команде continue задано число уровней, то точкой, с которой программа продолжает выполнение, является оператор цикла for или while, соответствующий указанному в команде continue числу уровней, например: while true do command list 3 until false do command list 2 while true do command list 1 continue $level done done done Если переменная level имеет значение 2, выполнение будет продолжено с опе¬ ратора цикла until. Если же значение переменной level равно 3, будет возобнов¬ лен внешний цикл while. Наконец, если переменная level не установлена (или уста¬ новлена в 1), программа будет продолжать выполнение в самом внутреннем цик¬ ле while. Выход из цикла exit Команды break и continue позволяют программе выходить из текущего цикла. Ко¬ манда exit (выход) приводит к прекращению не просто текущего цикла, а всей процедуры. Она позволяет прекратить обработку при возникновении ошибки. По¬ сле выполнения команды exit в вызывающую программу передается код возвра¬ та, равный нулю (true). В приведенном ниже примере, main является исходной программой, которая вызывает процедуру subpro. Рассматривая имя процедуры subpro как булеву переменную, эта программа для организации ветвления в ус¬ ловном операторе использует код завершения данной процедуры. Затем в зависи¬ мости от значения кода возврата программа main выводит одно из двух сообще¬ ний.
Программирование на языке shell системы Юникс 307 $ |cat main if subpro then echo ' else echo 1 fi $ |cat subpro HERE='pwd' status=0 Exit status Exit status is zero ' is non-zero I exit $status $ _ В процедурезб/Ьрго переменной status присваивается значение 0, которое при¬ водит к выводу сообщения Exit status is zero. Если бы значение переменной stat¬ us было бы ненулевым, должно было бы быть выдано сообщение Exit status is non-zero. Цикл типа for for Команда for (для) организует условный цикл и имеет следующий формат: for variable in list do [Выполнение команд (ы) от do до done] done Команда for берет следующее слово из list в качестве нового значения пере¬ менной variable, а затем проверяет это новое значение. Если переменная variable имеет допустимое значение, команды между операторами do и done выполняют¬ ся; если же переменная имеет пустое значение (указывающее, что справа в спис¬ ке больше нет слов), выполняется команда, следующая за оператором done. На¬ пример: $|cat example list='word1 word2 word3 word4' for VAL in $list do echo $VAL done echo 'END OF LIST' $ $|example word1 word2 word3 word4 END OF LIST $ Когда вызывается данная shell-программа, сначала переменной VAL присваи¬ вается значение word1. Затем команда for проверяет значение VAL. Поскольку VAL имеет допустимое значение (word1), выполняется командаесЛо $VAL, и про¬ грамма продолжается с команды for, при этом переменной VAL присваивается следующий аргумент (word2), и процесс снова повторяется. Цикл выполняется еще два раза (один раз для word3 и один раз для word4). Затем после повторения с последним аргументом (word4) переменная VAL принимает пустое значение, ука¬ зывая тем самым на достижение конца списка. В этой точке цикл прекращается, программа обходит команды, заключенные между операторами do и done, и вы¬ полняет команду echo ’END OF LIST’. В следующей shell-процедуре переменная VAL принимает значения аргументов процедуры, которые передаются интерпретатором shell: ш*
308 Часть V $ cat rebounce for VAL do echo $VAL done $ $ rebounce one two three one two three $ Программа rebounce вызывается с тремя аргументами, которые передаются в позиционные параметры и последовательно присваиваются переменной VAL при каждом выполнении команды for. Если при вызове программы в качестве аргу¬ мента указывается звездочка *, это приводит к тому, что через позиционные па¬ раметры программе rebounce передаются имена файлов текущего каталога. На¬ пример, две следующие процедуры приводят к одному результату: $|cat rebounce.1 set ls for VAL do echo $VAL done $ $|cat rebounce.T for VAL in * do echo $VAL done $ В примере слева (rebounce.1) команда set позиционным параметрам присваи¬ вает результат работы команды ls, которая формирует список имен файлов и ка¬ талогов, содержащихся в текущем каталоге. В примере справа интер¬ претатор shell генерирует имена файлов и каталогов текущего каталога, а затем по очереди присваивает их переменной VAL. Условный оператор if Команда if (если) в простейшем виде имеет следующий формат: if <expression> then < Список команд) fi Команда if проверяет значение выражения, которое следует за именем коман¬ ды, и, если значение выражения равно 0 (true), выполняет команды между then и fi; если же значение выражения не равно 0 (false), выполняется команда, следую¬ щая за fi. Например: $|cat checF if true then echo 'TRUE VALUE' fi $ check TRUE VALUE $ Команда true передает if нулевое значение, что приводит к выполнению ко¬ манды echo. Измените программу, заменяя true на false, и вызовите ее опять: $ cat check if false then echo 'TRUE VALUE' fi $ check $ На этот раз никакое сообщение не выводится. Поскольку команда false возвраща¬ ет ненулевое значение, команда echo пропускается.
Программирование на языке shell системы Юникс 309 Альтернативная ветвь else Оператор else (иначе) применяется для задания альтернативного пути при выпол¬ нении программы, когда в команде if условие не удовлетворяется. В этом случае команда if имеет следующий формат: if <expression> then < Список команд 1> eLse < Список команд 2> fi Если возвращаемое значение выражения expression равно 0 (true), то выполня¬ ются команды между then и else. Если же оно не равно 0 (false), вызываются ко¬ манды между операторами else и fi. Например: $ cat file1 if a= ехрг **information" : "$1'* then echo '* $a characters matched eLse echo 'No character matched' fi $ к Выражение expr ”information": ”$1” сравнивает цепочку символов аргумента ”$1” с цепочкой символов "information”. Если код возврата выражения равен 0 (имеется частичное соответствие мужду двумя цепочками символов), выполняет¬ ся команда между операторами then и else. В противном случае выполняется команда между else и if и затем программа завершается. Давайте вызовем про¬ грамму file1 с аргументами и посмотрим на результат ее работы: $ fi Le1 info 4 characters matched $|file1 format| No character matched $ Объединение операторов else и if elif Оператор elif является комбинацией операторов else и if и позволяет в shell- программе более кратко записывать вложенные команды if. Например, имеется программа checkname, которая пытается сопоставить передаваемые аргументы с цепочками символов Mark, John и Dennis: $ cat checkname if expr "$1" : ''Mark" >/dev/null then echo Matching word is Mark else if expr "$1" : "John" >/dev/null then echo Matching word is John else if expr "$1" : "Dennis" >/dev/null then echo Matching word is Dennis else echo * * * No match * * * fi fi $ fi 11-771
310 Часть V С использованием оператора elif эта программа может быть записана следую¬ щим образом: $ i f cat ехрг new fi le ?1" : "Mark" >/dev/nuU then elif ехрг then elif ехрг then else echo fi $ _ "$1" : "John" >/dev/null '$1' "Dennis" >/dev/nulL ★ * * No match * * * Обратите внимание, что при использовании оператора elif требуется только один оператор if. Вывод команды expr переадресуется в файл /dev/null, который может рассматриваться как место сброса нежелательного результата. Проверка файлов, числовых величин и цепочек символов test Команда test (проверять) используется совместно с командами while, if и until. Эти команды запускают команду test и их последующее действие зависит от зна¬ чения кода возврата команды test. Аргументы команды test образуют выражение, которое вычисляется при ее выполнении. Если результат является истинным (true), возвращается нулевое зна¬ чение; если же ложным (false), возвращается ненулевое значение. Команда test может быть использована для анализа трех объектов: файлов, числовых величин и цепочек символов. Проверка файлов Команду test можно применять для анализа файлов следующими пятью спосо¬ бами: test< г -г ’ -w f > < filename > / -d /8> [Файл существует и его можно прочитать] [Файл существует и в него можно записывать] [Файл существует и не является каталогом] [Файл существует и является каталогом] [Размер файла отличен от нуля] В каждом случае команда test возвращает нулевое значение, если проверка дает положительный (истинный) результат, и ненулевое значение, если — отри¬ цательный (ложный). В следующем примере для проверки состояния файла используются вложен¬ ные команды if и команды test: $ cat copyaLl num=0 if test -d $H0ME/$1 [Установка счетчика числа недо¬ ступных для чтения файлов в 0] [Проверка существования введенного каталога]
Программирование на языке shell системы Юникс 311 then : else mkdir $H0ME/$1 fi for eachone in * do if test -f $eachone then if test -r $eachone then cp $eachone $H0ME/$1 eLse num='expr $num + 1' fi [Если каталог существует, действие не выполняется] [Если каталог не существует, его надо создать в вашем начальном каталоге] [Проверка имен файлов в текущем каталоге] [Это файл?] [Если да,он доступен для чтения?] [Если да, копирование файла в каталог $HOME/$l] [В противном случае увеличение на 1 общего числа недоступных для чтения файлов в текущем каталоге] fi done echo "$num non-accessibte files'* $ Программа copyall позволяет копировать каждый доступный файл, не являю¬ щийся каталогом, из вашего текущего каталога в каталог, определяемый вами в вашем начальном каталоге. Например, если вы вызываете программу copyall с по¬ мощью командной строки copyall newdir она будет копировать каждый доступный для чтения файл в вашем текущем ка¬ талоге в подкаталог newdir в вашем начальном каталоге. Если каталог с именем newdir еще не существует, он будет создан. Если же он существует, проверяется каждый файл из вашего текущего каталога (сначала является ли обычным фай¬ лом, а затем доступен ли для чтения). Если выполнены оба условия (т. e. файл до¬ ступен для чтения), файл будет скопирован в каталог newdir] если он недоступен для чтения, программа copyall прибавит 1 к общему числу таких файлов (перемен¬ ная пит). После окончания копирования всех файлов программа выведет на экран число недоступных для чтения файлов. Сравнение числовых величин Для проверки соотношения между двумя числовыми величинами команда test ис¬ пользует различные операции отношения: (-eq \ [А равно В?] [А = В?] -ne I [А не равно В?] [А Ф В?] -ge I [А больше или равно В?] [А >B?] -le ) В [А меньше или равно В?] [А < В?] -gt I [А больше В?] [А > В?] -lt I [А меньше В?] [А < В?] В каждом случае команда test проверяет, имеет ли отношение значение ’’исти¬ на” (true). Если отношение истинно, возвращается нулевое значение; в противном случае — ненулевое значение. и*
312 Часть V Следующая shell-программа проверяет размер всех файлов в текущем катало¬ ге и затем выводит имена всех файлов, которые содержат по крайней мере 10 00Q символов: $ |cat bigfiles count=10000 for i in * do size= wc -с < $i if test $size -ge $count then echo "$i size: $size" fi done $ Эта программа работает следующим образом: сначала переменной count при¬ сваивается значение 10 000. Команда for перед установкой значения переменной / проверяет существование очередного файла в текущем каталоге: если файлов больше нет, программа завершается; в противном случае выбирается следующий файл. Выражение size = 'wc -с < $i' является подстановкой результата выпол¬ нения команды, подсчитывающей число символов в файле, имя которого в дан¬ ный момент присвоено переменной /. Затем значение переменной size сравнива¬ ется со значением переменной count. Выражение test $size -ge $count будет ис¬ тинным только тогда, когда $size больше или равно 10 000. В этом случае на экран выводится имя файла и его размер (команда echo ”$i size: $size”). В некото¬ рых случаях программа перед обработкой может проверять аргументы, напри¬ мер: if test $# -eq 2 then echo PROCESSING elif test $# -lt 2 then echo 'missing second filename' else echo 'too many arguments' fi Выражение test $# -eg 2 будет истинным только в том случае, если интер¬ претатор shell передает этой программе только два аргумента. А выражение test $ti -It 2 будет истинным, если число аргументов меньше двух. Сравнение цепочек символов Для проверки цепочек символов используются следующие операции: test -n < string > [Существование цепочки символов] test -z < string > [Отсутствие цепочки символов] test < string 1 > = < string 2 > [Равенство двух цепочек символов] test <stringl> != <string2> [Неравенство двух цепочек символов] В следующем примере проверяется наличие второго аргумента, который пере¬ дается этой программе интерпретатором shell: if test тп "$2" then echo PROCESSING else echo 'missing second filename' fi
Программирование на языке shell системы Юникс 313 Обратите внимание, что переменная $2 должна быть заключена в двойные ка¬ вычки, чтобы команда test рассматривала ее как цепочку символов. Наличие вто¬ рой строки-аргумента можно проверить также следующим выражением: if test "$2" Для последующего сравнения давайте присвоим двум переменным значения цепочек символов: Y=' abcd' X=abcd Как вы знаете из гл. 23, если цепочка символов заключена в двойные кавычки, специальные символы сохраняют свой смысл, а пробелы трактуются как симво¬ лы. Если вы оставите цепочку символов без кавычек, пробелы в цепочку не вклю¬ чаются. Вот почему следующая программа обнаруживает равенство цепочек сим¬ волов X и Y: i f test $Y = $X then echo 'they are the same' else echo 'they are different' fi Однако, когда переменные X и У заключаются в двойные кавычки, команда test будет принимать во внимание пробелы в цепочке символов У и поэтому сле¬ дующая программа зафиксирует неравенство цепочек символов, соответствую¬ щих переменным X и У: i f test "$Y" = "$X" then echo 'they are the same' eLse echo 'they are different' fi Если же X и У заключаются в апострофы, знак доллара $ теряет смысл специ¬ ального символа. Поэтому в следующем выражении команда test сравнивает две цепочки $X и $Y, состоящие из двух символов каждая, а не значения цепочек сим¬ волов, которые соответствуют $X и $Y: test '$Y' = '$X' Обратите внимание на следующие моменты, касающиеся сравнения цепочек символов: • Знак равенства = или неравенства != следует окружать пробелами. • В знаке неравенства != составляющие его символы не должны быть разделены пробелами. Смешанная проверка При программировании на языке shell описанные выше примитивы с помощью операторов not, and и or могут быть объединены для получения более гибких управляющих конструкций: ! Одноместная операция not инвертирует значение выражения. -о Двуместная операция or дает значение true, если хотя бы один из операн¬ дов имеет значение true. -а Двуместная операция and дает значение true, только если оба операнда имеют значение true. В следующем примере операция not инвертирует значение true (нуль) в значе¬ ние false (ненулевое):
314 Часть V if test ! true что эквивалентно такому выражению: if test faLse Поэтому если цепочка символов $2 существует, следующее выражение дает истинное значение: if test "$2" А такое выражение имеет истинное значение, если цепочка символов $2 не су¬ ществует: i f test ! "$2" Операции and и or тоже могут быть использованы для проверки нескольких выражений одним оператором test, например: if test -f $1 -а -r $1 -о -w $1 then echo "file $1 is accessible" elif test -d $1 then echo "$1 is a directory" else echo "file $1 is not accessible" fi Сообщение file $1 is accessible выводится только в том случае, если файл ар¬ гумента ($1) является обычным файлом, для которого возможно либо чтение, ли¬ бо запись. Выражение test -d$1 будет истинным, если файл аргумента является каталогом. Другие средства программирования Ветвление по нескольким направлениям case Команда case (раскладывать) организует в shell-программах ветвление по не¬ скольким направлениям. Команда вместе с esac (esac — case с обратным распо¬ ложением символов служит конечным ограничителем) имеет следующий формат: case <string> in S1 ) < Список команд) ;; S2) < Список команд) ;; Sn) < Список команд) ;; esac Команда case сравнивает шаблон string с каждым шаблоном $1, $2, ..., $n. Ес¬ ли она фиксирует совпадение, будет выполняться список команд, коГорый сле¬ дует за совпавшим с string шаблоном и заканчивается парой символов точка с за¬ пятой (;;). Синтаксис команды требует двойной точки с запятой в конце каждого списка команд и оператора esac в конце всей команды case. Например: echo -n 'Please enter your selection (from а to d) : 1 read entry case $entry in A|a) echo *You have an apple.' ;; B|b) echo 'Where's the beef?1 ;; C|c) echo 'Coke adds life.' ;; D|d) echo 'A drop in the bucket.1 ;; *) echo 'Please type A, B, C, or D' ;; esac
Программирование на языке shell системы Юникс 315 Команда read осуществляет вывод с клавиатуры и присваивает введенное значение переменной entry. Ввод завершается, когда вы нажимаете клавишу RETURN. Если вы введете А (или а), будет выполняться команда echo 'You have an appLe.' и на экране появится сообщение You have an apple. Если же вы введете В (или b), командой case будет выдано Where’s the beef? и т. д. В конце списка шаблонов должна быть помещена звездочка *, используемая здесь для указания любого другого ввода. В противном случае команда case не сможет выбрать ни одного из допустимых входов (А, В, С или D). Управление прерываниями trap Сигналы прерывания возникают вследствие различных ненормальных ситуаций. Хотя интерпретатор shell управляет большинством этих сигналов, ряд из них он передает shell-процедуре, которая активна в момент возникновения прерывания. К таким сигналам относятся следующие: • Сигнал 1, возникающий при отключении терминала. • Сигнал 2, возникающий при нажатии клавиши DEL. • Сигнал 9, генерируемый командой kill -9 номер процесса (уничтожение процес¬ са). • Сигнал 15, генерируемый командой kill без опций (программное завершение про¬ цесса). Shell-процедура может выбирать, перехватывать или игнорировать каждый из этих сигналов (за исключением сигналаЭ). Если ваша программа не перехватыва¬ ет сигналы прерывания при их появлении, интерпретатор shell будет завершать вызванную в данный момент shell-процедуру. В ряде случаев это может приво¬ дить, например, к потере некоторых временных файлов, созданных данной shell- процедурой. Чтобы избежать этого, используйте команду trap (ловушка) для пе¬ рехвата сигналов прерывания, например: trap'<CrmcoKKOMabia>1 <Сигналы> Список команд должен быть заключен в кавычки. Если в список входит не од¬ на команда, то каждая команда должна быть отделена от другой точкой с запя¬ той. В команде trap может быть определено несколько сигналов, и они должны быть разделены пробелами, например: trap *rm tempfiLe; exit' 1 2 15 [Управлениепрерываниями] for i in $HOME/zfile/* do if ехрг "$i" : "$HOME/zfile/za" >/dev/null then cat $i >>tempfile fi done i f test -f tempfi Le then nroff -50 tempfile >nnewfile rm tempfi le fi В этой программе при возникновении одного из сигналов прерывания 1, 2 или 15 интерпретатор shell перед завершением программы удаляет файл tempfile.
316 Часть V Отладка shell-процедуры Как уже говорилось в этой главе, интерпретатор shell допускает контроль за выполнением shell-программы, поэтому вы можете увидеть, где допускаете ошиб¬ ки. Для установления контроля над shell-программой при вызове команды sh до¬ бавьте одну из двух следующих опций: -x Опция трассировки: для просмотра команд и аргументов по мере их вы¬ полнения. -v Опция входного контроля: отображение входных строк по мере их считы¬ вания. Например, для отладки shell-процедуры filez введите команду: sh -x fi Lez Можно также объединять опции, например: sh -vx fi Lez Краткое изложение главы 24 В этой главе вы ознакомились с командами true, false и exit; командами организа¬ ции циклов (while, until, break, continue и for); командами, используемыми для по¬ строения условного оператора (if, then, else и elif); командой проверки файлов, цепочек символов и числовых величин (test вместе с набором разделителей и операций) и некоторыми другими средствами для написания shell-процедур (ко¬ манды case и trap, опции -x и -v для контроля за выполнением shell- процедуры). Построение циклов Цикл — это сегмент программы, который повторяется до тех пор, пока не будет зафиксировано выполнение некоторого условия. ВозвРАТ знАЧЕНия true. Команда true всегда возвращает код завершения, равный true. ВозвРАТ знАЧЕНия false. Команда false всегда возвращает код завершения, равный false. Цикл while. Для выполнения цикла до тех пор, пока код завершения равен true, используйте команду while следующего вида: whi le < Список команд) do [Выполнение команд между do и done] done Цикл until. Для выполнения цикла до тех пор, пока код завершения равен false, используйте команду until следующего вида: unti L < Список команд) do [Выполнение команд между do и done] done ВложЕННОСТЬ. Если один цикл находится внутри другого, их называют вложенны¬ ми. ПРЕРЫВАНИЕ циклА. Для прекращения выполнения внутреннего цикла и возврата во внешний цикл используйте команду break, задавая, если нужно, число уровней.
Программирование на языке shell системы Юникс 317 ВозовновлЕниЕ выполнЕния циклА. Чтобы возобновить выполнение вложенного цикла, построенного с помощью команд for или while, используйте команду continue, задавая, если нужно, число уровней. Выход из циклА. Для прекращения всей процедуры используйте команду exit. Цикл for. Для построения цикла на множестве значений заданной переменной ис¬ пользуйте конструкцию цикла for: for variable in (Список) do [Выполнение команд между do и done] done Условный оператор Команда if позволяет организовывать в shell-процедуре ряд ветвлений: if (Выражение) then ( Список команд) fi if (Выражение) then ( Список команд) e 1 s e < Список команд) fi elif = "else if" Проверка файлов, числовых величин и цепочек символов ПРОВЕРКА ФАйлов. Чтобы определить, может ли файл быть прочитан или можно ли в него осуществить запись, является ли он каталогом или пустым файлом, вы можете использовать команду test с одной из пяти возможных опций. СРАВНЕНИЕ числовых ВЕЛИчин. Для сравнения двух числовых величин (равны, не равны и т. д.) вы можете использовать команду test с одной из шести двусим¬ вольных опций. СРАВНЕНИЕ ЦЕПОЧЕКсимволов. Команду test вы можете использовать и для опреде¬ ления того, существует ли некоторая цепочка символов или равны ли две цепоч¬ ки символов. СМЕШАННАЯ ПРОВЕРКА. С помощью операций and (-a), or (- о) и not (!) вы можете вы¬ полнить смешанные проверки. Другие средства программирования ВЕТвлЕниЕ по НЕСкольким НАПРАВЛЕниям. С помощью команды case вы можете орга¬ низовать ветвление по нескольким направлениям, завершая каждый из списков команд двойной точкой с запятой, а весь список — оператором esac. УПРАВЛЕНИЕ ПРЕРЫВАНИЯМИ. Для управления обработкой различных системных пре- рываний.используйте команду trap. ОтлАДКА shell-процедуры. С помощью двух опций команды sh вы можете выво¬ дить команды и аргументы по мере их выполнения (-x) или выводить входные строки процедуры по мере их считывания (-v).
318 Часть V Глава 25. Введение в C-shell В главах 21—24 вы ознакомились с интерпретатором В-shell (исходный интерпре¬ татор shell , разработанный Стефаном Бурном в Bell Laboratories) и командой sh, которая используется для вызова процедур интерпретатора В-shell. В этой главе речь пойдет о более новой версии интерпретатора shell под названием C-shell. Этот интерпретатор, созданный Вильямсом Джоем в Калифорнийском университете, составляет одно из главных достоинств системы Юникс версии Беркли. Некоторые версии системы Юникс могут поддерживать только интерпретатор В-shell. Если система, с которой вы работаете, поддерживает и интерпретатор C-shell, то для вызова его процедур следует применять команду csh. Если в своей работе с системой вы не связаны с интерпретатором C-shell, вам следует обра¬ титься к администратору системы, чтобы он установил в качестве интерпретато¬ ра, с которым вы связываетесь при входе в систему, интерпретатор C-shell. Что¬ бы сделать это, администратор должен изменить элемент в файле с именем letc/passwd. В этом файле есть строка с вашим входным именем; последний эле¬ мент этой строки /bin/sh следует заменить на /bin/csh. Файлы инициализации Для того чтобы интерпретатор C-shell правильно работал с вашим терминалом, в вашем начальном каталоге должны быть два файла: •login .cshrc Эти два файла будут выполняться интерпретатором C-shell при каждом вашем входе в систему (сначала .cshrc, затем .login). Они подробно рассматриваются ниже. Файл входа в систему . Iogin Файл .login выполняется только один раз, когда вы входите в систему. Поэтому он должен содержать такие команды, которые нужно выполнить только один раз (например, команды установки, команды задания последовательности поиска и типа терминала). Ниже приводится типичный файл .login с пояснением к каждой команде: stty ffO сгО -tabs erase ИАНМ [Эта строка должна устанавливать характеристики вашего терминала: от¬ сутствие задержки после перевода формата или возврата каретки, замена знаков табуляции пробелами, установка CTRL-H в качестве символа удале¬ ния.] set path=(/test/bin /bin /usr/bin $HOME/bin .) [Эта строка должна устанавливать последовательность поиска команды. В данном случае интерпретатор осуществляет поиск в следующем порядке: /test/bin, /bin, /usr/bin, подкаталог /bin в вашем начальном каталоге и, нако¬ нец, ваш текущий каталог для команд.]
Программирование на языке shell системы Юникс 319 setenv TERM vt52 [Эта строка устанавливает «терминальную» переменную TERM. В данном случае ваш терминал будет известен системе как VT52 со всеми характери¬ стиками, описанными в строке vt52 в файле letc/termcap.] echo "today is Ndat£ " [Эта строка выводит текущую дату при каждом вашем входе в систему.] Команда setenv (set environment) поясняется в разделе «Переменные» гл. 26. Файл «Настройка команды» ингерпрегагораС-shell . cshrc Файл .cshrc выполняется всякий раз, как создается новый интерпретатор C-shell, т. e. когда вы первый раз входите в систему или когда вы вызываете процедуру C-shell. Поэтому он содержит главным образом переменные, которые должны быть переустановлены для вновь создаваемого интерпретатора shell. Ниже пред¬ ставлен типичный файл .cshrc: set prompt = м<\!> м set history = 11 alias h history ali as cdl cd '\!*; I I more' ali as ch cd /usr7Mi ke/bookA! \* alias ch8 cd /usr/Mi ke/book/chap8 alias ch9 cd /usr/Mi ke/book/chap9 alias ch10 cd /usr7Mi ke/book/chap10 alias ch11 cd /usr/Mi ke/book/chap11 Эти строки подробно объясняются в следующем разделе. Элементы файла Установка собственной подсказки (приглашения) prompt Как и В-shell, интерпретатор C-shell позволяет устанавливать подсказку, которая появляется перед вводом каждой командной строки. Однако интерпретатор C-shell допускает «динамическую» подсказку, которая изменяется с каждой новой командной строкой. Вы можете задать нумерацию строк в подсказках, если ис¬ пользуете номер командной строки, известный как «событие» и определяемый восклицательным знаком !. Как раз это и сделано в Рриведенном выше простом файле .cshrc, где текущее событие выводится внутри пары угловых скобок < >. (Чтобы предотвратить трактовку восклицательного знака ! интерпретатором shell как «спецификация события», следует перед восклицательным знаком поставить знак обратной косой черты \.) Если вы устанавливаете подсказку таким образом, то сразу же после своего входа в систему увидите следующее: <1> _ Этот номер события увеличивается каждый раз, когда вы выполняете следу¬ ющую команду, подсчитывая тем самым для вас ваши командные строки. Если вы не присваиваете значение переменной prompt, интерпретатор C-shell по умол¬ чанию устанавливает знак процента %.
320 Часть V Установка числа сохраняемых событий history Во второй строке приведенного выше простого файла .cshrc находится команда set history = 11 По этой команде переменной history присваивается значение 11. Это число опре¬ деляет количество событий, которые следует сохранить для того, чтобы впослед¬ ствии на них можно было сослаться (т. e. размер списка предыстории). Таким об¬ разом, интерпретатор C-shell сохраняет в этом списке командных строк послед¬ ние 11 событий, которые по вашему требованию могут быть вызваны. Вы можете присвоить переменной history любое число, не превышающее предел для вашей системы (обычно 25). С помощью команды set в любой момент можно изменить значение переменной history, например: <2> set history = 5 <3> После этого, пока переменной history не будет присвоено новое значение, бу¬ дут сохраняться только последние пять событий. Чтобы вывести «список преды¬ стории», можно вызвать history как команду, например: <10> lhistory 5 cd book/xenix 6 ls -1 7 cp chapter23 /usr/dennis/backup 8 vi chapter23 9 ls /usr/dennis/backup <11> Здесь показаны последние выполненные пять команд вместе с соответствую¬ щими им номерами событий. Эти номера событий можно теперь использовать для повторного вызова командных строк из списка предыстории. Более того, с помощью рассматриваемой в следующем разделе команды подстановки результа¬ та предыстории вы можете модифицировать предшествующую команду перед ее выполнением. Повторный вызов предшествующих команд Возможность повторного вызова предшествующей команды приводит к тому, что вам не надо повторно вводить всю командную строку, которая может быть очень длинной и сложной. Чтобы повторно вызвать предшествующее событие, сформи¬ руйте команду «сделать повторно» путем ввода восклицательного знака ! с по¬ следующей ссылкой на событие. Восклицательный знак предписывает интерпре¬ татору C-shell отыскать командную строку в списке предыстории. Существуют че¬ тыре способа задания ссылки на событие: • сдвоенные восклицательные знаки (предшествующее событие); • действительный номер события; • относительный номер события; • имя команды. Повторный вызов последнего события ! ! Самым быстрым способом повторного вызова последнего события является ввод в качестве текущей команды сдвоенных восклицательных знаков !!. (Поскольку в предыдущем разделе вы вводили history как событие с номером 10, следующим
Программирование на языке shell системы Юникс 321 номером события будет 11.) После ввода двух восклицательных знаков интерпре¬ татор выводит сначала повторяемую командную строку, а затем результат ее вы¬ полнения, например: <ii>f7Tl history [Предшествующее событие: номер 10] 6 ls -1 7 cp chapter23 /usr/denm's/backup 8 vi chapter23 9 ls /usr7dennis/backup 10 history <12> _ Повторный вызов события по номеру !n В приведенном ниже примере событие вызывается повторно путем ввода его но¬ мера. Давайте вызовем команду, определяемую как событие с номером 9: <12> | ! 9 l [Повторный вызов события 9] ls /usr/denni s/backup [Событие 9 — команда ls] micro.back entry.back [Результаткомандык] changes.back files.back <13> Повторный вызов события относительно текущего события Ы В редакторах ed и vi вы использовали относительные номера строк (например, .-5 означает пять строк назад от текущей Строки). В случае интерпретатора C-shell применяется тот же принцип (!-5 означает пять событий назад от текущего собы¬ тия). Ниже представлены два примера с относительными номерами событий: <13>|!-6| cp chapter 23 /usr/dennis/backup <14>|!-3 l hi story 8 vi chapter23 9 ls /usr/dennis/backup 10 history 11 history 12 ls /usr/dennis/backup 13 cp chapter23 /usr/dennis/backup <15> Повторный вызов события с цепочкой поиска ! string После восклицательного знака можно вводить и цепочку поиска, указывая тем самым, что интерпретатор C-shell должен найти соответствующую командную строку. Если он находит ее, найденное событие вызывается повторно; если нет,
322 Часть V на вашем экране появится сообщение «string: Event not found». Ниже представле¬ ны два примера: <15>fTn Ls /usr7dennis/backup micro.back entry.back changes.back fi les.back <16>|!s| s: Event not found Так как команда ls начинается с I, то команда перезапуска // завершилась ус¬ пешно (событие с номером 12), поэтому интерпретатор C-shell выводит результа¬ ты ее работы. Следующая попытка (/s) неудачна, поскольку отсутствует команда, начинающаяся с s. Однако интерпретатор дает возможность вести подбор соот¬ ветствия и в пределах командной строки. Для этого после восклицательного зна¬ ка введите знак вопроса, например: <17> | l ?s l ls /usr/dennis/backup micro.back entry.back changes.back fi les.back <18> _ Знак вопроса предписывает осуществить поиск для s в любом месте команд¬ ной строки. Выбор отдельных аргументов Как и интерпретатор В-shell, C-shell расчленяет каждую входную строку на слова, присваивая каждому слову номер. Как и выше, имени команды соответствует но¬ мер нуль, первому из последующих слов — номер один, второму — номер два и т. д. Например, следующая командная строка содержит имя команды (слово с но¬ мером 0), первый аргумент -/ (слово с номером 1) и второй аргумент lusr/dennis/backup (слово с номером 2): ls -1 /usr/dennis/backup Способ нумерации слов в командной строке, используемый интерпретатором C-shell, позволяет выбрать из нее отдельное слово. Для этого в команде повтор¬ ного вызова просто добавьте двоеточие с последующим номером требуемого сло¬ ва (это команда, которая начинается с восклицательного знака). В приведенном ниже примере мы сначала вводим команду (событие с номером 18), затем из этой командной строки выбираем слово 1 (событие с номером 19): echo word-1 word-2 word-3 word-4 word-5 word-6 Теперь мы выбираем второе слово из этой командной строки: echo !18:1 <19> echo word-1 word-1 [Интерпретатор C-shell сначала выводит команду] [Затем выводит результат работы команды]
Программирование на языке shell системы Юникс 323 Указание первого аргумента л Другим способом получения того же результата является замена 1 на знак встав¬ ки л, например: echo И8:л <20> echo word-1 word-1 Указание последнего аргумента S Для обращения к последнему аргументу командной строки может быть использо¬ ван знак доллара $, например: <21> echo word-6 echo !18;$ word-6 Указание диапазона аргументов n - m Для задания диапазона номеров слов используется знак дефиса, например: <22> echo M8:2-5 echo word-2 word-3 word-4 word-5 word-2 word-3 word-4 word-5 Указание всех аргументов Для указания всех слов командной строки, за исключением нулевого (т. e. для указания каждого аргумента команды, но без имени самой команды), используй¬ те звездочку *, например: <23> echo !18:* echo word-1 word-2 word-3 word-4 word-5 word-6 word-1 word-2 word-3 word-4 word-5 word-6 Пропуск двоеточия при наличии символов При использовании знака вставки д, доллара $ или звездочки * для указания вы¬ бираемого слова можно опускать знак двоеточия : между номером события и ука¬ зателем выбираемого слова. Ниже показан другой способ задания событий 20, 21 и 23: <20> echo !18А echo word-1 word-1 <21> echo !18$ echo word-6 word-6 <23> echo !18* echo word-1 word-2 word-3 word-4 word-5 word-6 word-1 word-2 word-3 word-4 word-5 word-6
324 Часть V Модификация командной строки Интерпретатор C-shell позволяет выполнить повторный вызов события из списка предыстории (командную строку) с учетом задаваемых изменений, что может со¬ кратить число вводимых символов. Чтобы модифицировать событие, на месте номера слова после двоеточия введите модификатор. Можно подставить одну цепочку символов вместо другой, повторить цепочку символов, удалить пристав¬ ку и суффикс, просмотреть событие, не выполняя его, или запретить дальнейшие изменения события. Замена цепочки символов s Для этой цели используйте модификатор подстановки s аналогично команде s в редакторах ed и vi для замены одной цепочки символов на другую. В качестве примера повторно вызовем событие 23, а затем выполним подстановку: <24>fi23l echo word-1 word-2 word-3 word-4 word-5 word-6 word-1 word-2 word-3 word-4 word-5 word-6 Теперь в самом последнем событии используем модификатор подстановки s/wAW, чтобы вместо w подставить W (только при первом появлении): <25> M:s/w/W echo Word-1 word-2 word-3 word-4 word-5 word-6 Word-1 word-2 word-3 word-4 word-5 word-6 Как и в случае команды s редактора ed, заменяется только первый появив¬ шийся символ w в слове word-1. Чтобы заменить все встречающиеся символы w на W, используйте модификатор g глобальной замены: <26> !23:gs/w/W echo Word-1 Word-2 Word-3 Word-4 Word-5 Word-6 Word-1 Word-2 Word-3 Word-4 Word-5 Word-6 Можно модифицировать также только определенное слово, если указать его номер. Например, в приведенной ниже команде изменяется только второе слово: <27> echo W0RD-2 Если вы попытаетесь изменить несуществующее слово строки (например, word-9), будет выдано сообщение ’’Modifier failed" (недопустимый модификатор). echo !23:2:s/word/W0RD W0R0-2 Повторение предшествующей подстановки Модификатор & позволяет повторить последнюю подстановку без повторного ввода всей команды. Предположим, только что вызвано событие 25: <25> M:s/w/W echo Word-1 word-2 word-3 word-4 word-5 word-6 Word-1 word-2 word-3 word-4 word-5 word-6 Для следующего события мы могли использовать модификатор &: <26> !25:S echo Word-1 Word-2 word-3 word-4 word-5 word-6 Word-1 Word-2 word-3 word-4 word-5 word-6 Этот модификатор в данном случае влияет только на слово Word-2.
Программирование на языке shell системы Юникс 325 Удаление последнего имени из составного имени h Для удаления последнего имени в составном имени используйте модификатор h. Например, создадим составное имя: <28> echo /usr7dennis/backup.new /usr/denni s/backup.new Затем для удаления backup.new из составного имени мы можем использовать модификатор h (head — заголовок), например: <29>| ! !: h echo /usr7dennis /'usr7denm's Удаление суффикса r Чтобы удалить из цепочки суффикс (вида .xxx), используйте модификатор r. Да¬ вайте для удаления .new из составного имени в событии 28 применим модифика¬ тор r: !28:r echo /usr7dennis/backup /usr/denni s/backup Удаление префикса t Для удаления из составного имени префикса используйте модификатор t (tail — хвост). Давайте применим модификатор t к составному имени в событии 28: !28:t echo backup.new backup.new Просмотр командной строки p Чтобы отобразить на экран командную строку, не выполняя ее, используйте мо¬ дификатор p (print — печать). Например, выведем командную строку события 28: <32> !28:p echo /usr/dennis/backup.new <33> Запрет дальнейшей модификации q Для запрещения дальнейшего изменения командной строки используйте модифи¬ катор q. После выполнения события 33 любая попытка модифицировать то или другое событие (28 или 33) приведет к выдаче сообщения об ошибке ("modifier failed" — недопустимый модификатор): <33> !28:q echo /usr7dennis/backup.new /usr/dennis/backup.new
326 Часть V ПсеВДОКОМаНДЫ alias Выше в этой главе указано, что интерпретатор C-shell расчленяет вводимую ко¬ манду на слова. Каждое из этих слов проверяется на наличие эквивалента в «списке альтернативных имен (псевдоимен)» (alias list), который содержит список сокращенных команд, называемых псевдокомандами1). Если интерпретатор C- shell находит эквивалент, то он вместо псевдоимени использует соответствую¬ щую ему командную строку; если же не находит, такая замена не производится. (Напомним, что семь из девяти строк, входящих в файл .cshrc в начале этой гла¬ вы, подразумевались в «списке псевдоимен».) Создание особых команд «Список пдевдоимен» позволяет создавать новое имя как для существующей, так и для вашей собственной новой команды, которая является составной команд¬ ной строкой. Вы, например, можете образовать новую команду с именем d вместо команды pwd, чтобы затем при вводе d{cr) получать тот же результат, что и при вводе pwd(cr). Вот как это сделать: <34> <35> /usr/book/xenix.l Заметим, что создание нового имени команды не препятствует использованию старого имени. Теперь вы можете использовать как d, так и pwd. alias d d pwd [Вызов новой команды d] Удаление псевдокоманды Если вам нужно удалить команду d из списка псевдоимен, используйте команду unalias, например: <36> unalias d <37>^ d: command not found Сохранение псевдокоманд Типичное использование команды alias заключается в том, чтобы дать вам воз¬ можность вводить сокращенные команды вместо часто используемых и чрезмер¬ но длинных команд. Чтобы сохранить ваши псевдокоманды, лучше всего запи¬ сать ваш «список псевдоимен» в собственный файл .cshrc, который должен вы¬ полняться каждый раз, когда создается новый субинтерпретатор subshell. Команду alias можно использовать и для вывода собственного «списка псев¬ доимен», например: <38>|aLias alias ch8 alias ch9 alias ch10 alias ch11 cd cd cd cd /usr/Mi ke/book/chapter8 /usr/Mi ke/book/chapter9 /usr/Mi ke/book/chapter10 /usr/Mi ke/book/chapter11 1) Более точно такие команды следовало бы назвать командами с альтернативным име¬ нем, т. e. командами, вызываемыми по псевдониму. — Прим. ред.
Программирование на языке shell системы Юникс 327 Вызов псевдокоманды Записав ch8, ch9, ch10 и ch11 в свой «список псевдоимен», вы затем можете вы¬ зывать их как собственные команды. Например, чтобы перейти в каталог с име¬ нем /usr/Mike/book/chapter10, теперь вы можете вызвать <39> <40> ch10 pwd /usr/Mi ke/book/chapter10 Выполнение непосредственной выборки Можно установить изменяемую команду, которая позволяет конкретизировать ее вид во время вызова, например: alias ch cd /usr/Hike/book/X!\* Псевдокоманда ch допускает передачу аргументов, которые должны исполь¬ зоваться как часть команды «изменить каталог» (cd). Чтобы восклицательный знак и звездочка не обрабатывались интерпретатором C-shell , им должны пред¬ шествовать знаки обратной косой черты. Однако псевдокоманде они передаются. Ниже приведен вызов псевдокоманды ch с аргументами: <39> ch chapter10 <40> pwd /usr/Mike/book/chapter10 <41>Ich chapter9 <42> pwd /usr/Mi ke/book/chapter9 Комбинированные команды В одну псевдокоманду можно объединять более одной команды, например: alias cdl cd '\!*; ls -1 | more' Поскольку этот список команд содержит пробелы, звездочку и символ конвей¬ ера, он должен быть заключен в апострофы. Чтобы восклицательный знак не об¬ рабатывался интерпретатором C-shell, а передавался псевдокоманде, он должен быть помечен (ему должен предшествовать знак обратной косой черты). После вызова псевдокоманда cdl устанавливает в качестве текущего каталог, имя кото¬ рого вы вводите после cdl в качестве аргумента; затем список всех файлов этого каталога передается по программному каналу команде more для вывода на экран. Используя команду more вместо команды cat, вы сможете управлять про¬ цессом вывода на экран большого каталога, подобного /etc, например: <43> cdl /etc total 398 -rwx 1 bin -rwxr-x 1 bin -rw-r—г— 1 bin -rwx 1 daemon -rw-r—г— 1 bin drwxr-xr-x 2 bin -rws—x—x 1 sysinf 1346 Sep 4 1982 accton 157 Арг 28 1981 asktime 21 Dec 19 15:40 checklist 6354 Sep 4 1982 cron 0 Арг 30 1981 ddate 128 Feb 24 04:50 default 7984 Feb 3 1983 dmesg
328 Часть V -rwx 1 гоо 28432 Feb 24 04:44 dmfmt -rwx 1 root 1274 Feb 24 04:46 firsttime -rwx—x—x 1 bin 9228 Sep 4 1982 fixperm -rwx 1 bin 4080 Feb 15 14:30 getty -rw-r—r— 1 bin 45 Feb 24 04:45 group -rwx 1 bin 4721 Feb 24 04:45 haltsys -rwx 1 bin 1438 Sep 27 1982 inir -rwx 1 bin 4736 Feb 24 04:44 init -rwx—x—x 1 bin 5792 Feb 22 16:23 mdmctl -rwx—x—x 1 root 7136 Feb 15 14:18 mffmt -rwx—x—x 1 sys 10496 Feb 24 04:45 mkfs -rwx 1 sys 5088 Feb 24 04:45 mknod -rwx 1 root 22720 Feb 14 1983 mkuser -rw-rw-r— 1 bin 202 Dec 23 09:21 motd -rwx—x—x 1 bin 5404 Feb 24 04:45 mount —More— (23%) В этой точке вывод на экран прекращается до тех пор, пока вы не нажмете клавишу пробела. Повторные подстановки Псевдокоманды можно определять повторно с произвольным числом уровней подстановки. В этом случае интерпретатор C-shell будет выполнять подстановки до тех пор, пока не достигнет последней команды в списке: <44> <45> <46> <47> last alias com.1 com.2 alias com.2 com.3 alias com.3 echo4ast command' com.1 command [Вызов команды com. 11 Предположим, вы изменили событие так, что com.3 заменяет com.1. Тог¬ да, если вы вызываете команду com.1, интерпретатор C-shell реагирует на эту ситуацию таким, например, образом: <46> <47> Alias Loop. [Сообщение об ошибке] C-shell может определить, что это бесконечный цикл, и предупреждает вас об этом выводом сообщения об ошибке. alias com.3 com.1 com.1 Файл выхода из системы .iogout Можно организовать типовую процедуру выхода из системы, если поместить ко¬ манды в специальный файл с именем .logout. Такими командами могут быть стандартные команды системы Юникс или ваши собственные команды, которые вы установили с помощью процедуры интерпретатора C-shell. Команды из файла .logout могут просто выводить сообщение на экран или же удалять все времен¬ ные файлы, которые вы создали во время работы с системой. Файл должен нахо¬ диться в вашем начальном каталоге, а не в каком-либо подкаталоге. Ниже приво¬ дится пример уже созданного файла .logout:
Программирование на языке shell системы Юникс 329 <48>|cat .logout echo'You аге echo'Goodbye leaving the system' Обычный выход Эти две командные строки, помещенные в файл .logout, позволяют не только выйти из системы при нажатии CTRL-D, но и вывести на экран короткое сообще¬ ние: <49> [Вы нажимаете CTRL-D] <49> You are Leaving the system Goodbye ! Специальная команда для выхода из системы Напомним, что CTRL-D служит в системе Юникс для двух целей: 1) посылка сиг¬ нала о выходе из системы, 2) задание кода end-of-file (конец файла). Если коман¬ да, которая выполняет ввод с клавиатуры, должна быть завершена до получения признака конца файла (EOF), она прекратит процесс. Иногда это приводит к слу¬ чайному выходу из системы. Для исключения такого рода ошибки интерпретатор C-shell предоставляет средство, которое отменяет значение CTRL-D как сигнала выхода из системы и заставляет вас для выхода из нее вместо CTRL-D вводить logout. Таким средством является переменная с именем ignoreeof (ignore end-of- life- игнорировать конец файла). Чтобы отменить значение CTRL-D как сигнала выхода из системы, просто введите команду set ignoreeof. <49> set ignoreeof <50> Use <50> "logout" to logout. Logout [Установка переменной ignoreeof] [Вы нажимаете CTRL-D] Краткое изложение главы 25 Эта глава служит введением в интерпретатор C-shell, являющийся расширенной версией интерпретатора В-shell. Вы ознакомились с двумя часто используемыми с интерпретатором C-shell файлами (.login и .cshrc), установкой собственной под¬ сказки, повторным вызовом предшествующих команд, выбором отдельных аргу¬ ментов, модификацией командной строки, укорачиванием командной строки и формированием файла выхода из системы (.logout). Файлы инициализации .login. Этот файл содержит команды, которые подлежат выполнению при каждом вашем входе в систему, такие, как команда идентификации вашего тер¬ минала, команда изменения последовательности поиска команды и, возможно, команда вывода сообщения при входе в систему. .cshrc. Этот файл содержит команды, которые выполняются всякий раз при создании нового интерпретатора C-shell и могут использоваться для установки собственной подсказки, задания числа подлежащих сохранению событий и име¬ нования командных строк. 12-771
330 Часть V УстАновкА соБСТВЕнной подскАЗки. Для задания собственной подсказки в виде слов или символов используйте переменную prompt. УстАновкА числА СОХРАНЯЕМЫХ соБытий. Для установки числа командных строк (событий), сохраняемых для последующей ссылки, используйте переменную his¬ tory. Повторный вызов предшествующих команд ПОВТОРНЫЙ ВЫЗОВ ПОСЛЕДНЕГО СОБЫТИЯ. Для повторного вызова последнего собы¬ тия введите //. Повторный вызов соБЫТия по номЕРУ. Для повторного вызова любого предшеству¬ ющего события введите восклицательный знак, затем номер события, например /77. ПОВТОРНЫЙ ВЫЗОВ СОБЫТИЯ ОТНОСИТЕЛЬНО ТЕКУЩЕГО СОБЫТИЯ. Для повторного вызова события с номером, меньшим на некоторое число номера текущей строки, введи¬ те восклицательный знак, знак дефиса и число, например M. ПОВТОРНЫЙ ВЫЗОВ СОБЫТИЯ C ЦЕПОЧКОЙ ПОИСКА. Для повторного вызова события из списка предыстории, которое начинается с некоторой цепочки символов, введи¬ те восклицательный знак, а затем символы (например, !ls). Для задания поиска во всей командной строке введите между восклицательным знаком и цепочкой сим¬ волов знак вопроса (например, !7s). Выбор отдельных аргументов УКАЗАНИЕ АРГУМЕНТА по номЕРУ. Для выбора отдельного аргумента в командной строке добавьте к концу команды повторного вызова двоеточие и номер аргумен¬ та (например, echo !18:4). УКАЗАНИЕ ПЕРвого АРГУМЕНТА. Для выбора первого аргумента введите одну из сле¬ дующих альтернативных команд: echo !18:1, echo /78:л, echo /78л. УкАЗАНИЕ послЕДНЕГО АРГУМЕНТА. Для выбора последнего аргумента введите коман¬ ду, подобную следующей: echo !18:$ (или echo /78$). УКАЗАНИЕ ДИАПАЗОНА АРГУМЕНТОВ. Для указания аргументов из диапазона номеров введите команду, подобную следующей: echo !18:2-5. УКАЗАНИЕ всЕХ АРГУМЕНТОВ. Для указания всех аргументов используйте символ *, например: echo !18:* (или echo !18*).* Модификация командной строки ЗАМЕНА ЦЕПОЧки символов. Для замены одной цепочки символов на другую исполь¬ зуйте модификатор подстановки s, например H:s/w/W (замена w на И^. ПовтоРЕниЕ ПРЕДШЕСТВУЮЩЕЙ подстАНОВКИ. Для повторения предшествующей под¬ становки используйте модификатор повторения & (например, !25:&). УДАЛЕНИЕ послЕДНЕГО имЕНИ из СОСТАВНОГО имЕни. Для удаления последнего имени из составного имени используйте модификатор заголовка h (например, H:h). УддлЕниЕ ПРЕФИКСА. Для удаления префикса из составного имени используйте мо¬ дификатор конца t (например, !28:t). УддлЕНИЕСУФФИксА. Для удаления суффикса из составного имени используйте мо¬ дификатор удаления r (например, !28:r). Просмотр комАндной строки. Для вывода на экран командной строки (события) без ее выполнения используйте модификатор просмотра p (например, !28:p). ЗдпРЕТ ДАЛЬНЕЙШЕЙ модиФИКАЦИИ. Чтобы предохранить командную строку (собы¬ тие) от дальнейшей модификации, используйте модификатор ограничения q (на¬ пример, !28:q).
Программирование на языке shell системы Юникс 331 Псевдокоманды СоздАНИЕСПЕЦИАЛЬНОй комАнды. Для получения сокращенного имени команды для достаточно длинной команды присвойте этой команде более короткое название с помощью команды aiias. ОткАЗ от АЛЫЕРНАТивного ИМЕНИ. Для отказа от назначенного альтернативного имени (псевдокоманды) используйте команду unalias, например: % unaLias d СохРАНЕНИЕ АЛьтЕРНАТивного имЕни. Для постоянного хранения альтернативно¬ го имени команды занесите имя в файл .cshrc вместе с другими альтернативны¬ ми именами команд, сформировав тем самым «список псевдоимен». Для просмот¬ ра этого списка введите команду alias. Вывод комАнды по псЕВДОИМЕНИ. Для вызова команды из «списка псевдоимен» просто введите в качестве имени команды ее псевдоимя. ВыполнЕНИЕ НЕПОСРЕДСТВЕННОЙ выБОРКи. Чтобы иметь возможность передавать аргументы через псевдокоманду, используйте восклицательный знак, за которым следует знак *, причем обоим знакам предшествует знак обратной косой черты. КомБинировАННЫЕ комАнды. Интерпретатор C-shell допускает объединение не¬ скольких команд в одну псевдокоманду. Файл выхода из системы СтАНДАРТный выход. Интерпретатор C-shell позволяет создавать файл выхода из системы, чтобы запускать команды во время выхода из системы. Эти команды выполняют либо вспомогательные действия, либо просто выводят сообщение. СпЕциАЛьнАЯ комАНДА для выходА из систЕмы. Чтобы выходить из системы вво¬ дом команды logout, а не CTRL-D, включите в свой файл .logout команду set ignoreeof. Глава 26. Переменные C-shell Присваивание значений строковым переменным Способ присваивания значения переменной в C-shell несколько отличается от способа присвоения в интерпретаторе В-shell. В приведенном ниже примере це¬ почка символов table присваивается переменной VAL как ее значение: <1> set VAL = table В C-shell следует использовать команду set, а знак равенства во многих верси¬ ях системы Юникс должен быть окружен пробелами. Как и для интерпретатора В-shell, для отображения присвоенного значения следует ввести знак доллара $ и имя переменной. Таким образом, $VAL даст значение переменной VAL: <2>|echo $VAL table <3> Если цепочка символов, которая должна быть присвоена как значение пере¬ менной, содержит пробелы, она должна быть заключена в апострофы, кавычки или круглые скобки, например: 12*
332 Часть V <3> set var1 = '$VAL А B' <4> set var2 = "$VAL А В" <5> set var3 = ($VAL А В) <6> Каждая пара символов ”, ” ”, () имеет свой смысл: • апострофы — метасимволы рассматриваются как обычные символы; • кавычки — метасимволы сохраняют свой специальный смысл; • скобки — метасимволы сохраняют свой специальный смысл, а заключенные в скобки символы образуют массив (который рассматривается в следующем разде¬ ле). Приведенные ниже команды echo иллюстрируют эти различия: <6> echo $var1 <9> echo $var1[2] $VAL А В Subscript out of range <7>|echo $var2 | table А В <10> echo $var2C2] Subscript out of range <8> echo $var3 table А В <11> echo $var3l2] А Отображение присвоенных значений set Введя команду set без аргументов, вы можете вывести список объявленных пере¬ менных и присвоенных им значений: <12> argv С) bk /usr/book/ history 23 home /usr/work path (/test/bin /bin /usr/bin /usr/work/bin .) prompt <!> shell /bin/csh status 0 unmask 022 <13> set Удаление переменной unset Интерпретатор C-shell хранит список всех объявленных переменных. Для удале¬ ния переменной из этого списка используйте команду unset, например: <13> unset bk [Удаление переменной bk из списка] <14> set [Вывод списка переменных] argv О history 23 home /usr/work path (/test/bin /bin /usr/bin /usr/work/bin .) prompt <!>
Программирование на языке shell системы Юникс 333 shelL /bin/csh status 0 unmask 22 [Переменная bk отсутствует в списке] <15> Переменные как массивы Развивая возможности интерпретатора В-shell, C-shell трактует любое строковое значение переменной как массив при условии, что строковое значение заключа¬ ется в круглые скобки. Это означает, что хотя вся строка имеет общее имя, вы можете обратиться к отдельным словам цепочки символов. В приведенном ниже примере переменная path является именем массива, значение которого — после¬ довательность поиска команды. На языке Си к каждому элементу массива мож¬ но адресоваться отдельно с помощью указателя: на первый элемент ссылаться как на path [1], на второй — path [2], на третий — path [3] и т. д. В приведенном ни¬ же примере выводится значение третьего элемента: <15>fccho $path [Вызов всех значений переменной path] /test/bin /bin /usr/bin /usr/work/bin [Вызов третьего элемента] [Третий элемент в последовательности поиска] <16> echo $pathC3] /usr7bin <17> Поскольку каждый элемент занимает позицию в массиве с определенным но¬ мером, его можно заменить на заданное значение строковой переменной. Для этого введите команду set и имя массива, за которым следует номер, заключен¬ ный в квадратные скобки []. В приведенном ниже примере первый элемент мас¬ сива path заменяется цепочкой символов /usr/joe/bin (которая становится первым именем в последовательности поиска): <17> <18> /usr/joe/bin /bin /usr7bin /usr7work/bin <19> set path[1] = /usr/joe/bin echo $path Объявление массива Перед использованием массива вы должны его объявить. Для этого в фиктив¬ ной ком.анде set определите имя массива и его размер. Интерпретатор C-shell за¬ резервирует память для затребованного вами числа элементов. После этого вы можете инициализировать массив с использованием конкретной цепочки симво¬ лов. Ниже приводится пример, в котором семь элементов массива temp инициа¬ лизируются пустыми цепочками символов: <19> <20> Присваивание значений элементам массива Если для элементов в массиве зарезервирована память, имя temp можно исполь¬ зовать в качестве указателя места в памяти, в которое могут быть записаны це¬ set temp = (" " " м " " •■)
334 Часть V почки символов и из которого они могут быть прочитаны. Давайте занесем в не¬ которые из элементов конкретные цепочки символов: <20> <21> <22> one three <23> _ Можно присвоить значение элемента из одного массива элементу из другого мас¬ сива, например: <23> <24> one /usr/joe/bin three <25> _ Кроме того, можно извлечь любую из этих цепочек символов и присвоить ее дру¬ гой переменной, например: <25> <26> one <27> set VAL1 = $temp[1] echo $VAL1 set temp[2] = $path[1] echo $temp set temp[13 = one set temp[3] = three echo $temp Определение объявления переменной Для получения информации об установленных переменных используются специ¬ ально зарезервированные переменные. Значение специальной переменной ? рав¬ но 0 (false), если переменная не объявлена, и 1 (true), если она объявлена, напри¬ мер: <27> 1 <28> echo $7temp [Проверка переменной temp] [True: переменная объявлена] Определение размера массива Для определения размера переменной (массива) используйте специальную пере¬ менную #. Давайте проверим размер массива temp: <28> echo $#temp 7 <29> [Проверка массива temp] [Массив temp содержит семь элементов] Присваивание значений числовым переменным @ Как команда set используется для присваивания переменным строковых значе¬ ний, так команда @ применяется для присваивания переменным числовых значе¬ ний, например: <29> <30> а VAL = 3
Программирование на языке shell системы Юникс 335 Если вы попытаетесь с помощью команды @ присвоить переменной нечисло¬ вое значение, будет выведено сообщение о синтаксической ошибке: Э VAL = abc 3: Expression syntax <31> Для получения списка всех объявленных числовых переменных используйте команду @ без аргументов, как и в случае команды set: <23>® vaL 3 num 5 integer 12 <24> Выполнение арифметических действий В отличие от команды set команду @ можно использовать для выполнения арифметических и логических действий аналогично команде expr интерпретато¬ ра В-shell. Команду @ можно использовать со следующими арифметическими операциями: + сложение - вычитание * умножение / деление % взятие остатка Ниже приведены несколько примеров: <32> S А = 2 ♦ 4 <33> а S = $A ^T <34> а м = $д * $s <35> а R = $м % 4 <36> а D = $м / 4 <37> echo $A $S $M $R $D 6 3 ' 8 2 4 <38> [Сложение 2 и 4 и присваивание суммы Л ] [Вычитание 3 из Л и присваивание разности 5] [Умножение Л на S и присваивание произведения M] [Деление M на 4 и присваивание остатка R] [Деление M на 4 и присваивание частного D] [Вывод всех пяти результатов] Увеличение значения переменной + + или + =n Для увеличения значения переменной на единицу используйте оператор ++: <38> 0 D++ <39> echo $D 5 <40> [Увеличение D на 7]
336 Часть V С помощью оператора + = можно увеличить переменную на любое число. Пусть переменная Я имеет значение 2. Ниже представлен пример того, каким об¬ разом вы могли увеличить Я на 5: [Прибавление 5 к значению R] <42> <40> а R += 5 <41> echo $R Уменьшение значения переменной — или - = n Для уменьшения значения переменной на единицу используйте оператор —: <42> а D— <43> echo $D 4 <44> [Уменьшение D на 7] С помощью оператора - = можно уменьшить переменную на любое число. Приведенный ниже пример показывает, как переменную D, имеющую начальное значение 4, можно уменьшить на 3\ <44> а D -= 3 <45> echo $D 1 <46> [Вычитание 3 из значения D] Получение единичного дополнения переменной Для получения единичного дополнения значения переменной (значение с проти¬ воположным знаком минус единица) используйте оператор -(знак тильда), на¬ пример: [Присваивание R значения ее единичного дополнения] [Это !единичное дополнение 7 (- 7 - 7)] <48> <46> R =~ $R <47> echo $R Логическая проверка Логические проверки интерпретатора C-shell подобны команде test В-shell и в ка¬ честве результата дают значение true (1) или false (0): А < В True, если А меньше А > В True, если А больше В А < = B True, если А меньше или равно В А > — В True, если А больше или равно В A = B True, если А равно В А != В True, если А не равно В Ниже приводится пример последовательности логических проверок: <48> а А = 10; а В = 15 [Присваивание значений переменнымЛиЯ] <49> а С = ($A <= $B) [Проверка А меньше ли или равно В]
Программирование на языке shell системы Юникс 337 <50> echo $C 1 <51> [Вывод результата] [True: А меньше иди равно В] Для правильной интерпретации со стороны C-shell знака < = выражение справа от знака равенства должно быть заключено в скобки. Можно строить и более сложные операторы, например: <51> а К = ($A + $B > $A * $B) <52> echo SK 0 <53> [Сумма больше произведения?] [False: 25 не больше 150] Как видите, код возврата выражения в событии 51 нулевой, что указывает на значение выражения, равное false. Установка элементов числовых массивов Понятие массивов рассматривалось выше в этой главе в связи со строковыми переменными. Как и команду set, команду @ можно использовать с указателями для выбора отдельных элементов числового массива, например: <53> <54> <55> 1 2 <56> а scale = (1 2 3 4 5 6 7 8 9) а scalet3] = 100 echo $scale 00 4 5 6 7 8 9 [Присваивание значения числовому массиву] Выполнение арифметических действий Команда @ допускает выполнение арифметических действий над элементами массива. В показанном ниже примере значения элементов с номерами 3 и 5 скла¬ дываются, а затем сумма присваивается элементу с номером 8: <56> <57> 1 2 100 4 5 6 7 105 9 <58> а scalet8] = $scalet3] + $scalet5] echo $scale Выполнение логических проверок Для элементов числовых массивов можно выполнять и логические проверки. В приведенном ниже примере логическая проверка выполняется для элементов с номерами 3 и 8 массива scale, а логический результат записывается в элемент с номером 9: <58> <59> 1 2 100 4 5 6 7 105 0 [False: 100 не больше 105] <60> _ Элемент с номером 9 становится равным 0, указывая на значение false. Как и выше, выражение справа от знака равенства в событии 58 заключается в круглые скобки. а scalet9] = ($scalet3] > $scaleC8]) echo $scale
338 Часть V Зарезервированные переменные C-shell Указанные в данном разделе переменные интерпретатор C-shell использует для запи¬ си информации и ее передачи порожденному процессу. Некоторые из специальных переменных устанавливаются интерпретатором Oshell, другие могут изменяться пользователем. Аргумент с номером n $argv[n] Интерпретатор C-shell использует переменную argv[n] для передачи аргументов своей процедуре точно так же, как В-shell передает позиционные параметры своей проце¬ дуре. Поэтому $argv[0] является именем подлежащей вызову программы, $argv[1] — первым аргументом и т. д. Пусть имеется процедура reflect, представляющая собой следующее: <60> cat reflect echo $argvC0] set argvt3] = echo $argv[31 <61> $argv[1] NEW [# указывает, что это C-shell-процедура] $argv[2] $argvt3] Вызовем процедуру reflect: <61> reflect one two three reflect one two three NEW <62> [Вызов программы с тремя аргументами] [Вывод только что введенной строки] [NEW заменяет three как третий элемент] Интерпретатор C-shell передает позиционные параметры процедуре reflect, и вы можете изменить любой аргумент, за исключением argv[0] команды echo. Вы также вместо $argv можете использовать $1, $2, ..., $9. Число аргументов $#argv Эта переменная используется интерпретатором C-shell для запоминания числа аргу¬ ментов в только что вызванной команде. Изменим программу reflect следующим об¬ разом: <62> cat reflect U [C-shell-процедура] echo $argv[1] $argvt2] $argvC3] echo $#argv [Добавление такой новой строки] <63> |reflect one two three| one two three [Вывод только аргументов] 3 [Число аргументов] <64> _ Выражение argv[*] определяет ссылку на все позиционные параметры.
Программирование на языке shell системы Юникс 339 Последовательность поиска $cdpath Когда вы вводите команду cd с именем требуемого каталога в качестве аргумента, эта команда использует значение переменной cdpath как последовательность поис¬ ка для перехода из текущего каталога в требуемый каталог. Если этот каталог най¬ ден, он становится вашим текущим каталогом. Предположим, например, что вашим текущим рабочим каталогом является каталог /usr/book, а cdpath установлена следу¬ ющим образом: <64> <65> set cdpath = $H0ME/book/xenix/chapter21 и вы вводите <65> <66> cd chapter21 pwd [Проверка вашего текущего каталога] /usr/book/xeni x/chapter21 <67> Если переменная cdpath не установлена или поиск закончился безрезультатно, выводится сообщение <67>_ cd: No <68> cd xenix such file ог directory Такое сообщение появляется потому, что xenix не является подкаталогом вашего текущего каталога (в действительности ваш текущий каталог является подкаталогом xenix). Номер порожденного процесса $child Переменная с именем child содержит номер процесса-потомка, который порождает¬ ся как фоновый процесс. Когда этот процесс завершается, интерпретатор C-shell сбрасывает эту переменную. Отображение команды $echo Если переменная echo установлена, любая вводимая вами команда перед выпол¬ нением будет отображаться на экране. Эта команда по своему действию анало¬ гична опции -x команды sh интерпретатора В-shell : <68> <69> pwd /usr/book/xenix <70> set echo pwd [Объявление переменной echo] [Вывод команды] [Вывод команды на экран перед ее выполнением] Для отмены действия переменной echo следует выполнить команду unset. Длина списка предыстории $history Переменная history была рассмотрена в гл. 25. Командой set можно присвоить этой переменной значение размера списка предыстории.
340 Часть V Начальный каталог $home Переменная home интерпретатора C-shell подобна переменной HOME В-shell, и для краткости вместо ее значения можно использовать знак тильда ~. Значени¬ ем переменной home является составное имя вашего начального каталога, кото¬ рое устанавливается интерпретатором, например: <70> <71> По этой команде файл с именем file.1 из каталога /usr//ohn должен копиро¬ ваться в каталог $home/saving. Игнорировение знака конца файла $ignoreeof Обычно CTRL-D (или AD) определяется как знак конца файла (EOF — end-of-file). Если установлена переменная ignoreeof, интерпретатор C-shell игнорирует знак конца файла, вводимый вами с клавиатуры. Это защищает вас от случайного вы¬ хода из системы. Вы можете выйти из системы с помощью команды logout (более подробно эта команда рассмотрена в разделе «Специальная команда для выхода из системы» в конце гл. 25). cp /usr/john/file.1 -/saving Предотвращение перезаписи файла $noclobber Когда переменная noclobber установлена, интерпретатор C-shell препятствует пе¬ резаписи файла в результате переадресации вывода. Предположим, например, что файл tempfile находится в вашем начальном каталоге, и вы вводите следую¬ щее: <71> <72> set noclobber [Объявление переменной] echo4 WRITE THIS LINE4> tempfiLe tempfile: File exists <73> [Переадресация вывода] [Перезапись в файл не разрешается] При установленной переменной noclobber интерпретатор C-shell воспрепятст¬ вует созданию нового файла, когда вы добавляете текст к несуществующему файлу, например: <73> echo'I ADD NEW LINE'» newfile newfile: No such file ог dirctory <74> Автоматическая отмена специального смысла символа $noglob Когда переменная noglob установлена, расширения имени файла типа *, ? и - трактуются как обычные символы и вы можете использовать их буквально. На¬ пример: <74> _ file.1 <75> <76> ★ <77> echo * file.2 file.3 tempfile [Файлыданногокаталога] [Установка переменной nog/ob] [Теперь звездочка трактуется как обычный символ] set noglob echo *
Программирование на языке shell системы Юникс 341 В событии 74 звездочка рассматривается интерпретатором C-shell как мета¬ символ, разрешая вывод всех имен файлов текущего каталога. В событии 75 пе¬ ременная noglob устанавливается, поэтому интерпретатор трактует звездочку, как любой другой символ, что показано в событии 76. Отмена специального смысла символа, если не обнаружено соответствие при генерации имени $nonomatch Если переменная nonomatch установлена, то интерпретатор C-shell в первую оче¬ редь пытается найти соответствующее имя файла для имени, содержащего один из метасимволов *, ? и ~. Если C-shell такое имя находит, он передает это имя вызывающей программе; если же он не находит соответствующего имени, то пе¬ редает аргумент со специальным символом (метасимволом), рассматривая его как обычный символ. Если же переменная nonomatch не установлена и C-shell не находит соответствующего имени для заданного метасимвола, выводится сооб¬ щение об ошибке, что иллюстрируется представленным ниже примером: <77>|echo tempfile? echo: <78> <79> No match set nonomatch echo tempfile? tempfile? <80> [Установка переменной nonomatch] [Команда echo рассматривает знак вопроса буквально] Последовательность поиска команды $path Интерпретатор C-shell использует значение переменной path в качестве последо¬ вательности поиска команды, присваивая ей по умолчанию значение /usr/bin /bin. Следовательно, вы можете выполнять только те файлы, которые находятся в этих каталогах. Подробно эта переменная рассматривается в гл. 21 и 25. Знак-подсказка $prompt Значением переменной prompt является ваш знак-подсказка. Если вы не устанав¬ ливаете значение этой переменной, то интерпретатор C-shell по умолчанию при¬ своит ей значение %. Подробнее эта переменная рассматривается в гл. 25. Составное имя интерпретатора $shell Значением переменной shell является составное имя интерпретатора shell. Эта переменная отражает все, что установлено в файле /etc/passwd, например: <80>|echo $shell /bin/csh <81> Ответ в виде /binlcsh указывает, что вы используете интерпретатор C-shell. Код завершения последней команды $status Значением переменной status является код завершения самой последней выпол¬ ненной команды.
342 Часть V Время выполнения команды $time Когда переменная time установлена, интерпретатор C-shell выводит на экран вре¬ мя выполнения самой последней команды в секундах (время выполнения коман¬ ды, системное время, общее время и долю общего времени в процентах, которую составляют время выполнения команды и системное время): <81> set time <82> pwd /usr/xeni x/book/chapter21 0.1u 0.4s 0:02 25% <83> Выведенные в данном примере числа определяют время выполнения коман¬ ды (0.1), системное время (0.4) и общее время в секундах (0:02), требуемое для об¬ работки команды pwd, а также доля общего времени, затраченная на выполнение команды и подготовку ее выполнения ((0.1 + 0.4)/2). Тип терминала $TERM Переменная TERM, которая устанавливается командой setenv, определяет тип ис¬ пользуемого вами терминала. Вы должны установить эту переменную, прежде чем сможете использовать команды vi, more или некоторые другие программы. Идентификационный номер процесса $$ Значением переменной $ является идентификационный номер текущего процесса (подробнее он рассматривался в гл. 21). Завершающие сообщения $verbose По своему действию переменная verbose аналогична опции -v в вызове команды sh интерпретатора В-shell. Если она установлена, ваши команды будут отобра¬ жаться на экране по мере их чтения интерпретатором C-shell. Постоянные назначения Если вы хотите, чтобы любым из перечисленных переменных присваивались выбранные вами значения при каждом вашем входе в систему, включите их в файл с именем .cshrc, который обрабатывается при каждом вашем входе и каж¬ дый раз при создании нового процесса. Краткое изложение главы 26 В этой главе вы ознакомились с присваиванием значений строковым и числовым переменным, работой с переменными как массивами, выполнением арифметиче¬ ских и логических операций и специальными переменными интерпретатора C-shell. Присваивание строковых значений Для присваивания переменным-строковых значений используйте команду set. ПолучЕниЕ ЗНАЧЕНИЯ ПЕРЕМЕННОЙ. После присваивания переменной строкового значения вызывайте переменную путем указания перед ее именем знака доллара.
Программирование на языке shell системы Юникс 343 ОтоБРАЖЕНИЕ ПРИСВОЕННЫХ знАЧЕний. Для вывода всех объявленных перемен¬ ных и присвоенных им значений используйте команду set без аргументов. Для «аннулирования» переменной используйте команду unset. ПЕРЕМЕННЫЕ КАК МАССИвы. Интерпретатор C-shell трактует значение переменной как массив, если присваиваемое ей значение заключается в круглые скобки. Это дает возможность обращаться к отдельным элементам массива. ОвъявлЕниЕ МАССИВА. Для объявления массива используйте пустые цепочки символов, заключенные в апострофы. ПРИСВАИВАНИЕ знАЧЕний ЭЛЕМЕНТАМ МАССИВА. В объявленном массиве можно присваивать значения отдельным элементам. ОПРЕДЕЛЕНИЕ ОБЪЯВЛЕНИЯ ПЕРЕМЕННОЙ. Чтобы определить, объявлена перемен¬ ная или нет, используйте в команде echo между знаком доллара и именем пере¬ менной знак вопроса. Ответом будет либо true (1), либо false (0). ОПРЕДЕЛЕНИЕ РАЗМЕРА МАССИВА. Для вывода на экран числа элементов в массиве используйте в команде echo между знаком доллара и именем переменной знак #. Присваивание значений числовым переменным Для присваивания переменным числовых значений вместо команды set исполь¬ зуйте команду @. ПолучЕниЕ знАЧЕНия ПЕРЕМЕнной. После присваивания переменной числового значения вызывайте переменную путем указания перед ее именем знака доллара. ОтоБРАЖЕНИЕ пРисвоЕнных знАЧЕний. Для вывода всех объявленных числовых переменных и присвоенных им значений используйте команду @ без аргументов, ВыполнЕНИЕ АРИФМЕТИЧЕСКИХ дЕйствий. Для выполнения арифметических дей¬ ствий над числовыми переменными используйте операции +, -, *, / и %. УВЕЛИЧЕНИЕ знАЧЕНия ПЕРЕМЕнной. Для увеличения значения переменной ис¬ пользуйте операторы +4- и += n. УмЕньшЕниЕ знАЧЕния ПЕРЕМЕнной. Для уменьшения значения переменной ис¬ пользуйте операторы — и -=n. ПолучЕниЕ Единичного дополнЕния ПЕРЕМЕнной. Для получения единичного до¬ полнения значения переменной используйте оператор ~. ВыполнЕниЕ логичЕСКих ПРОВЕРОК. Для выполнения логической проверки ис¬ пользуйте команду @ с операторами <, >, <=, > = , != и =. УстАновкА элЕМЕНтов числового МАССИВА. Для присваивания числового значе¬ ния отдельному элементу массива используйте команду @ с именем массива и индексом элемента в квадратных скобках. Команду @ можно применять для вы¬ полнения как арифметических, так и логических проверок с отдельными элемен¬ тами массива. Зарезервированные переменные C-shell Приведенный ниже список переменных зарезервирован для использования терпретатором C-shell: Описание Имя Тип Аргумент с номером n $argv[n] Строковая или числовая Число аргументов $#argv Числовая Последовательность поиска $cdpath Строковая Номер порожденного процесса $child Числовая Отображение команды $echo true или false Длина списка предыстории $history Числовая Начальный каталог $home Строковая
344 Часть V Игнорирование знака конца файла Предотвращение перезаписи $ignoreeof true или false файла Автоматическая отмена специального смысла $noclobber true или false символа Отмена специального смысла символа, если не обнаруже¬ но соответствие при генера¬ $noglob true или false ции имени Последовательность поиска $nonomatch true или false команды $path Строковая Знак-подсказка $prompt Строковая Составное имя интерпретатора Код возврата последней $shell Строковая команды $status true или false Время выполнения команды $time Строковая Тип терминала Идентификационный номер $TERM Строковая процесса $$ Числовая Завершающие сообщения $verbose true или false Постоянные назначения Вы можете установить некоторые из этих зарезервированных переменных в сво¬ ем файле .cshrc, который выполняется при каждом вашем входе в систему и каж¬ дый раз при создании нового процесса. Глава 27. Процедуры интерпретатора C-shell Выполнение файла как shell-процедуры C-shell как язык программирования предоставляет средства, которые аналогич¬ ны средствам В-shell, но они имеют несколько иной синтаксис. Файл может вызы¬ ваться как C-shell-процедура двумя способами: 1) объявлением файла выполняемым; 2) выполнением команды csh с именем файла в качестве аргумента. Объявление файла выполняемым Когда вы с помощью команды chmod объявляете файл выполняемым, он стано¬ вится файлом команды. Это означает, что данный файл можно выполнять как обычную команду в том каталоге, где он находится. Перед выполнением shell- файла интерпретатор C-shell проверяет, не является ли первый отличный от про¬ бела символ знаком #. Если это не так, файл по умолчанию автоматически вы¬ полняется под управлением интерпретатора В-shell (см. пример в следующем раз- деле).
Программирование на языке shell системы Юникс 345 Выполнение команды csh Самым надежным способом выполнить файл интерпретатором C-shell является вызов команды csh с именем требуемого файла в качестве аргумента, например: <1> csh filename Как и В-shell, интерпретатор C-shell передает имя файла как значение argv [0], а все последующие слова как argv[1], argv[2] и т. д. Проверка файла Для проверки файлов интерпретатор C-shell использует средство, аналогичное команде test В-shell. Однако форматы выражений, которые могут использоваться в операторах if, foreach и while, различны. Каждое выражение после его проверки дает в качестве кода возврата либо true (1), либо false (0) в зависимости от того, что проверяется: -e ^ -z -f -d -о - <имя файла> - -r -w -X ^ true, если файл существует true, если нулевой размер файла true, если обычный файл true, если файл каталога true, если пользователь владеет файлом true, если файл доступен для чтения true, если файл доступен для записи true, если файл — выполняемый Построение условных операторов Простой условный оператор if ... then Как и оператор if интерпретатора В-shell, этот оператор C-shell проверяет значе¬ ние выражения. Если оно равно true, интерпретатор выполняет следующий за if оператор, если false — следующий оператор пропускается, например: cat exampLe.1 <2> # This program checks for the existence of the argument file if -e $argv[1] then echo MFile $argvC1] exists” Знак # является обязательным; без него C-shell не выполнит файл. Из этого примера видно, что строка, начинающаяся со знака #, может содержать коммен¬ тарии, которые игнорируются интерпретатором C-shell. Оператор if проверяет выражение -e $argv[1], которое предписывает проверить существование файла, заданного аргументом. Если файл существует, интерпрета¬ тор выполнит оператор echo ”File $argvt1] exists” Сообщение заключено в двойные кавычки, чтобы сохранить специальный смысл знака доллара $. Если оператор, который следует за логической проверкой, слож¬ ный (т. e. содержит конвейер или группу операторов), будет выдано сообщение о синтаксической ошибке.
346 Часть V Условный оператор с ветвлением по трем направлениям if ... then ... else Этот оператор полностью аналогичен оператору if ... then ... else интерпретатора В-shell. Он позволяет реализовать в программе альтернативные логические пути в зависимости от кода возврата выражения, следующего за if. Например: <3> cat example.2 U This is а modified version of example.1 if -e $argv[1] then echo "File $argvC1] exists" eLse echo "File $argvC1] not found" endi f Если выражение, следующее за if, имеет значение true (1), выполняется список команд между операторами If и else; если же это выражение имеет значение false (0), выполняется список команд между операторами else и endif. Заметим, что endif используется для установления границы оператора if ... then ... else. Ес¬ ли endif отсутствует, фиксируется синтаксическая ошибка. В приведенном ниже примере файл example.2 вызывает самого себя и передает себя в качестве свое¬ го аргумента: <4>|example.2 example,2 Fi le example.2 exists Дополнительная альтернатива else if Оператор else if обеспечивает для C-shell-программ дополнительные альтерна¬ тивные ветвления. Этот оператор выполняется таким же образом, как оператор eltf в интерпретаторе В-shell, например: <5>|cat example.X, U This program checks the file-type of the argument file П if -f $argvt13 then echo "$argvl13 is an ordinary file" else if -d $argvl1] then echo "$argvC1] is a directory" else echo "$argv[13 is unknown" endi f Выражением -1 $argv[1] проверяется, является ли первый аргумент именем обычного файла. Если не является, интерпретатор рассматривает выражение, следующее за else if (-d $argv[1]), чтобы определить, является ли первый аргумент именем каталога. Если не является, выполняется список команд между операто¬ рами else и endif. Если любое из выражений дает true, интерпретатор будет вы¬ полнять список команд, который следует непосредственно за выражением. В C-shell-процедуре может быть не один оператор else if. Оператор else явля¬ ется необязательным и лишь один оператор endif необходим, чтобы завершить
Программирование на языке shell системы Юникс 347 управляющую структуру if, независимо от заданного числа логических ветвей. Вызовем команду example.3 с example.2 в качестве аргумента: <6> |example,3 example.2 example.2 is an ordinary file Построение циклов Оператор перехода goto Оператор перехода goto имеет следующий формат: goto Uibel Встретив оператор goto, интерпретатор C-shell отыскивает в файле строку, со¬ держащую метку label: (с двоеточием в конце), а затем передает управление на эту строку. Например: <7> cat example.4 # if -d $argv[1] then echo "$argvC1] is а directory" goto list else if -f $argvl1] then echo "$argvC1] is an ordinary file" else echo "$argvt1] unknown" endi f 1 i st: echo "Here are the contents of $argv[13:" ls $argvl13 exit В этой программе, если выражение, следующее за if, дает значение true (аргу¬ мент является каталогом), интерпретатор выполняет оператор goto list, т. e. C-shell найдет строку, которая начинается с метки list:, и затем выполнит следую¬ щую за меткой команду. В этом случае интерпретатор выведет список имен всех файлов из каталога с именем $argv[1]. Пусть, например, каталог является подкаталогом, содержащим четыре файла: file1.bk, file2.bk, file3.bk и file4.bk. Вы¬ зовем команду example.4 pаргументом bac <8> example.4 backup backup is а directory Here are the contents of backup: file1.bk file2.bk file3.bk file4.bk Операторуправления циклом foreach Оператор foreach организует цикл так же, как это делает оператор for интерпре¬ татора В-shell. Оператор foreach имеет следующий формат: foreach variable (wordlist) список команд end
348 Часть V При первой итерации значение variable устанавливается равным первому эле¬ менту из wordlist, затем следующему элементу для каждой последующей итера¬ ции. Если значение variable не является пустым, интерпретатор выполняет список команд между операторами foreach и end. Этот процесс повторяется до тех пор, пока variable не будет иметь пустое значение, что указывает на отсутствие слов в списке wordlist. В показанном ниже примере интерпретатор копирует каждый от¬ дельный элемент из buffer2 в buffer1, не изменяя их порядок: cat cp buff U set buffer1 = (" set buffer2 = (А set pointer = 1 buffer2 to к и и и и) В С D E F) buffer1 [Инициализация массива buffer 1] [Инициализация массива buffer2] [Инициализация указателя] # foreach data ($buffer2) [Чтениесловаизмассива6м#<?г2] set buffer1C$pointer]=$data [Запись слова в массив bufferl] Э pointer++ [Увеличениеуказателя] end # echo "buffer1 $buffer1" [Вывод имени, а затем и echo "buffer2 $buffer2" содержимого каждого буфера] exit В предыдущей главе говорилось о том, что перед использованием массив дол¬ жен быть объявлен с нужным числом элементов. В данном случае buffer1 и buffer2 объявлены как массивы с шестью элементами каждый. При первом повто¬ рении цикла foreach переменной data присваивается значение первого элемента массива buffer2, т. e. А. Поскольку переменной pointer присвоено начальное значение 1, buffer1[$pointer] соответствует buffer1[1]. Следовательно, при первой итерации $data записывает¬ ся в buffer1[1]. В конце тела цикла оператор @pomter+ + увеличивает значение переменной pointer на единицу. Таким образом, при второй итерации buffer1[$pointer] соответствует buffer1[2], при третьей итерации — buffer1[3] и т. д. После обработки символа F (перемещая его из buffer2[6] в buffer1[6]) оператор foreach обнаруживает отсутствие последующих символов в buffer2. Поэтому ког¬ да оператор foreach пытается выполнить цикл в седьмой раз, переменной data присваивается пустое значение, и цикл завершается. По этой причине при вызове cp buff вы увидите на экране следующее: <10> | cp_buff buffer1 А В С D E F buffer2 А В С D E F Цикл While True while Оператор while определяет значение следующего за ним в круглых скобках выра¬ жения. Если значение выражения равно true, интерпретатор выполняет список команд между выражением и оператором end. Если же оно равно false, интерпре¬ татор прекращает выполнение цикла while. Цикл while имеет следующий формат:
Программирование на языке shell системы Юникс 349 whi Le (выражение) список команд end В показанном ниже примере цикл while заполняет буфер (который объявлен как массив) числами: <11>fcat fi 1 lu7 # Fi L L an array with numbers in ascending order U set buffer = (0 0 0 0 0) set pointer = 1 set count = S#buffer [Инициализация массива buffer нулями] [Установкаро/я/егв 1] [count равна длине массива buffer (5)] » while ($count) [Проверка условия входа в цикл] set bufferCSpointer] = $pointer[3aHeceHne числа в массив buffer] а pointer++ [Увеличение pointer на 1] а count— [Уменьшение count на 1] end U echo Sbuffer [Вывод содержимого массива] Условие входа в цикл определяется по значению $count, которое первоначаль¬ но устанавливается равным числу элементов в массиве buffer (5 элементов) и за¬ тем в конце цикла каждый раз уменьшается на единицу. Цикл while завершается тогда, когда значение переменной count становится нулевым, что означает от¬ сутствие места для записи чисел в массив. Начальным значением переменной count является число элементов (5) в массиве buffer. При первой итерации $count не равно нулю и интерпретатор выполняет опера¬ торы внутри тела цикла: заносит в первый элемент массива buffer значение ука¬ зателя (1) {set buffer [$pointer] = $pointer соответствует set buffer[1] = 1), указатель увеличивается до 2 оператором @pointer+ +, а счетчик уменьшается до 4 опера¬ тором @count--. При второй итерации интерпретатор присваивает элементу buffer[2] значение 2, указатель увеличивается до 3, а счетчик уменьшается до 3; при третьей итера¬ ции элементу buffer[3] присваивается значение 3, указателю — 4, а счетчик умень¬ шается до 2 и т. д. до пятой итерации. Ниже приведена диаграмма, которая отра¬ жает то, что происходит при каждой итерации (с указанием значений «до» и «после» для указателя и счетчика): Номер Значение в начале: Значение, Значение в конце: итерации указатель счетчик присвоенное указатель счетчик массиву 1 1 5 buffer[1] = 1 2 4 2 2 4 buffer[2] = 2 3 3 3 3 3 buffer[3] = 3 4 2 4 4 2 buffer[4] = 4 5 1 5 5 1 buffer[5] = 5 6 0 В конце пятой итерации счетчик становится нулевым, указывая на отсутствие места для записи чисел в массив. Когда оператор while пытается выполнить ше¬ стую итерацию, он обнаруживает нуль в операторе while($count) и цикл заканчи¬ вается. При вызове fillup вы увидите на экране следующее: <12> 1 2 3 fi1lup 4 5
350 Часть V Прерывание цикла break Оператор break интерпретатора C-shell аналогичен такому же оператору B-shell. В интерпретаторе C-shell этот оператор прерывает ближайший к нему цикл, орга¬ низованный с помощью оператора while или foreach. Приведенный ниже пример показывает некоторые особенности обращения с файлами: <13> |cat backup # Copy files from the current directory to "$home/backup" [Каталог с именем back существует?] [Если да, перейти на COPY] [Если нет, ... создание такого каталога] [Запись списка всех файлов в total] [Проверка условия для продолжения] [Есть ли аргумент за backupl] <$argvC1]==$file)break[EcHH есть,и он соответствует текуще¬ му файлу, то на этом прекратить] [Если нет, копирование этого файла ... и вывод сообщения] if -d $home/backup then goto COPY else mkdi r $home/backup endi f C0PY: set total = 1 ls' foreach file ($total) if ($#argv == 1) then i f else cp $file $home/backup echo ' $file copied' endi f end echo '* Backup completed *' Эта процедура позволяет возвращать все файлы в текущем каталоге в каталог вашего начального каталога с именем backup с одной дополнительной особен¬ ностью. Если вы включаете имя файла как аргумент, процедура backup будет ко¬ пировать все файлы до названного файла, но не включать его. Например, пусть ваш текущий каталог содержит такие файлы: apple date kiwi orange banana fruit lemon peach coconut grape melon pear Если вы вызываете backup без аргумента, все 12 файлов будут скопированы в backup. Если же вы укажете имя одного из этих файлов после backup, будут ско¬ пированы только те файлы в каталоге, которые предшествуют названному фай¬ лу, например: <14> backup fruit apple copied banana copied coconut copied date copied Backup completed <15> Продолжение цикла continue Оператор continue передает управление в программе ближайшему в цикле опера¬ тору while или foreach. Ниже приведена программа, которая обрабатывает аргу¬ мент и выбирает в нем четные числа:
Программирование на языке shell системы Юникс 351 <16> cat select # Select only even numbers from arguments entered # if ($#argv == 0) then [Аргументыотсутствуют?] echo "Numeric arguments required"[Ecnn да, выдача сообщения и exit if($#argv > 10) then echo "Only ten numbers allowed" exit endi f set output = (0 0 0 0 0 0 0 0 0 set count = 1 foreach number ($argv) if ($number % 2) continue set outputC$count] = $number a count++ end echo "Even numbers: $output" завершение программы] [Аргументов больше 10?] [Если да, выдача сообщения и ... завершение программы] 0) [Инициализация массива output 10-ю нулями] [Установка счетчика в единицу] [number равна номеру следующего аргумента] [Проверка нечетности/четности аргумента] [Если четный, сохранение в массиве output и увеличение счетчика на 1] [Вывод сохраненных четных чисел] Вы запускаете эту программу путем ввода select, за которым следует последо¬ вательность не более десяти целых чисел. Первые семь строк операторов про¬ граммы защищают от некорректных вызовов команды (отсутствие чисел после select при вводе или слишком много чисел). Затем инициализируются две пере¬ менные (массив, в котором будут храниться выбранные числа, и счетчик). Наконец, основная часть процедуры начинается с оператора foreach, который сначала присваивает переменной number значение первого введенного числа. Оператор if на следующей строке является ключевым в этой программе. Для определения четности числа оператор if использует операцию взятия остат¬ ка (%): • Если число четное, остаток от деления на 2 будет равен 0 (false), оператор continue пропускается и число заносится в массив output в качестве следующего элемента, а счетчик увеличивается на единицу для следующей итерации. Счет¬ чик служит в качестве указателя следующей позиции в массиве output, в которую должно быть записано число. • Если число нечетное, остаток будет равен 1 (true) и интерпретатор C-shell вы¬ полнит оператор continue, который действует как оператор goto, возвращая управление оператору foreach. Это означает, что число не будет занесено в мас¬ сив output, а счетчик не увеличится. •Если аргумент не является числом, интерпретатор выдаст сообщение об ошибке. Когда все аргументы обработаны, выводится результирующий массив output. Ниже показано то, что вы увидите на экране: <17> select Numeric arguments required <17> select 3 4 5 11 16 17 22 31 46 63 Even numbers: 4 16 22 46 0 0 0 0 0 0
352 Часть V Выходиз цикла exit Оператор exit работает так же, как в интерпретаторе В-shell: он прекращает вы¬ полнение программы и возвращает управление родительскому процессу. В роди¬ тельский процесс в качестве аргумента оператора exit можно передать код за¬ вершения. Более подробное описание этого оператора содержится в гл. 24. Другие средства программирования Ветвление по многим направлениям switch Оператор switch, который подобен оператору case интерпретатора В-shell, обес¬ печивает ветвление по многим направлениям. Каждый оператор switch заканчи¬ вается оператором breaksw, аналогичным сдвоенным знакам точка с запятой (;;)в В-shell. После завершения оператора switch управление будет передано за опера¬ тор endsw. Оператор switch имеет следующий формат: switch (string) case модель 1 список команд breaksw case модель 2 список команд breaksw default: [Необязательный] список команд breaksw endsw Оператор switch передает string каждому case для сравнения с моделью. Пос¬ ле выполнения списка команд выбранной ветви case оператор breaksw передает управление в программе на оператор, следующий за оператором endsw. При от¬ сутствии оператора breaksw для каждого case программа продолжит выполнение следующей ветви case, хотя для нее не было совпадения с string. Если не обнару¬ живается совпадение string ни с одной из моделей в case, выполняется список команд, следующий за оператором default. Например: <18> # cat matchfile if ($#argv == 0) then echo "No argument is declared" exit endif switch ($argvC1]) case FILE1: echo "User selects FILE1" breaksw case FILE2: echo "User selects FILE2" breaksw default: echo "You must select either FILE1 or FILE2" breaksw [Необязательный] endsw
Программирование на языке shell системы Юникс 353 Оператор if необходим для проверки наличия аргумента перед переходом (не¬ обязательным) к оператору switch. Если вы опустите оператор if, при отсутствии argv[1] оператор switch не будет выполняться и программа завершится с непонят¬ ным сообщением. Если программа вызывается с указанием аргумента, оператор switch попыта¬ ется сравнить значение этого аргумента со словом FILE1 или FILE2. Если совпа¬ дение не происходит, вызывается default, т. e. эта процедура включает проверку ошибок для обеспечения правильного использования. Последний оператор breaksw необязателен, но его полезно все-таки здесь иметь. Если вы его не вклю¬ чаете, управление в любом случае будет передано на оператор endsw. (Оператор breaksw тоже передаст управление на оператор endsw.) Ниже показан вызов про¬ цедуры matchfile тремя различными способами, первые два из которых имеют ошибки: Вызов matchfile без аргумента: <19> matchfi Le No argument is declared Вызов matchfile с аргументом unknown: matchfile unknown <20> t You must select either FILE1 or Вызов matchfile с аргументом FILE2: FILE2 <21> matchfile FILE2 User selects FILE2 Поскольку оператор switch допускает метасимволы типа *, ? и т. д. как симво¬ лы расширения, мы можем заменить default на оператор case * без изменения ха¬ рактера выполнения программы: <22> cat matchfile # if ($#argv == 0) then echo "No argument is declared*1 exit endi f switch ($argv[1]) case FILE1: echo **User selects FILE1** breaksw case FILE2: echo **User selects FILE2** breaksw case *: [Изменение] echo **You must select either FILE1 or FILE2'* endsw Сдвиг аргументов shift Оператор shift эквивалентен такому же оператору интерпретатора В-shell. Он сдвигает на одну позицию влево каждый элемент argv и отбрасывает argv[1]. Ес¬ ли массив argv не содержит хотя бы одного слова, интерпретатор C-shell считает argv неустановленной переменной и выводит сообщение об ошибке. Например:
354 Часть V <23> cat moveleft[ # Shift arguments to the left foreach words ($argv[*]) shift echo $argv end Давайте вызовем moveleft с тремя аргументами (1, 2, 3): <24> moveleft 1 2 3 3 <25> 2 3 [Аргумент 1 отбрасывается] [Аргумент 2 отбрасывается] [Аргумент 3 отбрасывается] У правление прерываниями onintr Если в какой-то момент вам потребуется завершить C-shell-программу во время ее выполнения нажатием клавиши [DEL] и одновременно удалить все временные файлы, которые были созданы этой программой до момента ее прекращения, вы можете это сделать с помощью оператора onintr, имеющего следующий формат: onintr label Когда происходит прерывание, интерпретатор C-shell обрабатывает прерыва¬ ние и передает управление оператору onintr, который выполняет строку, которая начинается с label:, как будто задан оператор goto. Например: <25> П cat print.format if($#argv == 0) then [Файлсуществует?] echo "Missing input file" exit 0 else if -d $argv[1] then [Файлявляетсякаталогом?] echo "$argvl1] is а directory" exi t endi f onintr cleanup [Управлениепрерываниями] pr $argvl1] > $home/bin/tempfile cp $home/bin/tempfile $argvl1] cleanup: [Программа обработки прерываний] if -f $home/bin/tempfile then rm $home/bin/tempfile exi t Если вы нажимаете клавишу [DEL] при выполнении этой программы, оператор onintr передаст управление на строку с меткой cleanup. Эта программа обработки прерывания проверяет наличие временного файла tempfile в вашем каталоге bin и удаляет его перед выходом из программы. Встроенные команды Интерпретатор C-shell содержит встроенные команды, которым он передает управление, не используя последовательность поиска и не создавая новый про¬ цесс. Полный список встроенных команд приведен в приложении 6.
Программирование на языке shell системы Юникс 355 Краткое изложение главы 27 В этой главе вы ознакомились с выполнением файла как shell-процедуры; опера¬ торами для построения условных конструкций (if, then, else и else If); операторами для построения циклов (goto, foreach, while, break, continue и exlt) и некоторыми средствами для написания C-shell-процедур (switch, shift и onintr). Выполнение файла как shell-процедуры ОвъявлЕНИЕ ФАйЛА выполняЕМЫм. Чтобы объявить файл выполняемым интерпре¬ татором C-shell, необходимо в начале первой строки файла поместить знак #, а затем выполнить команду изменения прав доступа с опцией u + x. ВыполнЕНИЕ ФАйЛА. Для выполнения любого файла как C-shell-процедуры ис¬ пользуйте команду csh с именем файла. ПРОВЕРКА ФАЙЛА. Для проверки файлов и каталогов в операторах if, foreach и while интерпретатор C-shell использует выражения аналогично интерпретатору В-shell, выполняющему подобные проверки оператором test. Построение условных операторов Простой условный ОПЕРАТОР. Для проведения простой проверки можно использо¬ вать только оператор if. Условный ОПЕРАТОР с ВЕТВЛЕНИЕМ по ТРЕМ нАПРАВлЕниям. Для более сложных про¬ верок можно использовать конструкцию «if ... then ... else». ДополнитЕльный НАБОР АЛЬТЕРНАТив. Для получения дополнительного набора альтернатив используйте оператор else if. Построение циклов 0nEPATOP ПЕРЕХОДА. Для указания интерпретатору C-shell перейти на строку с мет¬ кой используйте оператор goto. УПРАВЛЕНИЕ циклом. Используйте оператор foreach C-shell так же, как вы при¬ меняли оператор for интерпретатора B-shell. Цикл while true. Для построения цикла используйте оператор while и поддер¬ живайте выполнение цикла до тех пор, пока проверка выражения дает значение true. ПРЕРЫВАНИЕ циклА. Используйте оператор break C-shell так же, как вы применя¬ ли этот оператор с интерпретатором B-shell. ПРОДОЛЖЕНИЕ циклА. Для передачи управления в программе на ближайший опе¬ ратор цикла while или foreach используйте оператор continue. Выход из циклА. Используйте оператор exit C-shell так же, как вы могли его применять с интерпретатором B-shell. Прочие средства программирования ВЕТВЛЕНИЕ по многим НАПРАВЛЕНИЯМ. Для организации ветвления по мыогим на¬ правлениям, основанного на сравнении с моделью и завершении каждой альтер¬ нативной ветви оператором breaksw (вместо ;; в В-shell), используйте оператор switch, аналогичный оператору case интерпретатора B-shell. Сдвиг АРГУМЕНтов. Используйте оператор shift C-shell так же, как вы использо¬ вали его с интерпретатором B-shell. УПРАВЛЕНИЕ ПРЕРЫВАНИЯМИ. Для удаления файлов в случае прерывания проце¬ дуры перед ее завершением используйте оператор onintr. При возникновении пре¬ рывания он будет действовать как оператор goto.
Приложение 1. Краткое описание команд и символов общего назначения Ниже приводится список команд и символов общего назначения операционной системы Ксеникс. Обобщенные имена в этом списке выделены курсивом. Основные команды для начала работы с системой date who @ # или дН CTRL-D man learn Вывести дату и время Дать список работающих пользователей Стереть всю командную строку Стереть символ в командной строке Выйти из системы; иногда конец файла (EOF — end-of-file) Вызвать оперативную документацию Ксеникс Вызвать автоматизированную систему обучения Ксеникс Работа с каталогами и файлами / /bin /usr > file > > file < file pr11 pr2 cat file more file head fiie tail file cat f1 f2 > file mv f1 f2 mv f1 f2 DIR cp f1 f2 cp f1 f2 DIR Корневой каталог Каталог, который содержит большинство shell-процедур и вы¬ полняемых командных программ Каталог, содержащий обычно средства пользователя Текущий каталог Родительский каталог Переадресация вывода на файл file Переадресация вывода и добавление к файлу file Переадресация ввода из файла file Программный канал: использует вывод процесса pr1 как ввод для процесса pr2 (pr1 должен посылать свой вывод в стандартный выходной файл, а pr2 должен осуществлять свой ввод из стандартного входного файла) Вывести содержимое файла file на экран CTRL-S: остановить продвижение информации по экрану CTRL-Q: возобновить продвижение информации по экрану Вывести содержимое файла file поэкранно Вывести начальные строки файла file Вывести последние строки файла file Объединить файлы f1 и f2 в файл file Изменить имя файла f1 на f2 Переместить файлы f1 и f2 в каталог DIR Выполнить копирование файла f1 и назвать копию f2 Скопировать файлы f1 и f2 в каталог DIR
Команды и символы общего назначения 357 rm file Is Is -I pwd cd dir mkdir dir rmdir dir rm -r dir mv d1 d2 chmod ... file Удалить файл file из текущего каталога Дать список имен всех файлов и подкаталогов в текущем ка¬ талоге Вывести длинный список каталога Вывести имя вашего рабочего каталога Изменить ваш рабочий каталог на dir Создать каталог dir Удалить каталог dir (который не должен содержать каких- либо файлов) Удалить каталог dir и каждый файл в нем Изменить имя каталога с d1 на d2 Изменить права доступа к файлу file, используя следующие со¬ кращения: u пользователь + добавление r чи7ать g группа - отмена w писать о остальные = назначение X выполнять Поиск: формирование регулярных выражений л Начало строки $ Конец строки ? Подбор одного символа при поиске * Подбор любого числа символа при поиске [] Подбор любого из символов, заключенных в скобках, при по¬ иске \ Интерпретировать следующий символ буквально Установка основных характеристик passwd newgrp пате newgrp stty tabs term Изменить пароль Включить в рабочую группу пате Вернуться обратно в свою устанавливаемую по умолчанию группу Установить параметры своего терминала Определить табуляцию для терминала term Работа с процессами & DEL kill nnnn ps time process Запустить процесс как фоновый (поместив в конце командной строки) Прекратить привилегированный процесс Прекратить фоновый процесс с номером nnnn Вывести состояния процессов, связанных с вашим термина¬ лом Вывести время, потребовавшееся для выполнения процесса process
358 Приложение 2 Обработка информации dc bc echo sort file grep 'p' fHe awk file wc file spell file diff f1 f2 cmp f1 f2 comm f1 f2 tr s1 s2 file lpr file nroff file Вызвать настольный калькулятор Вызвать высокоточный калькулятор Отобразить строку на экране Упорядочить файл file в определенной последовательности Найти в файле file модель p Выбрать строки в файле file и обработать их Подсчитать число строк, слов и символов в файле file Проверить орфографию слов в файле file Вывести различия в файлах f1 и f2 Сравнить файлы f1 и f2 Вывести общие строки файлов f1 и f2 Перевести символы из набора s7 в набор s2 в файле file Вывести содержимое файла file на печать Форматировать и распечатать содержимое файла Другие основные команды mail user mail calendar write user cu uucp Послать электронную почту пользователю user Получить свою электронную почту Вывести события, сохраненные в файле $HOME/calendar в со¬ ответствии с датой, как напоминание Передать прямо на терминал пользователя Вызвать другую систему Связаться с другой системой Юникс Приложение 2. Средства редактора ed В общем виде команда редактора ed — это буква, перед которой ставится один или два номера строк (в общем случае необязательные). Команды этого редакто¬ ра e (edit — редактировать) и r (read — читать) должны сопровождаться именем файла; команда w (write — писать) может также сопровождаться этим именем. Допускается набирать в строке только одну команду, но команда p (print — печа¬ тать) может следовать за любой командой, кроме команд e (edit), r (read), w (write) или q (quit — выйти). Обратная косая черта \ может использоваться в конце каж¬ дой строки для продолжения длинной командной строки в последующей строке экрана. а (append — добавить строки в буфер редактирования, начиная с текущей строки, если не определена другая строка. Добавление продолжается до тех пор, пока не встретится точка в отдельной строке в качестве первого символа. Когда добавление закончено, последняя добавленная строка рассматривается в качестве текущей строки, с change — заменить указанные строки на тест, который следует за коман¬ дой. Текст должен заканчиваться точкой на отдельной строке. Если стро¬ ки не указаны, заменить только текущую строку. Последняя измененная строка становится новой текущей строкой, d delete — удалить показанные строки текста. Если строки не указаны, уда¬ ляется текущая строка. Обычно первая строка, следующая за удаляемым
Средства редактора ed 359 текстом, становится новой текущей строкой. Однако, если удаляется по¬ следняя строка, новой последней строкой становится новая текущая строка. e edit — редактировать файл. Если буфер редактора содержит текст, ког¬ да вводится команда e, он заменяется содержимым нового файла. Что¬ бы избежать потери текста, введите перед командой e команду w (write) для записи буфера. f file — файл. Отменить имя активного файла. Если вы наберете имя фай¬ ла после f, тогда это имя станет именем нового активного файла. Оно также будет отменено при выполнении следующей команды f. g global search — глобальный поиск. Выполнить указанную команду для всех строк в буфере редактора. i insert — вставить текст, который следует перед текущей строкой или пе¬ ред указанной строкой. Вставляемый текст должен заканчиваться точ¬ кой в отдельной строке. Последняя вставленная строка становится теку¬ щей строкой. m move — переместить указанные строки на место непосредственно за строкой, указанной после m. Последняя перемещенная строка становится текущей строкой p print — напечатать (т. e. вывести на экран) указанные строки. Если стро¬ ки не указаны, вывести на экран текущую строку. Нажмите клавишу RETURN, чтобы вывести на экран строку, следующую за текущей. q quit ed — выйти из редактора ed. Выйти из редактора и вернуться в ин¬ терпретатор shel!. Если вы предварительно не выполнили команду w (write), команда q сбросит буфер редактора. r read — считать файл в буфер редактора, начиная с конца буфера, если не указана другая строка. Последняя считанная строка становится новой текущей строкой. s substitute — заменить в указанных строках первый экземпляр одной це¬ почки сигналов на другую цепочку. Если строки не указаны, замена про¬ изводится только в текущей строке. Последняя строка, в которой произ¬ ведена замена, становится новой первой строкой. Если замены не про¬ изошло, текущая строка остается неизменной. v reverse global search — обратный глобальный поиск. Выполнить команды над теми строками, в которых не найдена указанная цепочка. w write — записать текст, находящийся в буфере редактора, в файл. Файл может быть назван или здесь или в ранее выполнявшейся команде e (edlt). Текущая строка остается неизменной. / Поиск контЕКСТА. Отыскать следующую строку, в которой содержится ука¬ занная в II цепочка. Поиск начинается в строке, следующей за текущей строкой, и продолжается во всех направлениях в буфере редактора на¬ зад к текущей строке, если это необходимо. Строка, в которой найдена указанная цепочка, становится текущей строкой. ? ОвРАТный поиск контЕкстА. Искать в обратном направлении строку, кото¬ рая содержит цепочку, указанную между символами ??. Поиск начинает¬ ся в строке, предшествующей текущей строке, и продолжается во всех на¬ правлениях в файле, разворачиваясь к текущей строке, если это необхо¬ димо. Строка, в которой найдена цепочка, становится новой текущей строкой. = ТЕКУЩАЯ строкА. Вывести на экран номер текущей строки. = ПослЕДняя строкА. Вывести на экран номер последней строки буфера ре¬ дактора. ! Выход. Выполнить команду системы Ксеникс, не выходя из редактора ed.
360 Приложение 3 Специальные символы поиска В командах поиска и замены следующие специальные символы имеют значения, приведенные ниже, за исключением случаев, когда им предшествуют символы \. В последнем случае они интерпретируются буквально, д Начало строки $ Конец строки \ Выключение специального значения Подобрать символ * Повторить символ [] Подобрать один из символов, заключенных в скобки & Использовать цепочку поиска в качестве цепочки замещения Следующие специальные символы фиксированы и не изменяют своего значе¬ ния: / Ограничитель цепочки поиска и цепочки замещения. (В строке замещения вы можете также использовать любой другой символ, не найденный в самой строке замещения.) \(\) Этикетка (тег) подпоследовательности (в цепочке поиска). \п Вставить подпоследовательность n (в цепочке замещения). Приложение 3. Команды редакторов vi и ex Вы вводите команды редактора vi при нахождении в командном режиме. Эти команды не отображаются на экране. Для ввода команд редактора ex наберите двоеточие, чтобы войти в командный режим, наберите команду, затем нажмите клавишу ESC nnn RETURN для возврата в командный режим vi. Команды для ор¬ ганизации поиска начинаются с косой черты или вопросительного знака, а закан¬ чиваются символом RETURN. Команды, которые начинаются с двоеточия, косой черты и вопросительного знака, отображаются в нижней части экрана. Перемещение курсора h На одну позицию влево j На одну позицию вниз k На одну позицию вверх I На одну позицию вправо b К первому символу предыдущего слова В К первому символу предыдущего слова (игнорируя знаки пунктуации) w К первому символу следующего слова W К первому символу следующего слова (игнорируя знаки пунктуации) e К последнему символу следующего слова E К последнему символу следующего слова (игнорируя знаки пунктуации) ( К началу текущего предложения ) К концу текущего предложения [ К началу текущего раздела ) К концу текущего раздела [ К началу текущей секции J К концу текущей секции
Команды редакторов vi и ex 361 л К первому отображаемому символу на текущей строке О К началу текущей строки $ К концу текущей строки H К началу экрана M На середину экрана L К концу экрана nG К строке с номером n (на последнюю строку, если n опущен) % К символам скобок (), [), [] Ли Смещение текста на одну строку вверх (CTRL-U) AD Смещение текста на одну строку вниз (CTRL-D) ЛВ Смещение текста на один кадр назад (CTRL-B) AF Смещение текста на один кадр вперед (CTRL-F) Добавление нового текста а После курсора А К концу строки i Перед курсором I В начале строки о Образование новой строки под текущей строкой О Образование новой строки над текущей строкой Изменение текста Во всех приведенных ниже командах могут быть использованы множители (на¬ пример, c5w, 5cc, c5), c5] и т. д.). cw До конца текущего слова cW До конца текущего слова (игнорируя знаки пунктуации) сА От первого воспроизводимого символа на текущей строке cO От начала текущей строки c$ До конца текущей строки cc Изменение всей строки c( От начала текущего предложения с) До конца текущего предложения c{ От начала текущего раздела cj До конца текущего раздела Смещение текста Во всех командах, которые приведены ниже, можно использовать множители (например, 5> >, >5(, <5j и т.д.). Сдвиг влево — <; сдвиг вправо — >. <( или >( К началу текущего предложения < ) или >) К концу текущего предложения < ( или >( К началу текущего раздела < j или >( К концу текущего раздела < < или > > Сдвиг всей строки на ширину сдвига 13-771
362 Приложение 3 Удаление текста Во всех приведенных ниже командах можно использовать множители (например, d5w 5dd, d5), d5) и т. д.). dw До конца текущего слова dW До конца текущего слова (игнорируя знаки пунктуации) dA До первого видимого символа текущей строки dO До начала текущей строки d$ До конца текущей строки (аналогично команде D) d( До начала текущего предложения d) До конца текущего предложения d[ До начала текущего раздела d) До конца текущего раздела dd Удаление всей строки Поиск и замещение tx (или Tx) Смещение курсора вперед (или назад) к символу перед (или по¬ сле) x на текущей строке ctx (или cTx) Изменение текста от положения курсора до символа, следую¬ щего за x dtx (или dTx) Удаление текста от положения курсора до символа, следующе¬ го за x fx или Fx Поиск символа x на текущей строке cfx или cFx Изменение текста от положения курсора до символа x на теку¬ щей строке dfx или dFx Удаление текста от положения курсора до символа x на теку¬ щей строке /слово Поиск «слово» в прямом направлении в рабочей области ?слово Поиск «слово» в направлении назад в рабочей области r Замещение символа, под которым находится курсор, на другой символ R Замещение одной совокупности символов на другую, которую вы набира¬ ете s Замещение одного символа несколькими S Замещение всей строки (аналогично команде cc) :n, Ns/стАРОЕ слово/новоЕ слово/д :n, Ns7cTAPOE слово?новоЕ слово?д Замещение «старого слова» на «новое слово» в каждом месте текста, начи¬ ная со строки с номером n до строки с номером N, поиск вперед в рабочей области Замещение «старого слова» на «новое слово» в каждом месте текста, начиг ная со строки с номером n до строки с номером N, поиск назад в рабочей области Вызов редактора $ vi file Начало редактирования файла с первой строки $ vi + line file Начало редактирования файла со строки line $ vi + /word/file Начало редактирования файла file с первой строки, кото¬ рая содержит слово word
Команды редакторов vi и ex 363 $ vi + file $ vi - r file $ vi - R file $ vi - t tag $ vi - x file Начало редактирования файла file с последней строки Начало редактирования с обеспечением восстановления файла fiie после системного сбоя Начало редактирования в режиме присвоения файлу file статуса «только читать» Редактирование файла, который содержит тег "tag“ Редактирование зашифрованного файла file (или редакти¬ рование нормального текста файла и его шифрование по мере записи файла на диск) Выход из редактора :wq <CR> Запись и выход. Записать текст из рабочей области в файл и закончить редактирование :x <CR> Условная запись и выход. Записать текст в рабочую об¬ ласть только при наличии изменений, а затем закончить ре¬ дактирование (аналогично команде ZZ) :q! <CR> Оставление текста. Оставить текст в рабочей области (со всеми изменениями, сделанными в нем) и закончить редак¬ тирование Смещение текста В общем виде процедура смещения текста в пределах буфера заключается в том, что выполняются: установка курсора на начало текста, перемещение курсора в новую позицию, а затем «выдача» текста либо перед курсором (команда P), либо за курсором (команда p). Если вы перемещаете текст в другой файл, можете «уда¬ лить» текст из поименованного буфера (a-z), а затем «выдать» его из этого буфе¬ ра. Вы можете начать редактирование другого файла (команда :e) без введения каких-либо других операторов между «удалением» и «выдачей». Ниже приведены некоторые из многих вариантов основной процедуры по смещению (где символ p означает либо P, либо p): x и p Смещение символа nx и p Смещение n символов dwn p Смещение слова dnw и p Смещение n слов d) и p Смещение предложения dn) и p Смещение n предложенйй d} и p Смещение раздела dnJ и p Смещение n разделов ddn p Смещение строки ndd и p Смещение n строк Копирование текста В общем виде процедура копирования текста в пределах файла заключается в том, что выполняются: установка курсора на начало текста, «вытаскивание» текс¬ та, перемещение курсора в новую позицию, а затем «выдача» текста либо за кур¬ сором (команда p), либо перед курсором (команда P). Если вы копируете текст в другой файл, должны «вытащить» текст в поименованный буфер (a-z), а затем «выдать» его из этого буфера. Вы можете начинать редактирование другого файла (команда :e) без введения каких-либо операторов между «вытаскиванием» и «выдачей». Некоторые из многих вариантов основной процедуры содержат сле¬ дующие комбинации (где символ p означает p либо P): 13*
364 Приложение 4 ywn p Копирование слова у) и p Копирование предложения у) и p Копирование раздела yy и p Копирование строки ynw И p Копирование n слов yn) и p Копирование n предложе¬ ний yn] и p Копирование n разделов nyy и p Копирование п строк Настройка характеристик редактора vi Вы можете производить настройку характеристик редактора, устанавливая оп¬ ции, определяя сокращения и назначая командные последовательности клави¬ шам клавиатуры. Установка опций set :set aw :set report=3 :set dir=files Установить режим автозаписи Установить значение опции report, равное 3 Установить для вашего каталога файлы Присваивание сокращений ab :ab unx UNIX operating system Присвоить сокращению unx значение текста UNIX operating system Определение ключей :map * (>) Присвоить клавише * значение последовательности [>j Установление постоянного действия определенных свойств Для установления постоянного действия в проведенных присваиваниях помести¬ те команды (без двоеточия) в файл .exrc, который можно было бы прочитать при обращении к редактору vi. Ниже приведены примеры строк записей, которые можно было бы поместить в файл .exrc: set aw report=3 dir=files ab xen XENIX operating system map * { » Приложение 4. Опции редактора vi Ниже перечислены все опции для vi (и для ex), которые могут быть установлены командой :set. Опции сгруппированы по допустимым значениям (двоичные (клю¬ чевые), числовые и строковые). Для каждой опции вы можете найти ее имя, со¬ кращение (если имеется), значениепо умолчанию и описание. Двоичные опции Двоичные опции могут быть только включены или выключены. Для выключения (отмены) опции'наберите no перед ее именем (или перед ее аббревиатурой).
Опции редактора vl 365 Автоматическое выполнение отступов ai Опция autoindent (ai — автоотступ) дает возможность произвести отступы, кото¬ рые устанавливаются правилами структурного программирования. Для каждой строки, которая вводится в режиме текстового ввода, редактор vi подбирает от¬ ступ по отношению к предыдущей строке, используя число позиций между знака¬ ми табуляции, определенное опцией shiftwidth (ширина сдвига). Для возврата кур¬ сора назад к предыдущему знаку табуляции необходимо набрать CTRL-D. При установке данного режима работы редактора строки обрабатываются следую¬ щим образом: • Строка без символов превращается в строку пробелов. • Если вводится строка, которая начинается с символа Л, со следующим далее на¬ жатием CTRL-D, то текст размещается без отступа, с начала строки, но действие отступа для предыдущей строки остается в силе при рассмотрении новых по¬ ступлений строк, которые последуют. • Если вводится строка, которая начинается с символа 0, с последующим нажати¬ ем клавиши CTRL-D, то текст размещается без отступа, с начала строки с таким же размещением последующих строк. Опция автоматического отступа не действует по отношению к общим коман¬ дам. Значение опции по умолчанию: noai. Автоматическая печать ар Опция autoprint (ар — автопечать) вызывает печать текущей строки после любой команды редактора ex, которая изменяет буфер. Это аналогично действию, кото¬ рое возникает при добавлении к каждой команде команды p. Опция ар действует только по отношению к последней последовательности команд на одной строке и не действует на общие команды. Значение по умолчанию: ар. Автоматическая запись aw Опция autowrite (aw — автозапись) вызывает запись содержания буфера редакти¬ рования в автоматическом режиме в текущий файл, если вы сделаете любые из¬ менения в буфере перед выдачей одной из следующих команд: :n (next- следующий) :! (escape — сменить) :rew (rewind — перемотка) CTRL-A — переключить файлы :tag (tag — тег) CTRL-] — перейти к тегу Значение опции по умолчанию: noaw. «Украшение» текста bf Опция beautify (bf — украшать) предотвращает попадание всех управляющих сим¬ волов при вводе текста (за исключением символов табуляции, новой строки и смещения) в буфер редактирования. Первый знак возврата отбрасывается (это сообщение). Опция bf не действует на команду ввода. Значение по умолчанию: nobf. Совместимость с редактором ed edcompatible Опция edcompatible сохраняет общие g и подтверждающие с суффиксы при про¬ ведении множественных подстановок, а также по суффиксу для чтения r уста¬ навливается действие (подобно команде чтения read). Значение опции по умолча¬ нию: noedcompatible.
366 Приложение 4 Игнорирование действия буквенного регистра ic Опция ignorecase (ic) переводит прописные буквы в тексте в строчные с целью установления регулярных выражений, за исключением символов, заключенных в скобки. Значение опции по умолчанию: noic. ЛИСП-действие lisp Опция lisp позволяет выполнять отступы для написания программ на языке ЛИСП и модифицировать значения следующих символов, которые подчиняются правилам стандартного использования в ЛИСП: 0 [) [[]] Значение опции по умолчанию: nolisp. Отображение всего содержимого list Опция list дает возможность отображать текст путем исполнения команды редак¬ тора ed по отображению (I). Текст отображается с символами табуляции и пусты¬ ми строками, которые помечаются на экране символами I и $. Кроме того, опция «загибает» любую строку, которая длиннее 72 символов. Значение опции по умол¬ чанию: nolist. Специальные значения символов magic Опция magic дает возможность оставлять метасимволам их специальные значе¬ ния. Когда она выключена, остаются в действии только значения знаков л и $. Однако вы можете установить значения другим специальным символам, помещая перед каждым из них обратную косую черту \. Значение опции по умолчанию: magic. Выдача сообщений mesg Опция mesg разрешает другим пользователям системы Юникс выполнять опера¬ цию записи (по команде write) на экран во время вашей работы с редактором vi. Обычная установка опции в nomesg предотвращает такое воздействие других пользователей на изображение вашего экрана во время редактирования. Значе¬ ние опции по умолчанию: nomesg. Нумерация строк nu Опция number нумерует строки в тексте. Значение по умолчанию: nonu. Оптимизация вывода optimize Опция optimize ускоряет работу терминалов, на которых отсутствует адресация курсора путем исключения автоматических возвратов в случаях, когда отобража¬ ется более одной строки. Это особенно полезно, если текст содержит бит отсту¬ па в начале каждой строки. Значение по умолчанию: optimize. «Перерисовывание» экрана redraw С помощью опции redraw (перерисовывание) осуществляется моделирование ра¬ боты «интеллектуального» терминала на «простом» терминале. Производится пу¬
Опции редактора vi 367 тем «перерисовывания» экрана по мере его освобождения и путем постоянного обновления текста во время внесения исправлений. Поскольку эта опция требует много времени на обработку, она полезна только при очень высоких скоростях передачи. Значение по умолчанию: noredraw. Отображение парного символа sm Опция snowmatch позволяет отображать парные круглые или фигурные скобки. Когда вы, например, набираете ) или }, то курсор переместится к парной скобке: либо к (, либо к (. Если парный символ находится в пределах экрана, курсор по¬ сле подведения к символу задерживается около него на одну секунду и возвра¬ щается в исходное состояние. Значение по умолчанию: nosm. Выдача коротких сообщений terse Опция terse дает возможность опытному пользователю работать с сокращенными сообщениями на экране. Например, 15/297 выдается вместо сообщения 15 lines 297 characters. Значение по умолчанию: noterse. Предупреждение о сохранении warn Работающая в редакторе ex опция warn выдает предупреждение, перед тем как вы попытаетесь выполнить shell-команду с помощью знака переключения (!). [“No write since last change”.] Значение по умолчанию: warn. Организация зацикливания во время поиска ws Опция wrapscan (ws) обеспечивает возможность «зацикливания» поиска строки, т. e. продолжение поиска с начала буфера радактирования в случае достижения (при поиске) конца буфера. Остановки в конце буфера при поиске при этом не происходит. Значение по умолчанию: ws. Организация произвольной записи wa Опция writeany (wa) дает возможность производить запись в любой файл, дости¬ жимый в файловой системе Юникс, опуская проверки, которые обычно прово¬ дятся перед выполнением команды записи write. Значение по умолчанию: nowa. Числовые опции Эти опции основываются на присваивании числовых значений с помощью ис¬ пользования знака равенства. Знаки табуляции (аппаратные) ht Опция hardtabs (ht) указывает на пространство между схемно реализованными знаками табуляции на терминале. Значение по умолчанию: ht = 8. Информация о командах report Опция report указывает число повторений команды, которое необходимо выпол¬ нить для организации выдачи сообщения на экран. Для команд, которые могут
368 Приложение 4 иметь расширенную область действия (глобальные команды и команда аннулиро¬ вания), сообщение сохраняется до окончания исполнения команды. Значение по умолчанию: report = 5. Число строк при смещении экрана scroll Опция scroll указывает число логических строк, на которое должно происходить смещение экрана во время выполнения операций CTRL-D (смещение вниз) или CTRL-U (смещение вверх). Значение по умолчанию: scroll = 1/2 кадра. Знаки табуляции (программные) sw Опция shiftwidth (sw) указывает число позиций между программными знаками та¬ буляции, которые используются в командах сдвига (в командах autoindent и CTRL-D при указании отступов в тексте и организации возвратов к предыдущим отступам). Значение по умолчанию: sw = 8. Знаки табуляции (редакторские) ts Опция tabstops (ts) указывает количество позиций между знаками табуляции при отображении файла на экран. Значение по умолчанию: ts = 8. Длина тега tl Опция taglength (tl) указывает число знаков в имени тега, которые являются зна¬ чимыми. Нулевое значение опции соответствует случаю, когда все знаки являют¬ ся значимыми. Значение по умолчанию: tl = 0. Высота кадра window Опция window указывает число строк, изображаемых в одном кадре текста. Зна¬ чение по умолчанию зависит от скорости передачи информации для конкретного терминала. Значения по умолчанию: window = 8 (скорость передачи равна бООбит/с), window = 16 (скорость передачи равна 1200бит/с), window = 23 (ско¬ рость передачи равна 9600бит/с). Вместо чисел 8, 16, 23 могут быть использова¬ ны переменные w600, w1200, w9600. Переход на границе строки wm Опция wrapmargin (wm) указывает ширину поля для автоматического перевода слова на следующую строку при попытке набора слова в этом поле. Поле нахо¬ дится в конце строки экрана. Значение 0 соответствует отсутствию такого поля, а следовательно, и отсутствию автоматического перевода слова в конце строки на следующую строку. Значение по умолчанию: wm = 0. Строковые опции Эти опции, записываемые в форме оператора присваивания, устанавливают строковые значения.
Опции редактора vi 369 Каталог dir Опция directory (dir) предназначена для указания имени каталога, который дол¬ жен содержать буфер редактирования. Если этот каталог имеет защиту по запи¬ си, сразу же произойдет выход из vi, поскольку редактор не поддержан буфером редактирования. Значение по умолчанию: dir = /tmp. Разделы para Опция paragraphs (para) служит для определения границ при использовании ко¬ манд «начало раздела» (команда [) и «конец раздела» (команда J). Определение осуществляется путем задания имен для макрокоманд nroff. Значение по умолча¬ нию: para = IPLPPPQPPLIbp. Замечание. Значение по умолчанию представляет собой сокращенное пред¬ ставление семи макрокоманд — четырех ms-макрокоманд (.IP, .LP, .PP, .QP), двух mm-макрокоманд (.P, .LI) и одной макрокоманды nroff (.bp). Секции sections Опция sections служит для определения границ при использовании команд «начало секции» (команда [[) и «конец секции» (команда ]]). Определение осущест¬ вляется путем задания имен для макрокоманд nroff. Значение по умолчанию: sections = SHNHHHU. Замечание. Значение по умолчанию представляет собой сокращенное пред¬ ставление четырех макрокоманд — двух ms-макрокоманд (.SH, .NH) и двух mm- макрокоманд (.H и .HU). Интерпретатор shell sh Опция shell (sh) предназначена для определения полного имени файла shell, ко¬ торое используется при выполнении команды переключения интерпретатора (восклицательный знак) или при использовании shell-команды. Если было уста¬ новлено значение для переменной SHELL, оно и рассматривается как значение по умолчанию. Значение по умолчанию: sh = /bin/sh. Теги tags Опция tags предназначена для определения полных имен файлов, которые будут использованы как теговые файлы командами, где применяется средство тегиро¬ вания. Когда требуется тег, то будет отыскиваться последовательно в описан¬ ных теговых файлах. Значение по умолчанию: tags = /usr/lib, а также текущий ка¬ талог. Терминал term Опция term предназначена для определения типа терминала. Значение по умол¬ чанию: term = $TERM (значение shell-переменной TERM).
370 Приложение 5 Приложение 5. Средства запросов на форматирование Запросы макропакета ms Формирование разделов .PP Стандартный раздел .LP Раздел блока .RE Сдвиг влево .1C Единственная колонка .QP Раздел цитаты .IP Раздел с отступом .RS Сдвиг вправо .2C Две колонки Вывод текста на экран .DS Стандартный вывод на экран .DSC Центрированный вывод на экран .DSB Сблокированный вывод на экран .DE Конец вывода на экран Сохранение единства строк .KS Стандартное сохранение .KE Плавающее сохранение .KE Конец сохранения Использование примечаний .FS Начать примечание .FE Закончить примечание Использование заголовков .SH Ненумерованный заголовок .NH Нумерованный заголовок Выделение текста .l Курсивом .R Прямым Схема расположения страниц .ND Удалить дату .DA I Изменить дату Г (LH .ds I | jCH Изменить заголовок l(RH f(LF .ds (CF Изменить футер L(RF
Краткое описание ингерпретатора B-shell 371 Запросы nroff Настройка страницы Pl Длина страницы .ll Длина строки .bp Смена страницы .po Отступ страницы pn Номер страницы .ne Необходимость пространства по вертикали Вывод строк на экран .fi Включить заполнение .ad Настроить текст .ce n Центрировать следующие n строк .hy n Поставить дефисы .in n Сделать отступ на n позиций .nf Выключить заполнение .nd Нет настройки .ls n Строка с n пробелами .nh Отсутствуют дефисы .ti n Временный отступ Вывод символов на экран .ul Подчеркивание \и Надпись % Номер страницы .cu Непрерывное подчеркивание \d Подпись Приложение 6. Краткое описание интерпретатора B-shell Переменные интерпретатора B-shell Перечисленные ниже переменные могут быть установлены в файле входа в си стему (.profile): PS1 Первичная подсказка PATH Последовательность поиска команды PS2 Вторичная подсказка MAIL Почтовый файл TERM Тип терминала НОМЕ Входной каталог Стандартный ввод, вывод и диагностика Стандартный ввод Дескриптор файла 0 От терминала Стандартный вывод Дескриптор файла 1 Ha терминал Стандартный диагностический вывод Дескриптор файла 2 На терминал
372 Приложение 6 Переадресация ввода и вывода < Переадресация ввода команды > Переадресация вывода команды > > Добавление к выходному файлу Переадресация с использованием дескрипторов файлов Для переадресации стандартного вывода в один файл, а стандартного диагно¬ стического вывода в другой используйте дескрипторы файлов. Фоновые команды & Запустить процесс как фоновый ps Вывести состояние фоновых процессов (для получения более под¬ робной информации с опцией -I) PID Идентификационный номер процесса TTY Номер терминала TIME Суммарное время выполнения CMD Название команды nice Изменить приоритет процесса kill n Завершить фоновый процесс с номером n Связанные процессы p1lp2 Конвейер: соединить p1 и p2 (т.е. использовать вывод p1 в качестве ввода p2) p1ltee file Дублирование стандартного вывода: просматривать вывод p1 на экране во время его записи в файл Задание директив интерпретатору B-shell Группирование команд (p1 p2) Создать субинтерпретатор shell для ввода и выполнения команд p1 и p2 (p1 p2) Ввести и выполнить команды p1 и p2 p1; p2; рЗ Список из трех команд Условное выполнение p1llp2 OR-IF: Вызвать команду p2 только в том случае, если команда p1 не завершается успешно. p1 && p2 AND-IF: Вызвать p2 только тогда, когда p1 завершается успешно. Генерация имен * Генерация любой строкя произвольной длины ? Генерация любого единственного символа [] Генерация любых символов из заданного набора
Краткое описание интерпретатора B-shell 373 Процедуры интерпретатора B-shell Вспомогательные команды echo Вывести текст на стандартный вывод (экран терминала) read Ввести текст со стандартного ввода (клавиатура терминала) Переменные интерпретатора B-shell $var = string $echo $var string eval ($P)s Присвоить переменной var значение строки string Вывести значение переменной Выведенное на экран значение переменной var Для строки, содержащей пробелы, используйте апострофы Для сохранения в строке смысла специальных символов ис¬ пользуйте кавычки Получить значение командной строки Отделить переменную P от окружающего ее текста Подстановка результатов выполнения команд $files = ’Is’ $y = expr $x + 5’ Присвоить результат выполнения команды Is файлу files Вычислить арифметическое выражение и присвоить резуль¬ тат переменной у. Условная замена переменных $[var-sub) $(var=sub) $[var7sub) $(var + sub) Если переменной var присвоено значение, использовать это значение; если нет, использовать переменную sub, оставляя переменную var неопределенной Если переменной var присвоено значение, использовать это значение; если нет, переменной var присвоить значение пере¬ менной sub Если переменной var присвоено значение, использовать это значение; если нет, вывести сообщение var:sub и прекратить процесс Если переменной var присвоено значение, вместо него ис¬ пользовать значение переменной sub; если нет, использовать пустую цепочку символов, а переменной var никакого значе¬ ния не присваивать Позиционные параметры $0 Команда $3 Третий аргумент $1 Первый аргумент $4 Четвертый аргумент $2 Второй аргумент $5 Пятый аргумент и т. д Зарезервированные переменные интерпретатора B-shell # Число аргументов в командной строке ? Код возврата по завершеннии команды $ PID (идентификационный номер) текущего процесса ! PID фонового процесса, вызванного последним — Состояние флагов интерпретатора B-shell
374 Приложение 6 Построение циклов Цикл While True whi le < Список команд) do [Выполнение команд между do и done] done Цикл While False until <Списоккоманд) do [Выполнение команд между do и done] done Вложенные циклы whi le < Список команд) do [Выполнение команд между do и done] Вложенность цикла until until < Список команд) внутрь цикла while do [Выполнение команд между do и done] done done Операторы цикла break Выйти из цикла continue Возобновить выполнение с начала ближайшего цикла exit Выйти из B-shell-процедуры Цикл по переменной for <Переменнаяизсписка) do [Выполнение команд между do и done] done Условный оператор if (Выражение) then < Список команд) fi if (Выражение) then (Списоккоманд) e 1 se < Список команд) fi elif = "else if”
Краткое описание интерпретатора B-shell 375 Проверка файлов, числовых величин и цепочек символов Проверка файлов test -r > [Файл — w [Файл -f > ^Мепате>[Файл -d [Файл - s > [Файл существует и может быть прочитан] существует и в него можно записывать] существует и является обычным файлом] существует и является каталогом] не пуст, его размер отличен от нуля] Сравнение числовых величин test А -eq '4 [А равно В?] [А = В?] -ne ) [А не равно В?] [А * В?] -ge ( в [А больше или равно В?] [А ^ В?] -|е ( [А меньше или равно В?] [А $ В?] -gt ) [А больше В?] [А > В?] -it J [А меньше В?] [А < В?] Сравнение цепочек символов test -n <string> [Существованиецепочкисимволов] test -z <string> [Отсутствиецепочкисимволов] test <string_J> = <string_2> [Равенстводвухцепочексимволов] test <string__1> != <5^1*пд__2>[Неравенстводвухцепочексимволов] Смешанная проверка ! Одноместная операция not инвертирует значение выражения -о Двуместная операция or дает значение true, если хотя бы один из опе¬ рандов имеет значение true -а Двуместная операция and дает значение true, только если оба операн¬ да имеют значение true Другие средства программирования Ветвление по многим направлениям case <string> in 51) < Список команд) ; ; 52) < Список команд) ; ; • • • Sn) < Список команд) ;; esac Управление прерываниями Сигнал 1: Сигнал отключения Сигнал 2: Сигнал выхода trap'<CnncoK команд)’<Сигналы)
376 Приложение 7 Сигнал 9: Прерывание Сигнал 15: Программное завершение Отладка sheU-процедуры $ sh -X <fi lename> [Опция трассировки: отображение команд] $ sh —V <filename> [Опциявходногоконтроля:отображение вводимых строк] Приложение 7. Краткое описание интерпретатора C-chell Файлы инициализации Простой файл входа в систему .login stty Установить характеристики вашего терминала set path Установить вашу последовательность поиска команды setenv TERM Выбрать имя терминала из уже описанных имен echo Выбрать начальное сообщение системы Файл «Чтение команды» интерпретатора C-shell .cshrc set prompt Установить собственную подсказку set hystory Установить число сохраняемых событий alias Установить псевдокоманду Повторный вызов предшествующих команд !! Повторно вызвать последнее событие !17 Повторно вызвать событие с номером 17 !-4 Повторно вызвать событие с номером, на 4 меньше номера текущего события !ls Повторно вызвать событие, начинающееся с Is !7s Повторно вызвать событие, которое содержит s (где-либо в строке) Выбор отдельных аргументов !18:4 Выбрать четвертый аргумент события 18 И8:л Выбрать первый аргумент события 18 (то же И8Л) !18:$ Выбрать последний аргумент события 18 (то же !18$) N8:2-5 Выбрать аргументы 2, 3, 4 и 5 события 18 !18:* Выбрать все аргументы события 18 (то же !18*) Модификация командной строки !! :s/wW !!:& Заменить в предшествующем событии w на W Повторить предшествующую подстановку в последнем событии
Краткое описание интерпретатора C-shell 377 Удалить последнее имя из составного имени предшествующего события Удалить префикс из составного имени предшествующего собы¬ тия Удалить суффикс из составного имени предшествующего собы¬ тия Просмотр последнего события Защитить предшествующее событие от дальнейшей модифика¬ ции M:h M:t !!:r M:p M:q Псевдокоманды % alias d pwd % unalias d % alias ch cd /usr/Mike/book/ \ ! \ * % ch chapter10 $ alias cdl cd ’\! *; Is -I more’ Файл выхода из системы Стандартный выход из системы %AD [Нажать CTRL-D] Использовать d как сокращение для команды pwd Отменить d как сокращение для ком¬ анды (Динамическая подготовка) Вызвать команду ch с указанием аргу¬ мента (Комбинированная псевдокоманда) Собственно выход из системы set ignoreeof (Переменная, помещенная в файле .logout) Присваивание значений строковым переменным % set VAR = value % echo $VAR % set % echo $path /usr/peter/bin/bin/usr/- clan/bin/ % echo $path[2] % set array = (” ” " ") % set array[2] = two % echo $7array 1 % echo $#array 4 Присвоить переменной VAR значение value Отобразить значение VAR Вывести все объявленные переменные и их значения Вывести второй аргумент переменной path/bin Объявить массив array из четырех элементов Присвоить значение второму элементу Проверить, объявлен ли массив array [True: массив array объявлен] Вывести число элементов массива array Действия над числовыми переменными Значения %@ val = 5 Присвоить 5 переменной val % echo $val Вывести значение val 5
378 Приложение 7 %@ + Сложение - Вычитание % @Y + + %@X + = 5 %@Y %@X -= 3 %@x = ~$х %@M = 9; @N = 10 %@T = ($M < $N) < Меньше > Больше Вывести все числовые пере¬ менные и присвоенные им значения * Умножение / Деление % Взятие остатка Увеличить Y на единицу Увеличить X на пять Уменьшить Y на единицу Уменьшить X на три Присвоить X единичное до¬ полнение X Проверить M меньше, чем N <= Меньше или равно = Равно >= Больше или равно != Не равно Зарезервированные переменные C-shell Описание Имя Тип Аргумент с номером n $argv[n] Строковая или числовая Число аргументов $#argv Числовая Последовательность поиска $cdpath Строковая Номер порожденного процесса $child Числовая Отображение команды $echo True или false Длина списка предыстории $history Числовая Начальный каталог $home Строковая Игнорирование знака конца файла $ignoreeof True или false Предотвращение перезаписи файла Автоматическая отмена специального $noclobber True или false смысла символа Отмена специального смысла символа, если не обнаружено соответствие $noglob True или false при генерации имени $nonomatch True или false Последовательность поиска команды $path Строковая Знак-подсказка $prompt Строковая Составное имя интерпретатора shell $shell Строковая Код завершения последней команды $status True или false Время выполнения команды $time Строковая Тип терминала $TERM Строковая Идентификационный номер процесса $$ Числовая Завершающие сообщения $verbose True или false Некоторые из этих переменных вы можете включить в свой файл .cshrc, кото- рый выполняется каждый раз при вашем входе в систему или при создании ново¬ го процесса. Проверка файла Интерпретатор C-shell использует в операторах if, foreach и while следующие вы¬ ражения так же, как В-shell в команде test:
Краткое описание интерпретатора C-shell -e -z -f -d -о -r — w -X file true, если файл существует true, если нулевой размер файла true, если обычный файл true, если файл каталога true, если пользователь владеет файлом true, если файл доступен для чтения true, если файл доступен для записи ^true, если файл — выполняемый Построение условных операторов if . . . then if . . . then . . . else if . . . then . . . else . . Построение циклов goto label Перейти к строке с меткой label foreach variable (Списокслов) Список команд end whi le (Выражение) Список команд end break continue exit Выход из цикла Продолжение выполнения с начала ближайшего оператора цикла Выход из shell-процедуры Другие средства программирования switch (string) Модель 1: Список команд breaksw Модель 2: Список команд breaksw default: [Необязательный] Список команд breaksw endsw shift onintr label Сдвинуть все аргументы влево на одну позицию Перейти на строку с меткой label, если происходит прерывание 379
380 Приложение 7 Встроенные команды Встроенные команды являются командами, программы которых служат частью интерпретатора C-shell. При вызове встроенной команды для определения ее места интерпретатору не надо использовать последовательность поиска, по¬ скольку команда не является отдельным файлом. C-shell вызывает встроенную команду без создания нового процесса. Ниже приведен список этих команд, большинство которых подробно описаны в гл. 25 — 27. alias Используется для присваивания нового имени командной строке. Когда эта команда вызывается без аргументов, выводится список сокращенных команд. Бо¬ лее подробно рассмотрена в гл. 25. @ Используется для инициализации числовой переменной и для выполнения ло¬ гической или арифметической операции над переменной. Когда эта команда вы¬ зывается без аргументов, выводится список объявленных переменных. Более подробно описана в гл. 26. break Используется для прекращения ближайшего к ней цикла while или foreach. Выполнение возобновляется с оператора, находящегося за ближайшим операто¬ ром end. Более подробно описана в гл. 27. breaksw Служит для завершения оператора case в структуре switch. Более под¬ робно рассматривается при описании команды switch в гл. 27. case Используется в структуре switch; описывается в гл. 27 при рассмотрении структуры switch. cd или chdir name Используется для установки в качестве рабочего каталога ин¬ терпретатора указанного каталога-аргумента (name). Если аргумент не задан, ва¬ шим рабочим каталогом будет начальный каталог. Аргумент должен быть состав¬ ным именем. continue Передает управление ближайшей команде while или foreach. Более под¬ робно рассматривается в гл. 27. default Используется в операторе switch для обработки случая, когда ни для од¬ ного из операторов case не обнаружено совпадение с моделью. Эта команда должна находиться после операторов case. Более подробно рассмотрена в гл. 27. echo string Эквивалентна команде echo интерпретатора В-shell. Когда команда echo вызывается с \с, она блокирует вывод знака NL (newline) в конце при выво¬ де строки. else Используется в операторе if. Более подробно рассматривается в гл. 27. end Используется в операторах while и foreach. Каждый оператор while или foreach должен заканчиваться командой end. Рассматривается, например, с опе¬ ратором while. endsw Аналогична команде end; эта команда должна закрывать структуру switch. Более подробно рассматривается при описании оператора switch в гл. 27. exec Выполняет аргумент команды в текущем интерпретаторе shell без возврата к вызывающей программе. Например: % # cat example if -d $argvC1] then cd $argvC1] exec pwd echo ’This line is never displayed1 В представленной выше программе последняя строка никогда не будет выпол¬ нена, потому что команда exec после выполнения команды pwd передаст управ¬ ление интерпретатору C-shell и никогда не вернется в программу example.
Описание терминала для редактора vi 381 exit Эта команда завершит выполнение программы и возвратит управление вызы¬ вающей программе (родительскому процессу), fforeach Рассматривается в гл. 27. goto Рассматривается в гл. 27. history Рассматривается в гл. 25. if Рассматривается в гл. 27. Iogin Вызывается автоматически процессом getty при выполнении последова¬ тельности действий входа в систему. Когда вызывается пользователем, она вы¬ водит текущего пользователя из системы. Iogout Когда переменная ignoreeof установлена, эта команда дает вам возмож¬ ность только выйти из системы. Если файл .logout существует, интерпретатор вы¬ полняет этот файл перед выходом. set Используется для инициализации переменных. Более подробно рассматрива¬ ется в гл. 25. setenv Позволяет инициализировать переменные, такие, как TERM, и передавать значения этих переменных среде. shift Сдвигает аргументы на одну позицию влево. Подробно рассматривается в гл. 27. source Аналогична команде fe В-shell. При вызове эта команда выполняет файл- аргумент без создания нового процесса. Ее отличие от команды exec состоит в том, что она возвращает управление вызывающей программе после завершения ее выполнения. switch Команда ветвления по многим направлениям. Рассматривается в гл. 27. time Когда вызывается эта команда с другой командой в качестве своего аргу¬ мента, выводится время выполнения команды, указанной аргументом в команде time Выводимая информация эквивалентна хранящейся в переменной time. unalias Удаляет псевдокоманду из списка псевдокоманд, unset Удаляет определение переменной из списка переменных, while Команда рассматривается в гл. 27. Приложение 8. Описание терминала для редактора vi Процедуры начальной установки В основном каталоге letc находится файл, называемый termcap (сокращение от слов terminal capability — характеристики терминала). Этот файл содержит сокра¬ щенные описания всех характеристик терминалов, которые работают с вашей си¬ стемой Юникс. В каждом описании содержатся: альтернативные имена данного терминала, размер его экрана, базовые функции (типа действий «возврат на одну позицию», «автоматическое отслеживание границ»), коды, требуемые для очистки экрана, установки курсора в исходную позицию, смещения курсора в различных направлениях и т. д. Описание состоит только из одной строки для простого тер¬ минала и свыше 30 строк для сложного терминала. Например, для описания терминала типа Lear Siegler ADM-3 в файле будет на¬ ходиться следующая запись: Имена терминала 1 i l3|adm3|3| 1 si | adm3: bs: am: 1 i #24: co#80: с l=AZ t t Характеристики терминала
382 Приложение 8 В этой однострочной записи заданы четыре альтернативных имени терминала (разделены вертикальными линиями): 13 (el three) adm3 3 lsi adm3 В записи заданы также пять основных характеристик терминала (разделены двоеточием): bs am li#24 co#80 Cl = AZ — возврат на одну позицию (средство для возврата курсора назад со стиранием); — автоматическое отслеживание границ («заворачивание» текста на границе экрана); — 24 строки для изображения на экране; — 80 позиций на строке; — очистка (стирание содержимого экрана) по команде CTRL-Z. Действия при наличии записи о терминале в файле termcap Если в файле letcltermcap уже имеется запись о вашем терминале, то вам доста¬ точно лишь идентифицировать ваш терминал через интерпретатор shell. Такое действие заключается в установке значения для shell-переменной TERM (сокраще¬ ние от слова terminal). Например, если вы используете терминал типа Lear Siegler ADM-3, то вам достаточно выбрать одно из альтернативных имен и присвоить его shell-переменной TERM: В-shell C-shell $ TERM=adm3; export TERM % setenv TERM adm3 Кроме того, используйте редактор ed для выбора в ваш начальный каталог файла, который называется .profile (В-shell), либо .login (C-shell). Далее необходи¬ мо поместить рассмотренный текст в виде строки в этот файл. Теперь интерпре¬ татор shell системы Юникс будет автоматически обращаться к вашему терминалу как к терминалу типа Lear Siegler ADM-3 (после выполнения вами процедуры вхо- да). Действия при отсутствии записи о терминале в файле termcap Если в файле letcltermcap нет записи о вашем терминале, тогда вы должны буде¬ те сами добавить эту запись (хотя не для всех терминалов эта задача простая). Ниже показано, как составить описание вашего терминала и как приступить к ра¬ боте с редактором vi. Замечания по начальной установке Прежде чем переходить к использованию редактора vi, вы должны быть увере¬ ны, что выполнены два следующие условия: • В файле letcltermcap находится запись, которая описывает ваш терминал в си¬ стеме Юникс. • Вы установили соответствие между терминалом, описанным в файле letcltermcap, и shell-переменной TERM (либо с помощью командной строки, либо с помощью вашего входного файла log-in file. Кроме того, эта переменная была пе¬ редана.
Описание терминала для редактора vi 383 Разработка записи о терминале Предположим, что вы проверили файл /etc/termcap в системе и обнаружили, что в нем отсутствует запись о вашем терминале. Что делать в такой ситуации? Если вы принадлежите к числу «искателей приключений», можете составить описание сами. В противном случае вы должны обратиться за помощью. Вы можете обна¬ ружить, что файл /etc/termcap в вашей системе доступен только для чтения. Если это так, вам необходимо обратиться к системному администратору для получе¬ ния временного разрешения произвести запись вашего описания в файл или же вы можете создать ваш собственный небольшой файл на время разработки опи¬ сания терминала. Вы можете обнаружить, что ваша система не допускает использования имени /etc/termcap при работе с вашим каталогом. Тогда вы должны подыскать другое имя, похожее на первое. Допустим, вы решили назвать ваш файл, состоящий из одной записи, именем tcap. Теперь начните редактирование этого файла и вве¬ дите информацию о вашем терминале. Возникает вопрос: каким образом интер¬ претатор shell узнает, что вы пользуетесь вашей записью вместо записи из из¬ вестного файла? Ответ простой: вы сообщите об этом интерпретатору shell. Вы должны сообщить интерпретатору shell имя файла, который содержит описание вашего терминала (в рассматриваемом примере таким именем является tcap), вме¬ сто имени файла /etc/termcap. Кроме того, вы должны сообщить интерпретатору shell имя самого описания. Ниже приведены команды, которые необходимо набрать на вашем терминале: В-shell C-chell $ TERMCAP=/usr7robin cap % setenv TERMCAP /usr/robin cap $ export TERMCAP $ TERM=newterm %setenv TERM newterm $ export TERM В этих двух примерах показано, как вы должны помещать описание, называе¬ мое newterm в файл с именем tcap. В C-shell действие по команде setenv включа¬ ет присваивание значения shell-переменной и передачу данного значения. Набираемые в командной строке такого рода команды имеют действие толь¬ ко на время вашей текущей работы с Юникс. При выходе из системы действие команд прекращается. Если вам необходимо устанавливать действие такого рода команд каждый раз при вхождении в систему, вы должны разместить их в ваш входной файл log-in file (в В-shell файл называют .profile, а в C-shell — .login). До¬ статочно добавить командные предложения, показанные выше, к этому файлу и они будут автоматически активизироваться. После этого удостоверьтесь, что в составе вашего входного файла находится предложение, подобное следующему: stty erase ИАНМ kiU ,,AD" Это предложение устанавливает вашему терминалу символ для осуществления возврата на одну позицию со стиранием информации в позиции (в данном приме¬ ре это CTRL-H), а также символ для «уничтожения» процесса с вашего терминала (в данном примере это CTRL-D). Вы не сможете правильно использовать редактор vi, если такие предложения будут недоступны из вашего входного файла log-in file. Процесс описания вашего терминала с помощью записи в файле termcap включает просмотр инструкции, где описано требуемое действие, а также нахож¬
384 Приложение 9 дение кодов, которые используются для выполнения различных операций на ва¬ шем терминале. После выполнения этих действий вы устанавливаете имя соот¬ ветствующей Гегтсар-переменной и набираете требуемое предписывающее пред¬ ложение (предписывающие предложения разделяются двоеточием). Например, вы узнали из инструкции к вашему терминалу, что кодом для очистки (стирания) изображения на экране до конца строки является CTRL-N. Обратившись в разд. 5 к описанию termcap в UNIX Programmer’s Manual, вы найдете, что для перемен¬ ной, которая предназначена для описания такого рода действия, установлено имя се. Тогда вы должны набрать следующее: ce=AN Предположим, что код для очистки изображения до конца экрана равен CTRL-0. Поскольку соответствующая termcap-переменная носит имя cd, вы дол¬ жны добавить следующее предписывающее предложение на строке: ce=AN:cd=A0 Когда вы набираете данные записи, пользуйтесь символом Л, за которым следует буква. Для набора последовательности переключения (типа ESC-L) используйте для представления символа прописную букву E, которой предшествует обратная косая черта \: \EL Это все, что мы хотели сказать о процессе конструирования записи в файле termcap. Для более подробного изучения материала требуется ознакомиться с тремя статьями Вилла Татилла в первых трех номерах журнала UNIX/WORLD (1984). Приложение 9. Различные версии системы Юникс Команды различных версий Ниже приведены списки команд, которые используются в наиболее распростра¬ ненных версиях Юникс: Версия 7, Система III, реализации BSD4.1 и 4.2, Ксеникс 2.3. Команды системы Версии 7: ас deroff ln pubindex tr adb df login pwd tee ar diff look quot test arcv diff3 lookaU ranUb tk as du lorder ratfor time at dump lpr rm tp awk dumpdir ls rmdir tr bas echo m4 refer troff basename ed mail restor true bc egrep make rev tsort
Различные версии системы Юникс 385 cal enroU man roff tty calendar eqn mesg sa uniq cat expr mkdir sed units cb factor mv sh uucp cc false ncheck size uulog chkeq fgrep newgrp sleep uux chgrp Ше nice sort waU chmod find nm speU wc chown fsck nohup spHne who ch*i f77 nroff spHt write cmp graph od strip xget col grep passwd struct xsend comm icheck plot stty yacc cp iostat pr su crypt join prep sum cu kiU primes sync date ld prof tabs dc learn ps tail dcheck lex pstat tar dd Hnt ptx tbl Команды Системы III Система III включает в свой состав большинство команд системы Версии 7, а так¬ же следующие команды: acctcom delta kun rsh unpack admin dfl Hne sact uuname banner diffmk logname sag uupick bdiff dircmp mm scc uustat bfs dirname mmcheck sccsdiff uuwhat bs env mmt sdb vpmc cdc errpt news sdiff vpr checkcw get nl send 300 comb getopt pack sno 300s cpio greek paste spUt 4014 cref help pcat timex 450 cspUt hp prs tplot ct hyphen reform typo cut id regcmp uname cw kas rjestat unget
386 Приложение 9 Команды системы 4.1 BSD В состав системы 4.1BSD включены большинство команд системы Версии 7, а также следующие команды: clear ex more ssp vi csh freq num strings view ctags head reset tra whereis e last script tset whoami edit mkstr see ul xstr Команды системы 4.2BSD В состав системы 4.2BSD включены большинство команд системы Версии 7, а также большинство команд системы 4.1BSD (за исключением команд freq, num, see, spp, tra), а также следующие команды: addabib ftp newaUases soeHm uusend apply gprof page sortbit vgrind apropos groups pagesize speUin vlp arll hostid pc speUout vmstat biff hostname pdc style vplot chsh indent Pi symorder vpq colcrt indxbib pix sysUne vprint cohra instaU pmerge t300 vprm compact lastcomm print t300s vtroff dbx leave printenv t450 w diction Ub prmail talk whatis error Hsp pti tek which expand Uszt px tebiet whois explain lock pxp tftp yes eyacc lookbib pxref tip f lpq quota trman fed lprm rcp u finger lptest rlogin uncompact fmt bcref roftbib unexpand fold mail ruptime unifdef force mailq ruusend uptime fp mesg rwho users fpr mt score uudecode from netstat secs uuencode fspHt new sendbug uupoU
Различные версии системы Юникс 387 Система Ксеникс Усовершенствования Система Ксеникс была разработана в конце 70-х и начале 80-х годов фирмой Microsoft для удовлетворения потребностей различных категорий пользователей, поскольку система Юникс была ориентирована только на научно-исследователь¬ ские работы и не обладала многими необходимыми свойствами. Она представля¬ ет собой наиболее совершенный вариант системы Юникс и учитывает уникаль¬ ные характеристики каждого из основных микропроцессоров, используемых в на¬ иболее современных микроЭВМ (lntel 8086 и 8088, Motorola 68 000 и Zilog Z8000). Например, в микропроцессорах 8086 и 8088 система Ксеникс использует сегмен¬ тацию памяти, динамическую перемещаемость кодов, разделение данных и ко¬ манд, ввод-вывод через механизм страничной организации памяти, а также ис¬ пользует мультиобработку. Мини-ЭВМ, на которых разрабатывалась Ксеникс, не обладали достаточным количеством ресурсов памяти и центрального процессо¬ ра, но обращение к диску было быстрым. Современные персональные компьюте¬ ры характеризуются богатыми ресурсами памяти и центрального процессора и относительно медленным обращением к диску. Ксеникс согласовывает эти разли¬ чия, например, путем увеличения скорости передачи данных и уменьшения доли свопинга программ с диска и на диск. К числу других усовершенствований Юникс относятся: аннулирование нерабо¬ чих секторов диска, интерактивная конфигурация системы, встроенная арифме¬ тика с плавающей точкой, регистрация ошибок устройств, автоматическое вос¬ становление файлов системы, оптимизация в Си-компиляторе, обнаружение раз¬ нообразных ошибок. Дополнительные возможности Дополнительные возможности предназначены для упрощения реализации сете¬ вых организаций и баз данных. Ксеникс обеспечивает синхронизацию блокирова¬ ния на уровне записей и файлов. Благодаря этому программа может приобрести исключающий доступ к записи, группе записей или даже файлу. Тем самым уст¬ раняются ошибки, которые могут возникнуть в результате того, что не одна, а не¬ сколько программ пытаются получить доступ к записи (файлу) и изменить содер¬ жимое записи (файла). Для управления решением различных задач в составе Ксеникс имеются меха¬ низмы семафоров и буферирования сообщений. Механизм семафоров позволяет двум различным задачам проводить синхронизацию путем посылки друг другу простых сигналов. Механизм буферирования сообщений позволяет устанавли¬ вать взаимосвязи (информационные) независимым задачам. К дополнительным возможностям относятся: средство «загрузки вразброс» (размещение сегментов программы в несмежных областях памяти), синхрониза¬ ция процесса записи информации на диск и неблокированный способ считыва¬ ния записей с диска с целью избежания ненужного ожидания. Команды системы Ксеникс версии 2.3 В состав Ксеникс версии 2.3 входят большинство команд системы Версии 7, а также следующие команды: asktime enable mkfs printenv (BSD) shutdown config finger (BSD) mknod random strings (BSD) сору head (BSD) mkstr (BSD) rmusr touch ctags (BSD) 1 mkusr sddate tset (BSD) disable lc more (BSD) settime vi (BSD) wait xstr (BSD)
Предметный указатель Аналоговые сигналы 68 Аргумент с HOMepoM(C-shell) 428 ARPANET 65 Асинхронная связь 69 А S С I I 70 - 73 Видимые символы 71 Встроенные команды C-shell 354, 380 Вход в систему 16 Вывод управляющих символов в ed 96 Выделение текста в ms 245 Вызов другой системы Юникс 63, 64 Выполнение 0anna(C-shell) 344 Выполнение команд Юникс в ed 128 — 136 Выход из редактора vi 184 Выход из системы 18 Вычисление арифметических выраже¬ ний 294 Группирование команд (B-shell) 282 Дескриптор файла (B-shell) 272 Директивы интерпретатора shell 282 — 285 Дуплексный режим 70 Завершающие сообщения 342 Игнорирование знака конца файла 340 Изменение даты в ms 246 Изменение текста в ed 91, 92 в vi 145, 160 — 166 Использование двухколонного форма¬ та 257 — 258 — заголовков в ms 244 Калькуляторы 22 Каталог, — изменение 35 — начальный 268 — описание 25 — 28, 34 — отображение содержимого 35 — переименование 36 — создание 35 — удаление 35 — bin 25 — dev 26 — etc 26 Ключи при редактировании в vi 217 — 220 Команда bc 22 — break (B-shell) 305, 306 —break (C-shell) 350 Команда calender 62 — case (B-shell) 314, 315 — cat 29, 46 — cd 35 — chmod 38, 39 — comm 54, 55 — continue (B-shell) 306 — continue (C-shell) 350, 351 — cp 30 — crypt 66, 67 — cu 63 — dc 22 — diff 53 — echo 288 — exit (B-shell) 306 — exit (C-shell) 352 — expr 295 — false 303 — file 48 — for 307 — greep 52 — head 47 — kill 21 — learn 23 — Ipr 57 — Is 34 — mail 61 — man 23 — mesg 63 — more 47 — mv 30 — nice 279 — passwd 18 — pr 57 — prep 51 — ps 21, 277 — pwd 35 — read 289 — rm 31 — rmdir 36 — sort 49 — sp 48 — spell 53 — tail 47 — tee 282 — tr 55 — trap 315 — true 303 — unig 51 — until 304 — uucp 64 — wc 52
Предметный указатель 389 — while 303 — write 62 Команды и аргументы (B-shell) 269 — 272 Командная строка 41, 324 — 326 Конвейеры 44 — 46 Контекстный поиск в ed 103 Копирование текста из одного файла в дру¬ гой в vi 203 — 205 в ed 94 —в пределах файла в vi 192 — 197 — файла 30 Ксеникс 387 Макропакет nroff, определение 250 Множественные замены в ed 106 — 109 Начало строки в ed 109 — 112 Номер порожденного процесса (C-shell) 399 Номера строк в ed 84 — 87 Объединение файлов 29 Оператор перехода 440 Операции над строками в ed 119 — 124 Определение ключей в vi 217 — сокращений в vi 215, 216 Опции редактора vi 211 — 215, 364 — 369 — форматирования текста 228 — 230 Отладка (B-shell) 316 Отмена выделения текста (B-shell) 246 Паскаль 136 Передача переменных shell 269 Переменные B-shell 289 — 293 — текста в файле в vi 185 — 192 Подсказка в B-shell 267, 268 — в C-shell 319 Подсоединение текста в vi 156 Подстановка результатов выполнения ко¬ манды (B-shell) 293 — 296 Подсчет строк, слов, символов 52 Поиск и простые замены в ed 101 — 105 Последовательности переключения 73 Посылка и получение почты 61 Право доступа 36 — 39 Прикладные программы 12 Программирование B-shell 266 — 317 Протокол связи 69 Процедуры B-shell 287, 288 Псевдокоманды (C-shell) 326 — 328 Работа с каталогами 34 — 36 Разметка страниц 246 Редактирование более одного файла в vi 198 — другого файла в ed 98 — использование редактирующего текста в ed 124 — начало 75 — окончание 148 Связь с Юникс 60 — 74 Си, выполнение и модификация прог¬ рамм 129 —136 C-shell,nporpaMMnpoBaHne 318 — 355 Смешанная проверка (B-shell) 313 Содержимое файлов,вывод 29 Создание файла 29 Сравнение цепочек символов (B-shell) 312,313 — числовых величин (B-shell) 311,312 Стандартный ввод,вывод и диагностика (B-shell) 272 — 275 Строковый редактор 75 — 137 Теги в программах 209 текстовых файлах 208 Удаление командной строки 19 — текста в ed 90, 102 vi 1 147, 166 — файла 31 Управление курсом в vi 152 — 155 — прерываниями C-shell 354 B-shell 315 — процессом 20, 21 — экраном дисплея в vi 155, 156 Управляющие символы 70, 71 Условное выполнение команд (B-shell) 283, 284 Условный оператор 308, 345 — 347 Установление прописных букв в vi 148 Файловая система 25 — 40 Файлы, именование 26 — 27 — определение содержимого 48 — сортировка 49 — сравнение 53 Фильтры (программы) 281 Фоновые команды (B-shell) 277 — 279 — процессы, исполнение 20 — 21 окончание 280 Форматирование таблиц 255 — 257 — текста в ms 222 — 249 Фортран 136 Цифровые сигналы 68 Чтение файлов в ed 83 Шифрование информации 66 Язык Си 9, 13, 130 — 136
Оглавление Предисловие редактора перевода 5 Предисловие авторов 6 Часть I. Основные сведения о системе Юникс 7 Глава 1. Введение в систему Юникс 7 Глава 2. Система Юникс. Основные понятия 14 Глава 3. Файловая система Юникс 25 Глава 4. Команды системы Юникс 41 Глава б.СвязьссистемойЮникс 60 Часть II. Редактирование текста с помощью редактора ed 75 Глава 6. Введение в строковый редакторес! 75 Глава 7. Манипулирование полными строками с помощью редакто¬ ра ed 88 Глава 8. Внесение изменений в строку с использованием редакто- paed 100 Глава 9. Техника редактирования с использованием peflaKTopaed 119 Глава 10. Выполнение команд системы Юникс при использовании ре¬ дактора ed 128 Часть III. Редактирование текста с помощью редакторов vi и ex 138 Глава 11. Введение в визуальный редактор vi 138 Глава 12. Выполнение изменений с помощью редактора vi 151 Глава 13. Изменение и удаление текста с помощью редактора vi 160 Глава 14. Поиски и замена текста с помощью редактора vi 172 Глава 15. Выполнение изменений в файле с помощью редактора vi 184 Глава 16. Использование редактора vi при работе с несколькими фай¬ лами 198 Глава 17. Настройка характеристик peflaKTopavi 211 Часть IV. Обработка и форматирование текста 222 Глава 18. Обработка текста и чисел 222 Глава 19. Форматирование с использованием команды nroff. Исполь¬ зование макропакета ms 235 Глава 20. Некоторые способы форматирования текста с использова¬ нием nroff 249 Часть V. Программирование на языке shell системы Юникс 268 Глава 21. Введение в B-shell 268 Глава 22. Процессы интерпретатора B-shell 277 Глава 23. Переменные интерпретатора B-shell 287 Глава 24. Управление программами в языке B-shell 302 Глава25.ВведениевС-зИеИ 318 Глава 26. Переменные C-shell 331 Глава 27. Процедуры интерпретатора C-shell 344 Приложение 1. Краткое описание команд и символов общего назна¬ чения 356 Приложение 2. Средства редактора ed 358 Приложение 3. Команды редакторов vi и ex 360 Приложение 4. Опции редактора vi 364 Приложение 5. Средства запросов на форматирование 370 Приложение 6. Краткое описание интерпретатора B-shell 371 Приложение 7. Краткое описание интерпретатора C-shell 376 Приложение 8. Описание терминала для редактора vi 381 Приложение 9. Различные версии системы Юникс 384 Предметный указатель 388
УВАЖАЕМЫЙ ЧИТАТЕЛЬ ! Ваши замечания о содержании книги, ее оформлении, качестве перево¬ да и другие просим присылать по адресу: 129820, Москва, И-110, ГСП, 1-й Рижский nep., 2, изд-во «Мир».
Учебное издание Дуглас Топхем, Хай Ван Чыонг Юникс и Ксеникс Зам. зав. редакцией Э.Н. Бадиков Ст. научный редактор И.М. Андреева Мл. научный редактор B.H. Соколова Художник A.B. Захаров Художественный редактор Н.И. Иванов Технический редактор Л.С. Тимофеева Корректор Р.Л. Вибке ИБ №6409 Подписано к печати 23.06.88. Формат 70x100 1/16. Бумагаофсетная №1. Гарнитура таймс. Печать офсетная. Обьем 12,25 бум.л. Усл. печ. л. 31,85. Усл. кр.-отт. 63,70. Уч.-изд.л. 25,67. Изд. №6/5507 Тираж 40000 экз. Зак.771. Цена 2 p. 20 к. ИЗДАТЕЛЬСТВО ”МИР” В/О ’’Совэкспорткнига’ Государственного комитета СССР по делам издательств, полиграфии и книжной торговли. Набрано в Межиздательском фотонаборном центре Издательства ”Мир” 129820, ГСП, Москва, И-110, 1-й Рижский nep., 2. Можайский полиграфкомбинат В/О ’’Совэкспорткнига” Государственного комитета СССР по делам издательств, полиграфии и книжной торговли. 143200, Можайск, ул. Мира, 93.