Страница:
отличаются, вы должны выяснить их. Обратите внимание, что в файле
/etc/termcap символ ESCAPE представлен как \E. Это не годится для
today, и вы должны изменить такое представление на настоящий ESCAPE.
Поскольку ESCAPE является символом выхода из режима ввода в редакторе
vi, вы должны использовать команду control-V в этом редакторе для вво-
да управляющих символов. Последовательность control-V вызывает печать
символа ^, а ESCAPE - печать символа [. Таким образом, реальная коман-
да входа в инверсный режим в редакторе vi представлена последователь-
ностью ^[[7m. Эта команда включает символы ^[ в качестве ESCAPE и за-
тем обычные символы [7m для изменения режима.
Теперь, когда характеристики терминала учтены, цель утилиты today
- выделить текущий день календаря в инверсном виде, а все остальное
оставить в обычном виде. Это делается путем передачи по конвейеру вы-
хода команды cal команде sed. Утилита sed находит число в выходных
данных и подставляет специальную графическую ESC-последовательность.
Поскольку ваш терминал использует специальные символы для изменения
режима, вы не увидите их выдачи на экран.
Данная программа не имеет опций или какого-то особого входа. Она
распечатывает календарь с отмеченным сегодняшним днем.
В строке 4 выполняется инициализация переменной SYSV значением
"n". Это заставляет программу переходить к особой области, в которой
жестко закодированы управляющие коды терминала, определенные вручную.
Если вы работаете с последними версиями системы System V, то вам нуж-
но, чтобы эта переменная имела значение "y".
В строке 6 позиционным параметрам присваивается результат команды
date. Мы обратимся к этим значениям позже.
Строки 8-16 - это остальная часть программы. Они представляют со-
бой один оператор if-then-else. Строки 9-12 поддерживают принятый в
System V метод tput для получения характеристик терминала, а строки
13-15 управляют ручным способом их получения.
В обоих случаях переменным shell присваиваются ESC-последователь-
ности. Эти значения используются позже. В обоих случаях выполняется
вызов команды cal с использованием значений месяца и года, полученных
от команды date. Этот образ календаря пропускается по конвейеру через
утилиту sed, которая ищет указанный день "сегодня", также полученный
от команды date. Когда этот день найден, sed заменяет цифры дня на
последовательность включения инверсного режима, последовательность
включения режима мерцания, если он есть, и символы дня, а затем после-
довательность возврата в обычный режим работы терминала. Последняя ко-
манда sed заполняет пробелами начало строки для размещения ее в центре
экрана.
Много рабочего времени тратится на запоминание важной информации,
такой как деловые встречи, адреса, номера телефонов, расписания, учет-
ные сведения о проектах и так далее. Большинство из такой информации
может быть сохранено в системе UNIX в виде простых структурированных
текстовых файлов, которыми можно манипулировать с помощью соответству-
ющих средств. Автоматизация этой области может освободить много време-
ни для выполнения "настоящей" работы.
Хотя мощные коммерческие программы для сохранения такой информа-
ции имеются в среде MS-DOS, эти программы не имеют широкого распрост-
ранения в UNIX. Часто у вас нет необходимости в отдельной большой
программе для выполнения таких работ в UNIX. UNIX обеспечивает хороший
компромисс между легкими в применении, но не гибкими коммерческими
программами и программированием на мощных, но непростых в использова-
нии традиционных языках программирования. Возможности языка shell плюс
богатый ассортимент встроенных команд UNIX дают мощный, гибкий и СРАВ-
НИТЕЛЬНО простой в использовании компромисс. В данном разделе мы
представляем широкий набор средств управления личной информацией, ко-
торые вы можете приспособить для своих нужд.
Для шутки начнем с программы по имени jargon - генератора техни-
ческих терминов, конструирующего замысловатые фразы. С его помощью
можно удивлять людей тем, как много вы знаете, или начать прибыльную
вторую карьеру в качестве составителя рекламы. Комбинирование слов по-
рождает сотни фраз.
Затем мы рассмотрим программу phone. Phone - это командный файл,
управляемый с помощью меню, который поддерживает базу телефонных номе-
ров и сопутствующей информации. Она сводит воедино разнообразные
аспекты сопровождения базы данных и обслуживания запросов к ней.
Последнее инструментальное средство называется office. Это управ-
ляемая при помощи меню утилита, которая дает одноклавишный доступ ко
всем функциям делопроизводства. Сюда относятся почта, новости, кален-
дарь, номера телефонов и автоматические напоминания.
-------------------------------------------------------
ИМЯ: jargon
-------------------------------------------------------
Компьютеризованная версия старого настольного генератора техни-
ческих терминов.
jargon
jargon Если ввести 125 в ответ на запрос, то на выходе
125 получится фраза Total Monitored Concept
ТЕКСТ ПРОГРАММЫ jargon
1 :
2 # @(#) jargon v1.0 Technical jargon generator
Author: Russ Sage
2а Генератор технического жаргона
4 echo "\n\t\tThe Jargon Generator"
5 while :
6 do
7 echo "\nEnter a 3 digit number (000-999), ?
, or: \c"
8 read NUM
10 case $NUM in
11 "") exit;;
12 \?) cat <
14 0. Integrated 0. Management 0. Options
15 1. Total 1. Organizational 1. Flexibility
16 2. Systematized 2. Monitored 2. Capability
17 3. Parallel 3. Reciprocal 3. Mobility
18 4. Functional 4. Digital 4. Programming
19 5. Responsive 5. Logistical 5. Concept
20 6. Optional 6. Transitional 6. Time-Phase
21 7. Synchronized 7. Incremental 7. Projection
22 8. Compatible 8. Operational 8. Hardware
23 9. Balanced 9. Third-Generation 9. Contingency
24 EOF
25 continue;;
26 ???) expr "$NUM" : "^[0-9][0-9][0-9]$" > /dev/
null ||
27 { echo "\nNot a valid number, try again
"; continue; };;
28 *) echo "\nInvalid input, try again"
29 continue;;
30 esac
32 N1=`echo $NUM|cut -c1`
33 N2=`echo $NUM|cut -c2`
34 N3=`echo $NUM|cut -c3`
35 SEN=""
37 case $N1 in
38 0) SEN="${SEN}Integrated ";;
39 1) SEN="${SEN}Total ";;
40 2) SEN="${SEN}Systematized ";;
41 3) SEN="${SEN}Parallel ";;
42 4) SEN="${SEN}Functional ";;
43 5) SEN="${SEN}Responsive ";;
44 6) SEN="${SEN}Optional ";;
45 7) SEN="${SEN}Synchronized ";;
46 8) SEN="${SEN}Compatible ";;
47 9) SEN="${SEN}Balanced ";;
48 esac
50 case $N2 in
51 0) SEN="${SEN}Management ";;
52 1) SEN="${SEN}Organizational ";;
53 2) SEN="${SEN}Monitored ";;
54 3) SEN="${SEN}Reciprocal ";;
55 4) SEN="${SEN}Digital ";;
56 5) SEN="${SEN}Logistical ";;
57 6) SEN="${SEN}Transitional ";;
58 7) SEN="${SEN}Incremental ";;
59 8) SEN="${SEN}Operational ";;
60 9) SEN="${SEN}Third-Generation ";;
61 esac
63 case $N3 in
64 0) SEN="${SEN}Options";;
65 1) SEN="${SEN}Flexibility";;
66 2) SEN="${SEN}Capability";;
67 3) SEN="${SEN}Mobility";;
68 4) SEN="${SEN}Programming";;
69 5) SEN="${SEN}Concept";;
70 6) SEN="${SEN}Time-Phase";;
71 7) SEN="${SEN}Projection";;
72 8) SEN="${SEN}Hardware";;
73 9) SEN="${SEN}Contingency";;
74 esac
76 echo "\n\"$SEN\""
77 done
N1 Первая цифра числа
N2 Вторая цифра числа
N3 Третья цифра числа
NUM Число, введенное пользователем с клавиатуры
SEN Предложение, полученное из найденных слов
ОПИСАНИЕ
ЗАЧЕМ НАМ НУЖЕН jargon?
В нашем скоростном, заполненном техникой мире на нас оказывается
большое давление с целью получения каких-то результатов. К сожалению,
быстрота современной техники относится к выполнению программ, а не к
их созданию. Когда мы сделали всего лишь третью часть программы, а уже
пора ее предъявлять на рынок - как мы можем создать впечатление, что
наш продукт делает больше, чем на самом деле? Необходимо немного
пустить пыль в глаза заказчику. Пускание пыли состоит из фраз, которые
выглядят и звучат впечатляюще. При строгой проверке мы можем увидеть,
что фраза составлена из настоящих английских слов, значение которых
можно посмотреть в словаре. Эта фраза в целом совершенно бессмысленна,
но если нам повезет, то читатель этого не заметит!
Одним из простых способов получения таких вещей является наличие
таблицы взаимозаменяемых слов, которые можно использовать для состав-
ления предложений. Если у вас система BSD, то вы можете запустить
jargon вместе с программой fortune, которая имитирует случайные подар-
ки судьбы. Мудрость веков может принадлежать вам!
ЧТО ДЕЛАЕТ jargon?
Jargon - это инструмент для генерации фраз, состоящих из техни-
ческих терминов. Строится фраза, которая является комбинацией трех
слов. Первые два слова являются прилагательными, используемыми для
описания третьего слова, имени существительного. Каждое слово выбира-
ется из столбца, содержащего десять возможных слов. Именно это придает
программе jargon ее творческие способности. Она может объединять слово
из одного столбца с любым словом из другого столбца для построения
многих полезных фраз. Если вы хотите увидеть всю таблицу слов, введите
символ ?. Вот пример таблицы:
-----------------------------
|
| The Jargon Generator
|
| Enter a 3 digit number (000-999), ?, or: ?
|
| 0. Integrated 0. Management 0. Options
| 1. Total 1. Organizational 1. Flexibility
| 2. Systematized 2. Monitored 2. Capability
| 3. Parallel 3. Reciprocal 3. Mobility
| 4. Functional 4. Digital 4. Programming
| 5. Responsive 5. Logistical 5. Concept
| 6. Optional 6. Transitional 6. Time-Phase
| 7. Synchronized 7. Incremental 7. Projection
| 8. Compatible 8. Operational 8. Hardware
| 9. Balanced 9. Third-Generation 9. Contingency
|
Имеется три возможных варианта ввода. Вы можете ввести трехзнач-
ное число, знак вопроса для печати таблицы или возврат каретки для вы-
хода из программы. Проверяется, является ли строка из трех цифр до-
пустимым числом. Если все в порядке, то введенное число разбивается на
три составляющие его цифры. Каждая цифра используется как ключ поиска
в массиве из десяти слов для получения куска предложения. Затем все
слова объединяются для формирования жаргонной фразы. После этого вам
выдается запрос на дальнейший ввод.
Если вы ввели знак вопроса, печатается таблица слов, как показано
в предыдущем примере, и вам снова выдается запрос. Если был введен
только возврат каретки, то цикл, выдававший запросы, завершается и за-
канчивается выполнение программы.
Внутри самой программы выполняется только проверка на ошибки.
Программа jargon организована аналогично программе, управляемой с по-
мощью меню, однако никакого меню нет. Это просто цикл, который выпол-
няется до тех пор, пока не будет нажат возврат каретки.
1. $ jargon
898
Открывается секрет, что у меня персональный компьютер 898, то
есть Compatible Third-Generation Hardware (совместимая аппаратура
третьего поколения).
2. $ jargon
187
Оказывается это Total Operational Projection (всеобъемлющий раз-
рабатываемый проект).
Строка 4 печатает заголовок при начальном запуске программы.
Отображается возврат каретки, две табуляции и сообщение.
Строки 5-77 представляют собой один большой бесконечный цикл
while. В нем имеется всего одна точка выхода, находящаяся внутри опе-
ратора case. Строка 7 выводит приглашение, а строка 8 читает вводимый
ответ в переменную NUM.
Строки 10-30 являются оператором case, который проверяет информа-
цию, введенную с клавиатуры. Если был введен только возврат каретки,
строка 11 рассматривает это как нулевой ввод. В этом случае выполня-
ется выход из программы. Это и есть нормальная точка выхода.
Ввод вопросительного знака соответствует строке 12. Обратите вни-
мание, что знак вопроса экранирован. Это выполнено по той причине, что
символ ? имеет для shell специальное значение. Он используется как
представитель любого одиночного символа при порождении имени файла.
Для того, чтобы сделать знак вопроса обычным символом, мы должны экра-
нировать его для отмены специального значения.
В строках 12-24 команда cat получает текст из последующего фраг-
мента самой программы. Такого рода файл иногда называют "встроенным
документом". Возможность обработки встроенного документа активируется
последовательностью символов <<. Слово, которое следует за ней, явля-
ется признаком начала-окончания, в данном случае EOF. После того, как
текст будет выведен на экран, строка 25 продолжает выполнение следую-
щей итерации внешнего цикла while.
Попутно отметим: для того, чтобы увидеть, как shell управляет
встроенными документамм, посмотрите во время работы командного файла
каталог /tmp. В нем находится файл с именем "shXXXX", где XXXX - иден-
тификатор shell, создавшего этот файл. Весь встроенный документ цели-
ком помещается в этот временный файл. Затем shell выполняет переад-
ресацию своего входа на этот временный файл. Довольно простой метод.
Строка 26 соответствует всем случаям ввода, когда имеется три
символа. Эти символы могут быть буквами и/или цифрами. В этом месте
shell еще не знает, есть ли там буквы. Для проверки того, что все вве-
денные символы являются цифрами, мы должны использовать команду expr,
выполняющую дополнительный анализ. Оператор expr указывает, что нужно
сравнить строку NUM с последовательностью "начало строки, цифра, циф-
ра, цифра, конец строки". Если сопоставление успешно, expr возвращает
статус успешного возврата и программа идет дальше. Поскольку expr
возвращает число совпавших символов, этот результат должен быть пере-
направлен в каталог /dev/null.
Если сравнение завершилось неудачей, активизируется оператор ||
(мы уже видели такого рода управляющую структуру ранее), который печа-
тает сообщение об ошибке и вызывает следующую итерацию цикла while.
Такой синтаксис представляет собой то же самое, что и оператор
if-then-else. Поскольку за символами || может следовать список команд,
то внутрь простых разделителей списка {} можно вставить более одной
команды. Будьте внимательны. Если отсутствуют символы-разделители, то
оператор continue выполнится как после сообщения об ошибке, ТАК И при
успешном выполнении команды expr. Это может заставить вас заниматься
отладкой, пока вы не обнаружите, что же произошло на самом деле.
Точно такую же проверку числа можно было бы выполнить с помощью
оператора case. Синтаксис был бы таким же, за исключением зацепочных
символов ^ и $. Шаблон для оператора case выглядел бы так:
[0-9][0-9][0-9] statement;;
Я использовал оператор expr для того, чтобы показать, каким обра-
зом expr может быть использован для выполнения такого рода проверки.
Любой другой ввод перехватывается в строке 28 путем проверки на
совпадение с универсальным символом-заменителем *. Выводится сообщение
об ошибке, и оператор continue вызывает следующую итерацию цикла
while, который запрашивает новый ввод.
Обратите внимание, как shell рассматривает строки. Команда test
фактически выполняет сравнение значения строки. Несмотря на то, что
команде test(1) посвящена своя страница справочного руководства, она
является встроенной функцией shell. Если при вызове команды test
использован синтаксис =, !=, то два аргумента рассматриваются как
строки. Но если в команде test используется синтаксис вида -lt, -eq,
то производится сравнение двух аргументов-строк как чисел и выполня-
ется их числовая обработка. Эти два различных режима нельзя смешивать,
т.е. нельзя сравнивать строки при помощи числового оператора, например
str1 -eq str2.
В строках 32-34 каждая цифра вырезается из числа и помещается в
свою собственную переменную. Затем эти переменные используются в ка-
честве индекса в операторе case, который содержит магические слова.
Строка 35 инициализирует переменную SEN для сбора предложения. (Пред-
варительное замечание перед тем, как мы начнем получать письма от рев-
нителей чистоты грамматики - да, мы знаем, что то, что мы генерируем,
является фразой, а не настоящим предложением, поскольку отсутствует
глагол.) Начинаем мы с пустого предложения и добавляем к нему каждый
раз по одному слову.
Строки 37-48 представляют собой первый оператор case. Оператор
case берет значение переменной N1 и добавляет слово с таким номером к
предложению. На самом деле нет необходимости включать значение пере-
менной SEN в правую часть присваивания, поскольку еще ничего нет. Од-
нако это делает текст программы более гибким, если мы решим предвари-
тельно сгенерировать первоначальное предложение некоторыми другими
средствами. Аналогичные операторы case обрабатывают две следующие циф-
ры.
Полученное предложение выводится в строке 76 после того, как най-
дены все слова. Вы могли бы сказать, что вся эта штука представляет
собой 754 подвиг, или Synchronized Logistical Programming (Синхронизи-
рованное логическое программирование).
Можно немного поиграться с этой программой. Вы могли бы получать
случайное число, зависящее от текущего системного времени (используя
извлечение и команду expr) и основывать поиск на этом числе, а не на
числе, введенном пользователем. Вы также могли бы использовать каждую
цифру случайного числа для управления выбором слова из различных баз с
жаргонными терминами, имея, возможно, по одному файлу для каждой из
трех позиций слова и организуя цикл на случайное значение для чтения
каждого слова. Слова могли бы читаться и удаляться из файла до тех
пор, пока не прочитается слово, которое соответствует случайной цифре.
Имеется множество других возможностей. Если вы вовремя не останови-
тесь, то обнаружите, что вы написали компьютерную игру!
--------------------------------------------------------
ИМЯ: phone
--------------------------------------------------------
phone База данных с телефонными номерами
Управляемое меню средство, поддерживающее базу данных с телефон-
ными номерами
phone
phone Вызов телефонной базы данных
s Ввод опции поиска
russ Поиск номера телефона Расса
ТЕКСТ ПРОГРАММЫ phone
1 :
2 # @(#) phone v1.0 Maintain telephone database
Author: Russ Sage
2а Сопровождение телефонной базы данных
4 if [ $# -gt 0 ]
5 then echo "phone: argument error" >&2
6 echo "usage: phone" >&2
7 exit 1
8 fi
10 BASE="$HOME/.phone.list"
12 while :
13 do
14 echo "
16 phonebase = $BASE
18 PHONE MENU
19 ----------
20 add name to list
21 delete name from list
22 edit list
23 search for name in list
24 view complete list
25 - exit program
27 Press a,d,e,s,v or: \c"
28 read RSP
30 case $RSP in
31 "") exit 0
32 ;;
33 a|A) echo "\nEnter name to add ( to exit
): \c"
34 read NAME
35 if [ "$NAME" = "" ]
36 then continue
37 fi
38 echo "Enter description of person: \c"
39 read DESC
40 echo "Enter number to add: \c"
41 read NUM
42 echo "$NAME\t$DESC\t\t\t$NUM" >> $BASE
43 sort -t" " +1 -1.3b -o $BASE $BASE
44 ;;
45 d|D) echo "\nEnter name to delete ( to exit
): \c"
46 read NAME
47 if [ "$NAME" = "" ]
48 then continue
49 fi
50 sed -e "/$NAME/d" $BASE.new
51 mv $BASE.new $BASE
52 ;;
53 e|E) vi $BASE
54 ;;
55 s|S) echo "\nEnter name to search: \c"
56 read NAME
57 echo "\n----------------------------------"
58 grep -y "$NAME" $BASE
59 echo "------------------------------------"
60 ;;
61 v|V) echo "\n\tPhone List\n\t---------" &
62 more $BASE
63 echo "\nhit\c"
64 read RSP
65 ;;
66 *) echo "Not a valid command"
67 ;;
68 esac
69 done
BASE Фактическое имя файла телефонной базы данных
DESC Описание, вводимое в базу данных
NAME Имя, вводимое в базу данных
NUM Номер телефона, вводимый в базу данных
RSP Ответ пользователя на приглашение
ОПИСАНИЕ
ЗАЧЕМ НАМ НУЖЕН phone?
Телефоны представляют собой очень важную часть нашего рабочего
дня. Мы используем их для сообщения своих планов, отдачи распоряжений
и для многих других целей. Немного поразмышляем. Если почти на каждом
рабочем месте в США установлен телефон, то телефонных номеров миллио-
ны. Каким образом вы храните все ваши телефонные номера?
Нам необходима очередная база данных. Эта база данных должна уп-
равлять вводом данных, их извлечением, модификацией и удалением. У нас
теперь есть опыт в реализации программ, управляемых с помощью меню,
поэтому имеет смысл использовать меню и здесь.
ЧТО ДЕЛАЕТ phone?
Phone - это универсальная утилита для использования и управления
базой данных телефонных номеров. Полностью управляемая при помощи ме-
ню, phone содержит все необходимые функции, связанные с управлением
базой данных: добавление, удаление, просмотр, редактирование и поиск.
Файл, представляющий собой базу данных, размещен в вашем регист-
рационном каталоге. Это файл $HOME/.phone.list. Phone использует ваш
регистрационный каталог, так что один и тот же исполняемый модуль ра-
ботает для любого пользователя. Независимо от того, где размещается
командный файл phone или кто и откуда его запустил в вашей системе, вы
всегда получите именно ваш файл телефонных номеров, поскольку он подк-
лючен к вашему регистрационному каталогу посредством встроенной пере-
менной shell с именем HOME.
Имеется всего одно главное меню. Оно выводится на экран, и внизу
появляется приглашение. Большинство вариантов выбора запрашивают до-
полнительную информацию. Меню выглядит так:
------------------------
|
|
| phonebase = /usr/russ/.phone.list
|
| PHONE MENU
| ----------
| add name to list (добавить имя к списку)
| delete name from list (удалить имя из списка)
| edit list (редактировать список)
| search for name in list (поиск имени в списке)
| view complete list (просмотр списка)
| - exit program (выход из программы)
|
| Press a,d,e,s,v or:
|
В верхней строке меню выводится имя телефонной базы данных, кото-
рую вы используете. Если это не ваш файл, вы точно знаете, что прои-
зошла ошибка. Опции выбираются нажатием клавиши, соответствующей пер-
вой букве слова. Если был нажат только возврат каретки, программа за-
вершается.
1. $ phone
a
russ sage
unix master
123-4567
Такая последовательность действий используется для добавления еще
одного номера в базу данных. Вызывайте меню, выбирайте опцию добавле-
ния и в ответ на запросы утилиты phone вводите имя, описание и номер
телефона.
2. $ phone
V
Просмотр всех записей в вашей базе данных.
Строки 4-8 выполняют некоторую проверку на наличие ошибок. Если
вы вызвали phone с какими-либо аргументами, выводится сообщение об
ошибке и программа завершается. Поскольку phone управляется при помощи
меню, она не использует аргументы.
Строка 10 инициализирует переменную BASE именем файла телефонной
базы данных. Это назначение выполняется с помощью переменной HOME для
получения вашего регистрационного каталога.
Строки 12-69 представляют собой один большой бесконечный цикл
while. Вся эта структура подобна структуре других программ, управляе-
мых с помощью меню, которые мы рассмотрели. Само меню выводится опера-
тором echo. Текст меню НЕ выделен отступами подобно остальной части
программы, поскольку оператор echo воспринимает этот текст как лите-
ральные данные, включая пробелы.
Строка 28 читает ответ пользователя, а строки 30-68 представляют
собой оператор case, который проверяет значение ответа. Если был нуле-
вой ввод, программа завершается.
Если была введена буква a, выбирается опция добавления. (В
действительности каждая опция проверяется и на верхнем, и на нижнем
регистре для обеспечения гибкости). Текст программы, соответствующий
добавлению, запрашивает имя, описание и номер телефона. Если вы оказа-
лись в опции добавления случайно, используйте возможность возврата пу-
тем нажатия возврата каретки в ответ на запрос имени. Однако после то-
го, как вы ввели имя, выйти уже нельзя. Вам необходимо в этом случае
поместить в базу фиктивную запись или нажать клавишу аварийного завер-
шения для выхода из программы вообще. Описание может быть произвольной
длины, однако оно не смотрится, если очень длинное. После того как все
поля введены, вся строка помещается в конец базы данных. Отметим, что
добавляются символы табуляции для разбиения записи на поля. После это-
го база данных пересортировывается, чтобы новая запись заняла свое
место в алфавитном порядке.
Если была введена буква d, то она распознается в строке 45. Зап-
рашивается удаляемое имя. Если вводится только возврат каретки, опера-
тор continue возвращает нас обратно в цикл while и снова выводится
главное меню. Для удаления записи использована команда sed, поэтому
вводимое имя должно указываться точно в таком же виде, как оно хра-
нится в файле. Результат удаления помещается во временный файл, кото-
рый затем в строке 51 переименовывается в исходный файл базы данных.
Одной из модификаций может быть показ пользователю того, что он соби-
рается удалять, и запрос подтверждения. Если подтверждение получено,
то данные удаляются окончательно. Сейчас сделано так, что вы на самом
деле не знаете, что именно собираетесь удалять. Поэтому необходимо
точно указывать удаляемое имя. Здесь выбран относительно быстрый и не
совсем честный подход. А вообще вы даже могли бы использовать не-
посредственно редактор vi для поиска и удаления.
Опция редактирования в строке 53 выполняет только одно - вызывает
редактор vi для работы с базой телефонных номеров. Используя редактор
vi, вы можете вручную сделать файл базы данных таким, как вам нужно.
Зачастую формат входных данных "плывет" из-за разной длины. Все данные
хранятся в свободном формате и поэтому их можно как угодно смещать
вдоль строки.
Когда вы редактируете ваш файл редактором vi, все его команды ак-
тивны. Действует даже выход в shell и выполнение обычных действий с
системой. Поэтому не забудьте прекратить работу этого shell'а, иначе
вы будете весьма удивлены в конце рабочего дня при выходе из системы.
Для выхода из редактора и возврата к утилите phone используйте обычные
методы, такие как ZZ, :x и :wq.
Опция поиска в строке 55 запрашивает имя, которое нужно искать,
читает это имя, выводит декоративные элементы до и после данных и
использует утилиту grep для нахождения требуемой записи. Утилита grep
в строке 58 использует команду -y, вызывающую нечувствительность к ре-
гистру. Это означает, что вы можете производить ввод искомого элемента
как на верхнем, так и на нижнем регистре. Если не найдено ничего, то
ничего и не выводится на экран.
Опция просмотра начинается со строки 61. Сначала выводится заго-
ловок в фоновом режиме. Это делается для быстроты. На самом деле это
/etc/termcap символ ESCAPE представлен как \E. Это не годится для
today, и вы должны изменить такое представление на настоящий ESCAPE.
Поскольку ESCAPE является символом выхода из режима ввода в редакторе
vi, вы должны использовать команду control-V в этом редакторе для вво-
да управляющих символов. Последовательность control-V вызывает печать
символа ^, а ESCAPE - печать символа [. Таким образом, реальная коман-
да входа в инверсный режим в редакторе vi представлена последователь-
ностью ^[[7m. Эта команда включает символы ^[ в качестве ESCAPE и за-
тем обычные символы [7m для изменения режима.
Теперь, когда характеристики терминала учтены, цель утилиты today
- выделить текущий день календаря в инверсном виде, а все остальное
оставить в обычном виде. Это делается путем передачи по конвейеру вы-
хода команды cal команде sed. Утилита sed находит число в выходных
данных и подставляет специальную графическую ESC-последовательность.
Поскольку ваш терминал использует специальные символы для изменения
режима, вы не увидите их выдачи на экран.
Данная программа не имеет опций или какого-то особого входа. Она
распечатывает календарь с отмеченным сегодняшним днем.
В строке 4 выполняется инициализация переменной SYSV значением
"n". Это заставляет программу переходить к особой области, в которой
жестко закодированы управляющие коды терминала, определенные вручную.
Если вы работаете с последними версиями системы System V, то вам нуж-
но, чтобы эта переменная имела значение "y".
В строке 6 позиционным параметрам присваивается результат команды
date. Мы обратимся к этим значениям позже.
Строки 8-16 - это остальная часть программы. Они представляют со-
бой один оператор if-then-else. Строки 9-12 поддерживают принятый в
System V метод tput для получения характеристик терминала, а строки
13-15 управляют ручным способом их получения.
В обоих случаях переменным shell присваиваются ESC-последователь-
ности. Эти значения используются позже. В обоих случаях выполняется
вызов команды cal с использованием значений месяца и года, полученных
от команды date. Этот образ календаря пропускается по конвейеру через
утилиту sed, которая ищет указанный день "сегодня", также полученный
от команды date. Когда этот день найден, sed заменяет цифры дня на
последовательность включения инверсного режима, последовательность
включения режима мерцания, если он есть, и символы дня, а затем после-
довательность возврата в обычный режим работы терминала. Последняя ко-
манда sed заполняет пробелами начало строки для размещения ее в центре
экрана.
Много рабочего времени тратится на запоминание важной информации,
такой как деловые встречи, адреса, номера телефонов, расписания, учет-
ные сведения о проектах и так далее. Большинство из такой информации
может быть сохранено в системе UNIX в виде простых структурированных
текстовых файлов, которыми можно манипулировать с помощью соответству-
ющих средств. Автоматизация этой области может освободить много време-
ни для выполнения "настоящей" работы.
Хотя мощные коммерческие программы для сохранения такой информа-
ции имеются в среде MS-DOS, эти программы не имеют широкого распрост-
ранения в UNIX. Часто у вас нет необходимости в отдельной большой
программе для выполнения таких работ в UNIX. UNIX обеспечивает хороший
компромисс между легкими в применении, но не гибкими коммерческими
программами и программированием на мощных, но непростых в использова-
нии традиционных языках программирования. Возможности языка shell плюс
богатый ассортимент встроенных команд UNIX дают мощный, гибкий и СРАВ-
НИТЕЛЬНО простой в использовании компромисс. В данном разделе мы
представляем широкий набор средств управления личной информацией, ко-
торые вы можете приспособить для своих нужд.
Для шутки начнем с программы по имени jargon - генератора техни-
ческих терминов, конструирующего замысловатые фразы. С его помощью
можно удивлять людей тем, как много вы знаете, или начать прибыльную
вторую карьеру в качестве составителя рекламы. Комбинирование слов по-
рождает сотни фраз.
Затем мы рассмотрим программу phone. Phone - это командный файл,
управляемый с помощью меню, который поддерживает базу телефонных номе-
ров и сопутствующей информации. Она сводит воедино разнообразные
аспекты сопровождения базы данных и обслуживания запросов к ней.
Последнее инструментальное средство называется office. Это управ-
ляемая при помощи меню утилита, которая дает одноклавишный доступ ко
всем функциям делопроизводства. Сюда относятся почта, новости, кален-
дарь, номера телефонов и автоматические напоминания.
-------------------------------------------------------
ИМЯ: jargon
-------------------------------------------------------
Компьютеризованная версия старого настольного генератора техни-
ческих терминов.
jargon
jargon Если ввести 125 в ответ на запрос, то на выходе
125 получится фраза Total Monitored Concept
ТЕКСТ ПРОГРАММЫ jargon
1 :
2 # @(#) jargon v1.0 Technical jargon generator
Author: Russ Sage
2а Генератор технического жаргона
4 echo "\n\t\tThe Jargon Generator"
5 while :
6 do
7 echo "\nEnter a 3 digit number (000-999), ?
, or
8 read NUM
10 case $NUM in
11 "") exit;;
12 \?) cat <
14 0. Integrated 0. Management 0. Options
15 1. Total 1. Organizational 1. Flexibility
16 2. Systematized 2. Monitored 2. Capability
17 3. Parallel 3. Reciprocal 3. Mobility
18 4. Functional 4. Digital 4. Programming
19 5. Responsive 5. Logistical 5. Concept
20 6. Optional 6. Transitional 6. Time-Phase
21 7. Synchronized 7. Incremental 7. Projection
22 8. Compatible 8. Operational 8. Hardware
23 9. Balanced 9. Third-Generation 9. Contingency
24 EOF
25 continue;;
26 ???) expr "$NUM" : "^[0-9][0-9][0-9]$" > /dev/
null ||
27 { echo "\nNot a valid number, try again
"; continue; };;
28 *) echo "\nInvalid input, try again"
29 continue;;
30 esac
32 N1=`echo $NUM|cut -c1`
33 N2=`echo $NUM|cut -c2`
34 N3=`echo $NUM|cut -c3`
35 SEN=""
37 case $N1 in
38 0) SEN="${SEN}Integrated ";;
39 1) SEN="${SEN}Total ";;
40 2) SEN="${SEN}Systematized ";;
41 3) SEN="${SEN}Parallel ";;
42 4) SEN="${SEN}Functional ";;
43 5) SEN="${SEN}Responsive ";;
44 6) SEN="${SEN}Optional ";;
45 7) SEN="${SEN}Synchronized ";;
46 8) SEN="${SEN}Compatible ";;
47 9) SEN="${SEN}Balanced ";;
48 esac
50 case $N2 in
51 0) SEN="${SEN}Management ";;
52 1) SEN="${SEN}Organizational ";;
53 2) SEN="${SEN}Monitored ";;
54 3) SEN="${SEN}Reciprocal ";;
55 4) SEN="${SEN}Digital ";;
56 5) SEN="${SEN}Logistical ";;
57 6) SEN="${SEN}Transitional ";;
58 7) SEN="${SEN}Incremental ";;
59 8) SEN="${SEN}Operational ";;
60 9) SEN="${SEN}Third-Generation ";;
61 esac
63 case $N3 in
64 0) SEN="${SEN}Options";;
65 1) SEN="${SEN}Flexibility";;
66 2) SEN="${SEN}Capability";;
67 3) SEN="${SEN}Mobility";;
68 4) SEN="${SEN}Programming";;
69 5) SEN="${SEN}Concept";;
70 6) SEN="${SEN}Time-Phase";;
71 7) SEN="${SEN}Projection";;
72 8) SEN="${SEN}Hardware";;
73 9) SEN="${SEN}Contingency";;
74 esac
76 echo "\n\"$SEN\""
77 done
N1 Первая цифра числа
N2 Вторая цифра числа
N3 Третья цифра числа
NUM Число, введенное пользователем с клавиатуры
SEN Предложение, полученное из найденных слов
ОПИСАНИЕ
ЗАЧЕМ НАМ НУЖЕН jargon?
В нашем скоростном, заполненном техникой мире на нас оказывается
большое давление с целью получения каких-то результатов. К сожалению,
быстрота современной техники относится к выполнению программ, а не к
их созданию. Когда мы сделали всего лишь третью часть программы, а уже
пора ее предъявлять на рынок - как мы можем создать впечатление, что
наш продукт делает больше, чем на самом деле? Необходимо немного
пустить пыль в глаза заказчику. Пускание пыли состоит из фраз, которые
выглядят и звучат впечатляюще. При строгой проверке мы можем увидеть,
что фраза составлена из настоящих английских слов, значение которых
можно посмотреть в словаре. Эта фраза в целом совершенно бессмысленна,
но если нам повезет, то читатель этого не заметит!
Одним из простых способов получения таких вещей является наличие
таблицы взаимозаменяемых слов, которые можно использовать для состав-
ления предложений. Если у вас система BSD, то вы можете запустить
jargon вместе с программой fortune, которая имитирует случайные подар-
ки судьбы. Мудрость веков может принадлежать вам!
ЧТО ДЕЛАЕТ jargon?
Jargon - это инструмент для генерации фраз, состоящих из техни-
ческих терминов. Строится фраза, которая является комбинацией трех
слов. Первые два слова являются прилагательными, используемыми для
описания третьего слова, имени существительного. Каждое слово выбира-
ется из столбца, содержащего десять возможных слов. Именно это придает
программе jargon ее творческие способности. Она может объединять слово
из одного столбца с любым словом из другого столбца для построения
многих полезных фраз. Если вы хотите увидеть всю таблицу слов, введите
символ ?. Вот пример таблицы:
-----------------------------
|
| The Jargon Generator
|
| Enter a 3 digit number (000-999), ?, or
|
| 0. Integrated 0. Management 0. Options
| 1. Total 1. Organizational 1. Flexibility
| 2. Systematized 2. Monitored 2. Capability
| 3. Parallel 3. Reciprocal 3. Mobility
| 4. Functional 4. Digital 4. Programming
| 5. Responsive 5. Logistical 5. Concept
| 6. Optional 6. Transitional 6. Time-Phase
| 7. Synchronized 7. Incremental 7. Projection
| 8. Compatible 8. Operational 8. Hardware
| 9. Balanced 9. Third-Generation 9. Contingency
|
Имеется три возможных варианта ввода. Вы можете ввести трехзнач-
ное число, знак вопроса для печати таблицы или возврат каретки для вы-
хода из программы. Проверяется, является ли строка из трех цифр до-
пустимым числом. Если все в порядке, то введенное число разбивается на
три составляющие его цифры. Каждая цифра используется как ключ поиска
в массиве из десяти слов для получения куска предложения. Затем все
слова объединяются для формирования жаргонной фразы. После этого вам
выдается запрос на дальнейший ввод.
Если вы ввели знак вопроса, печатается таблица слов, как показано
в предыдущем примере, и вам снова выдается запрос. Если был введен
только возврат каретки, то цикл, выдававший запросы, завершается и за-
канчивается выполнение программы.
Внутри самой программы выполняется только проверка на ошибки.
Программа jargon организована аналогично программе, управляемой с по-
мощью меню, однако никакого меню нет. Это просто цикл, который выпол-
няется до тех пор, пока не будет нажат возврат каретки.
1. $ jargon
898
Открывается секрет, что у меня персональный компьютер 898, то
есть Compatible Third-Generation Hardware (совместимая аппаратура
третьего поколения).
2. $ jargon
187
Оказывается это Total Operational Projection (всеобъемлющий раз-
рабатываемый проект).
Строка 4 печатает заголовок при начальном запуске программы.
Отображается возврат каретки, две табуляции и сообщение.
Строки 5-77 представляют собой один большой бесконечный цикл
while. В нем имеется всего одна точка выхода, находящаяся внутри опе-
ратора case. Строка 7 выводит приглашение, а строка 8 читает вводимый
ответ в переменную NUM.
Строки 10-30 являются оператором case, который проверяет информа-
цию, введенную с клавиатуры. Если был введен только возврат каретки,
строка 11 рассматривает это как нулевой ввод. В этом случае выполня-
ется выход из программы. Это и есть нормальная точка выхода.
Ввод вопросительного знака соответствует строке 12. Обратите вни-
мание, что знак вопроса экранирован. Это выполнено по той причине, что
символ ? имеет для shell специальное значение. Он используется как
представитель любого одиночного символа при порождении имени файла.
Для того, чтобы сделать знак вопроса обычным символом, мы должны экра-
нировать его для отмены специального значения.
В строках 12-24 команда cat получает текст из последующего фраг-
мента самой программы. Такого рода файл иногда называют "встроенным
документом". Возможность обработки встроенного документа активируется
последовательностью символов <<. Слово, которое следует за ней, явля-
ется признаком начала-окончания, в данном случае EOF. После того, как
текст будет выведен на экран, строка 25 продолжает выполнение следую-
щей итерации внешнего цикла while.
Попутно отметим: для того, чтобы увидеть, как shell управляет
встроенными документамм, посмотрите во время работы командного файла
каталог /tmp. В нем находится файл с именем "shXXXX", где XXXX - иден-
тификатор shell, создавшего этот файл. Весь встроенный документ цели-
ком помещается в этот временный файл. Затем shell выполняет переад-
ресацию своего входа на этот временный файл. Довольно простой метод.
Строка 26 соответствует всем случаям ввода, когда имеется три
символа. Эти символы могут быть буквами и/или цифрами. В этом месте
shell еще не знает, есть ли там буквы. Для проверки того, что все вве-
денные символы являются цифрами, мы должны использовать команду expr,
выполняющую дополнительный анализ. Оператор expr указывает, что нужно
сравнить строку NUM с последовательностью "начало строки, цифра, циф-
ра, цифра, конец строки". Если сопоставление успешно, expr возвращает
статус успешного возврата и программа идет дальше. Поскольку expr
возвращает число совпавших символов, этот результат должен быть пере-
направлен в каталог /dev/null.
Если сравнение завершилось неудачей, активизируется оператор ||
(мы уже видели такого рода управляющую структуру ранее), который печа-
тает сообщение об ошибке и вызывает следующую итерацию цикла while.
Такой синтаксис представляет собой то же самое, что и оператор
if-then-else. Поскольку за символами || может следовать список команд,
то внутрь простых разделителей списка {} можно вставить более одной
команды. Будьте внимательны. Если отсутствуют символы-разделители, то
оператор continue выполнится как после сообщения об ошибке, ТАК И при
успешном выполнении команды expr. Это может заставить вас заниматься
отладкой, пока вы не обнаружите, что же произошло на самом деле.
Точно такую же проверку числа можно было бы выполнить с помощью
оператора case. Синтаксис был бы таким же, за исключением зацепочных
символов ^ и $. Шаблон для оператора case выглядел бы так:
[0-9][0-9][0-9] statement;;
Я использовал оператор expr для того, чтобы показать, каким обра-
зом expr может быть использован для выполнения такого рода проверки.
Любой другой ввод перехватывается в строке 28 путем проверки на
совпадение с универсальным символом-заменителем *. Выводится сообщение
об ошибке, и оператор continue вызывает следующую итерацию цикла
while, который запрашивает новый ввод.
Обратите внимание, как shell рассматривает строки. Команда test
фактически выполняет сравнение значения строки. Несмотря на то, что
команде test(1) посвящена своя страница справочного руководства, она
является встроенной функцией shell. Если при вызове команды test
использован синтаксис =, !=, то два аргумента рассматриваются как
строки. Но если в команде test используется синтаксис вида -lt, -eq,
то производится сравнение двух аргументов-строк как чисел и выполня-
ется их числовая обработка. Эти два различных режима нельзя смешивать,
т.е. нельзя сравнивать строки при помощи числового оператора, например
str1 -eq str2.
В строках 32-34 каждая цифра вырезается из числа и помещается в
свою собственную переменную. Затем эти переменные используются в ка-
честве индекса в операторе case, который содержит магические слова.
Строка 35 инициализирует переменную SEN для сбора предложения. (Пред-
варительное замечание перед тем, как мы начнем получать письма от рев-
нителей чистоты грамматики - да, мы знаем, что то, что мы генерируем,
является фразой, а не настоящим предложением, поскольку отсутствует
глагол.) Начинаем мы с пустого предложения и добавляем к нему каждый
раз по одному слову.
Строки 37-48 представляют собой первый оператор case. Оператор
case берет значение переменной N1 и добавляет слово с таким номером к
предложению. На самом деле нет необходимости включать значение пере-
менной SEN в правую часть присваивания, поскольку еще ничего нет. Од-
нако это делает текст программы более гибким, если мы решим предвари-
тельно сгенерировать первоначальное предложение некоторыми другими
средствами. Аналогичные операторы case обрабатывают две следующие циф-
ры.
Полученное предложение выводится в строке 76 после того, как най-
дены все слова. Вы могли бы сказать, что вся эта штука представляет
собой 754 подвиг, или Synchronized Logistical Programming (Синхронизи-
рованное логическое программирование).
Можно немного поиграться с этой программой. Вы могли бы получать
случайное число, зависящее от текущего системного времени (используя
извлечение и команду expr) и основывать поиск на этом числе, а не на
числе, введенном пользователем. Вы также могли бы использовать каждую
цифру случайного числа для управления выбором слова из различных баз с
жаргонными терминами, имея, возможно, по одному файлу для каждой из
трех позиций слова и организуя цикл на случайное значение для чтения
каждого слова. Слова могли бы читаться и удаляться из файла до тех
пор, пока не прочитается слово, которое соответствует случайной цифре.
Имеется множество других возможностей. Если вы вовремя не останови-
тесь, то обнаружите, что вы написали компьютерную игру!
--------------------------------------------------------
ИМЯ: phone
--------------------------------------------------------
phone База данных с телефонными номерами
Управляемое меню средство, поддерживающее базу данных с телефон-
ными номерами
phone
phone Вызов телефонной базы данных
s Ввод опции поиска
russ Поиск номера телефона Расса
ТЕКСТ ПРОГРАММЫ phone
1 :
2 # @(#) phone v1.0 Maintain telephone database
Author: Russ Sage
2а Сопровождение телефонной базы данных
4 if [ $# -gt 0 ]
5 then echo "phone: argument error" >&2
6 echo "usage: phone" >&2
7 exit 1
8 fi
10 BASE="$HOME/.phone.list"
12 while :
13 do
14 echo "
16 phonebase = $BASE
18 PHONE MENU
19 ----------
20 add name to list
21 delete name from list
22 edit list
23 search for name in list
24 view complete list
25
27 Press a,d,e,s,v or
28 read RSP
30 case $RSP in
31 "") exit 0
32 ;;
33 a|A) echo "\nEnter name to add (
): \c"
34 read NAME
35 if [ "$NAME" = "" ]
36 then continue
37 fi
38 echo "Enter description of person: \c"
39 read DESC
40 echo "Enter number to add: \c"
41 read NUM
42 echo "$NAME\t$DESC\t\t\t$NUM" >> $BASE
43 sort -t" " +1 -1.3b -o $BASE $BASE
44 ;;
45 d|D) echo "\nEnter name to delete (
): \c"
46 read NAME
47 if [ "$NAME" = "" ]
48 then continue
49 fi
50 sed -e "/$NAME/d" $BASE.new
51 mv $BASE.new $BASE
52 ;;
53 e|E) vi $BASE
54 ;;
55 s|S) echo "\nEnter name to search: \c"
56 read NAME
57 echo "\n----------------------------------"
58 grep -y "$NAME" $BASE
59 echo "------------------------------------"
60 ;;
61 v|V) echo "\n\tPhone List\n\t---------" &
62 more $BASE
63 echo "\nhit
64 read RSP
65 ;;
66 *) echo "Not a valid command"
67 ;;
68 esac
69 done
BASE Фактическое имя файла телефонной базы данных
DESC Описание, вводимое в базу данных
NAME Имя, вводимое в базу данных
NUM Номер телефона, вводимый в базу данных
RSP Ответ пользователя на приглашение
ОПИСАНИЕ
ЗАЧЕМ НАМ НУЖЕН phone?
Телефоны представляют собой очень важную часть нашего рабочего
дня. Мы используем их для сообщения своих планов, отдачи распоряжений
и для многих других целей. Немного поразмышляем. Если почти на каждом
рабочем месте в США установлен телефон, то телефонных номеров миллио-
ны. Каким образом вы храните все ваши телефонные номера?
Нам необходима очередная база данных. Эта база данных должна уп-
равлять вводом данных, их извлечением, модификацией и удалением. У нас
теперь есть опыт в реализации программ, управляемых с помощью меню,
поэтому имеет смысл использовать меню и здесь.
ЧТО ДЕЛАЕТ phone?
Phone - это универсальная утилита для использования и управления
базой данных телефонных номеров. Полностью управляемая при помощи ме-
ню, phone содержит все необходимые функции, связанные с управлением
базой данных: добавление, удаление, просмотр, редактирование и поиск.
Файл, представляющий собой базу данных, размещен в вашем регист-
рационном каталоге. Это файл $HOME/.phone.list. Phone использует ваш
регистрационный каталог, так что один и тот же исполняемый модуль ра-
ботает для любого пользователя. Независимо от того, где размещается
командный файл phone или кто и откуда его запустил в вашей системе, вы
всегда получите именно ваш файл телефонных номеров, поскольку он подк-
лючен к вашему регистрационному каталогу посредством встроенной пере-
менной shell с именем HOME.
Имеется всего одно главное меню. Оно выводится на экран, и внизу
появляется приглашение. Большинство вариантов выбора запрашивают до-
полнительную информацию. Меню выглядит так:
------------------------
|
|
| phonebase = /usr/russ/.phone.list
|
| PHONE MENU
| ----------
| add name to list (добавить имя к списку)
| delete name from list (удалить имя из списка)
| edit list (редактировать список)
| search for name in list (поиск имени в списке)
| view complete list (просмотр списка)
|
|
| Press a,d,e,s,v or
|
В верхней строке меню выводится имя телефонной базы данных, кото-
рую вы используете. Если это не ваш файл, вы точно знаете, что прои-
зошла ошибка. Опции выбираются нажатием клавиши, соответствующей пер-
вой букве слова. Если был нажат только возврат каретки, программа за-
вершается.
1. $ phone
a
russ sage
unix master
123-4567
Такая последовательность действий используется для добавления еще
одного номера в базу данных. Вызывайте меню, выбирайте опцию добавле-
ния и в ответ на запросы утилиты phone вводите имя, описание и номер
телефона.
2. $ phone
V
Просмотр всех записей в вашей базе данных.
Строки 4-8 выполняют некоторую проверку на наличие ошибок. Если
вы вызвали phone с какими-либо аргументами, выводится сообщение об
ошибке и программа завершается. Поскольку phone управляется при помощи
меню, она не использует аргументы.
Строка 10 инициализирует переменную BASE именем файла телефонной
базы данных. Это назначение выполняется с помощью переменной HOME для
получения вашего регистрационного каталога.
Строки 12-69 представляют собой один большой бесконечный цикл
while. Вся эта структура подобна структуре других программ, управляе-
мых с помощью меню, которые мы рассмотрели. Само меню выводится опера-
тором echo. Текст меню НЕ выделен отступами подобно остальной части
программы, поскольку оператор echo воспринимает этот текст как лите-
ральные данные, включая пробелы.
Строка 28 читает ответ пользователя, а строки 30-68 представляют
собой оператор case, который проверяет значение ответа. Если был нуле-
вой ввод, программа завершается.
Если была введена буква a, выбирается опция добавления. (В
действительности каждая опция проверяется и на верхнем, и на нижнем
регистре для обеспечения гибкости). Текст программы, соответствующий
добавлению, запрашивает имя, описание и номер телефона. Если вы оказа-
лись в опции добавления случайно, используйте возможность возврата пу-
тем нажатия возврата каретки в ответ на запрос имени. Однако после то-
го, как вы ввели имя, выйти уже нельзя. Вам необходимо в этом случае
поместить в базу фиктивную запись или нажать клавишу аварийного завер-
шения для выхода из программы вообще. Описание может быть произвольной
длины, однако оно не смотрится, если очень длинное. После того как все
поля введены, вся строка помещается в конец базы данных. Отметим, что
добавляются символы табуляции для разбиения записи на поля. После это-
го база данных пересортировывается, чтобы новая запись заняла свое
место в алфавитном порядке.
Если была введена буква d, то она распознается в строке 45. Зап-
рашивается удаляемое имя. Если вводится только возврат каретки, опера-
тор continue возвращает нас обратно в цикл while и снова выводится
главное меню. Для удаления записи использована команда sed, поэтому
вводимое имя должно указываться точно в таком же виде, как оно хра-
нится в файле. Результат удаления помещается во временный файл, кото-
рый затем в строке 51 переименовывается в исходный файл базы данных.
Одной из модификаций может быть показ пользователю того, что он соби-
рается удалять, и запрос подтверждения. Если подтверждение получено,
то данные удаляются окончательно. Сейчас сделано так, что вы на самом
деле не знаете, что именно собираетесь удалять. Поэтому необходимо
точно указывать удаляемое имя. Здесь выбран относительно быстрый и не
совсем честный подход. А вообще вы даже могли бы использовать не-
посредственно редактор vi для поиска и удаления.
Опция редактирования в строке 53 выполняет только одно - вызывает
редактор vi для работы с базой телефонных номеров. Используя редактор
vi, вы можете вручную сделать файл базы данных таким, как вам нужно.
Зачастую формат входных данных "плывет" из-за разной длины. Все данные
хранятся в свободном формате и поэтому их можно как угодно смещать
вдоль строки.
Когда вы редактируете ваш файл редактором vi, все его команды ак-
тивны. Действует даже выход в shell и выполнение обычных действий с
системой. Поэтому не забудьте прекратить работу этого shell'а, иначе
вы будете весьма удивлены в конце рабочего дня при выходе из системы.
Для выхода из редактора и возврата к утилите phone используйте обычные
методы, такие как ZZ, :x и :wq.
Опция поиска в строке 55 запрашивает имя, которое нужно искать,
читает это имя, выводит декоративные элементы до и после данных и
использует утилиту grep для нахождения требуемой записи. Утилита grep
в строке 58 использует команду -y, вызывающую нечувствительность к ре-
гистру. Это означает, что вы можете производить ввод искомого элемента
как на верхнем, так и на нижнем регистре. Если не найдено ничего, то
ничего и не выводится на экран.
Опция просмотра начинается со строки 61. Сначала выводится заго-
ловок в фоновом режиме. Это делается для быстроты. На самом деле это