Жанр: Учеба
Приемы профессиональной работы в Unix
...н. Это выполнено по той причине, что
символ ? имеет для 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. Сначала выводится заголовок
в фоновом режиме. Это делается для быстроты. На самом деле это
просто эксперимент для того, чтобы увидеть, будут ли асинхронные события
производить вывод на экран синхронно. В данном случае это именно
так. Файл выводится командой more. Пока утилита more постранично выводит
файл, все ее команды нам доступны. (Наш командный файл m в главе 4
иллюстрирует, что мы можем делать с помощью more.)
В строке 63 выводится сообщение пользователю о том, что он должен
нажать возврат каретки. Строка 64 выполняет чтение. Эта последовательность
придерживает распечатанный файл данных на экране, чтобы его
строки не пропали при сдвиге вверх. Если бы этих операторов не было,
напечаталось бы главное меню и мы потеряли бы то, что находилось в
верхней части экрана.
Строка 66 выполняет проверку на ошибки для меню в целом. Если вы
ввели данные, которые не соответствуют ни одному из предыдущих шаблонов,
то им сопоставляется шаблон *. В этом случае печатается сообщение
об ошибке, управление переходит из оператора case в конец цикла while
и при следующей итерации этого цикла снова печатается главное меню.
---------------------------------------------------------------------------
ИМЯ: office
---------------------------------------------------------------------------
office Делопроизводитель
НАЗНАЧЕНИЕ
Обеспечивает простой доступ ко многим утилитам управления делопроизводством,
которые мы уже рассмотрели.
ФОРМАТ ВЫЗОВА
office
ПРИМЕР ВЫЗОВА
office Проверяет мой почтовый ящик и сообщает, пуст ли он
m
ТЕКСТ ПРОГРАММЫ office
1 :
2 # @(#) office v1.0 Office Manager Author: Russ Sage
2а Делопроизводитель
4 if [ $# -gt 0 ]
5 then echo "office: argument error" "&2
6 echo "usage: office" "&2
7 exit 1
8 fi
10 while :
11 do
12 c
13 set `date`
14 echo "
15 $1, $2 $3 $4
17 Office Menu
18 -----------
19 Mail
20 News
21 Calendar
22 Phone
23 Automatic Reminders
24 Shell Command
25 to exit
27 press m,n,c,p,a,s or : \c"
29 read CMD
31 case $CMD in
32 "") exit;;
33 m|M) if [ -s /usr/spool/mail/$LOGNAME ]
34 then echo
35 ll /usr/spool/mail/$LOGNAME
36 echo "\nWould yuo like to see it (
y/n): \c"
37 read CMD
38 if [ "$CMD" = "y" ]
39 then echo
40 mail
41 fi
42 else echo "\nNo mail today"
43 fi
44 echo "\nhit \c"
45 read CMD;;
46 n|N) PWD=`pwd`
47 cd /usr/news
48 echo "\nThe following files are news item
in /usr/news:\n"
49 lc
50 echo "\nEnter filename or to exit: \c"
51 read NAME
52 while [ "$NAME" != "" ]
53 do
54 if [ -s $NAME ]
55 then echo "\n-------------------"
56 cat $NAME
57 echo "---------------------"
58 else echo "$NAME is not a news
file"
59 fi
60 echo "\nEnter filename or to
exit: \c"
61 read NAME
62 done
63 cd $PWD;;
64 c|C) echo "\n"
65 today
66 if [ -s $HOME/calendar ]
67 then echo "Calendar file:\n`ll $HOME/
calendar`"
68 echo "\nCalendar notifications:"
69 PWD=`pwd`
70 cd $HOME
71 calendar
72 cd $PWD
73 echo "\nCheck your mail for calendar
notifications"
74 else echo "\nYou do not have a calendar
file at $HOME"
75 fi
76 echo "\nhit \c"
77 read CMD;;
78 p|P) phone;;
79 a|A) greet
80 $HB/at 11:45 echo ^GLunch in 15 minutes
81 $HB/at 16:45 echo ^GShift change in 15
minutes
83 echo "\nYou will receive notices at 11:45
& 4:45"
84 echo "\nWould you like to leave some
reminders (y/n): \c"
85 read CMD
86 if [ "$CMD" = "y" ]
87 then echo "\nThe syntax is: at HR:MN
executable_phrase"
88 echo "The time now : `date '+%T'`"
89 echo "\n\ncmd ( to exit): \c"
90 read CMD
91 while [ "$CMD" != "" ]
92 do
93 eval $CMD
94 echo "cmd ( to exit
): \c"
95 read CMD
96 done
97 fi;;
98 s|S) echo "\nenter command: \c"
99 read CMD
100 eval $CMD
101 echo "\nhit \c"
102 read CMD;;
103 *) echo "\nInvalid command"
104 echo "\nhit \c"
105 read CMD;;
106 esac
107 done
ПЕРЕМЕННЫЕ СРЕДЫ ВЫПОЛНЕНИЯ
CMD Содержит различные команды на разных уровнях меню
HOME Еще одна экспортируемая переменная, взятая из
среды выполнения
LOGNAME Shell-переменная, предварительно экспортированная
NAME Содержит имя файла с новостями
ОПИСАНИЕ
ЗАЧЕМ НАМ НУЖЕН office?
Многие инструментальные средства в системе UNIX могут выполнять
полезные функции, относящиеся к делопроизводству. В силу способа организации
UNIX, это отдельные и самостоятельные средства. Для того чтобы
узнать о них, необходимо найти все эти средства в справочных руководствах,
изучить каждое из них и все время помнить, как с ними работать.
Это очень неудобно.
Кроме, того, нам необходимо добавить ряд мощных команд к нашему
UNIX, включая несколько отдельных управляемых с помощью меню утилит.
Каким образом мы можем все это об'единить?
Нам необходим механизм, с помощью которого мы можем получить
доступ ко всем функциям, имеющим отношение к делопроизводству. Если
использовать меню, мы сможем вызывать каждую функцию нажатием одной
клавиши.
ЧТО ДЕЛАЕТ office?
Office представляет собой попытку собрать наиболее часто используемые
функции делопроизводства в один пакет, управляемый с помощью
меню. Тем самым office упрощает вызов этих функций, поскольку вам не
обязательно знать, где эти утилиты размещаются и как к ним обращаться.
Если у вас есть помощник-секретарь без всякого опыта работы в системе
UNIX, вы можете поручить ему выполнение многих из этих функций. Вы можете
добавить новые функции и уровни меню, если это необходимо.
В office имеются как неотъемлемые общие функции делопроизводства,
так и специфические добавки. Данная утилита пытается управлять как
основными функциями, так и кругом задач по вашему вкусу. К базовым
функциям относятся почта, новости, календарь и база телефонных номеров.
Добавляемые особенности включают в себя систему напоминаний,
В строке 71 мы получаем для проверки команду главного меню и ининтерпретатора
shell, не выходя из программы office. Благодаря всем
этим качествам, все находится в одном месте и обеспечивается простота
доступа и сопровождения.
Главное меню содержит все доступные функции. Оно выглядит так:
---------------------------------------------------------------------------
|
| Fri, Jun 20 16:18:23
|
| Office Menu
| -----------
| Mail (Почта)
| News (Новости)
| Calendar (Календарь)
| Phone (Телефоны)
| Automatic Reminders (Автоматические напоминания)
| Shell Command (Переход в shell)
| to exit (Выход)
|
| press m,n,c,p,a,s or :
|
День и дата в левом верхнем углу получены командой UNIX date.
Каждый раз при выводе меню печатается новое значение времени. Оно
сообщает вам о том, когда вы начали работать с этим меню, и как долго
вы работали.
Первым вариантом выбора является почта. Здесь ваш почтовый файл
проверяется на ненулевой размер. Если размер нулевой (или такой файл
отсутствует), выводится сообщение "no mail today" (сегодня почты нет).
Если для вас есть почта, то информация из файла почтового ящика распечатывается
в длинном формате командой ls и выводится запрос о том, хотите
ли вы прочитать вашу почту. Если вы сказали "yes" (да), выполняется
обычная команда UNIX mail.
Вторым вариантом выбора являются новости. Файлы новостей хранятся
в одном каталоге, где каждая порция новостей представляет собой независимый
файл. Все порции новостей хранятся в специальном каталоге с
именем /usr/news. Office выводит список всех файлов новостей и затем
спрашивает, хотите ли вы просмотреть один из них. Если да, введите имя
файла - и он распечатается командой more. Мы предполагаем, что у вас
есть сетевая связь между пользователями или какое-то другое средство
для получения новостей.
Третий вариант выбора - календарь. Поскольку с календарем связана
разнообразная информация, данная опция подразделяется на различные
функции. Сначала выводится полностью календарь на текущий месяц с выделенной
сегодняшней датой. Это делается с помощью утилиты today,
рассмотренной ранее. Затем выполняется обращение к системной утилите
работы с календарем. Если в вашем регистрационном каталоге есть файл с
именем calendar, то утилита calendar (выполняемая командой cron для
просмотра каждого регистрационного каталога) просматривает записи вашего
календаря. Если какие-либо запи
...Поділитися у соцмережах