Приемы профессиональной работы в UNIX



         

Глава 05_1 - часть 4


| | Statistics | ---------- Project: | a) Accumulative time totals | n) All times on | f) All times off | | enter response (a,n,f,):

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

ПРИМЕРЫ

1. c,l,v

Это первый набор команд при первоначальном запуске. Опция c пункт меню для создания файла проекта. Команда l выводит список всех имен файлов проектов, а v просматривает исходные данные, находящиеся в файле проекта.

2. n,n

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

3. s,junk

Эта последовательность также иллюстрирует проверку ошибок. Пытаемся выбрать новое имя файла проекта. Имя файла junk (которого вы не имеете). Timelog проверяет, существует ли файл регистрации времени с именем junk. Если нет, выводится сообщение о том, что вы должны выбрать правильное имя файла проекта.

ПОЯСНЕНИЯ

В этом командном файле много текста, но замысел не очень сложен.

Строка 4 инициализирует переменную PROJ нулевым значением. PROJ это переменная, которая содержит имя проекта, отображаемое в меню. В начале работы мы должны быть уверены, что эта переменная установлена в нуль.

Строки 6-104 - это огромный бесконечный цикл while, который выполняет работу всей программы. Поскольку это бесконечный цикл, мы можем выйти из него либо оператором break, (вводя обычные символы прерывания), либо с помощью команды выхода.

В строке 8 позиционным параметрам присваивается результат команды date. Поступая таким образом, мы можем затем легко обращаться к каждому полю без выделения его командой cut - shell выполняет за нас синтаксический разбор полей. Мы можем ссылаться на поля даты в виде $1, $2 и т.д.

Строки 9-23 выводят на экран главное меню. Верхняя строка обращается к данным из команды date. $1, $2 и $3 представляют собой день недели, месяц и число. $4 - это время. Перед тем как команда echo выводит текстовые строки, эти переменные раскрываются таким образом, что они появляются в меню. Если переменная PROJ равна нулю, то ничего не печатается в качестве имени текущего проекта. Символы \c в конце огромного оператора echo устанавливают курсор после приглашения в этой же строке, так что мы готовы принимать вводимые пользователем символы.

После печати меню в переменную RSP читается ответ в строке 25.

Затем наступает черед огромного оператора case (строки 27-103), который содержит ветку для каждой команды.

В строке 28 проверяется, не был ли ответ всего лишь возвратом каретки, указывающим, что пользователь хочет выйти. Если был, то цикл while завершается посредством команды break и программа заканчивает работу.

Иногда возврат каретки - более желательный метод выхода, чем команда exit интерпретатора shell. В конечном итоге эта команда shell приводит к выполнению программ exit и _exit Си -интерфейса. Выполнение вызова exit в Си иногда приводит к неожиданным побочным эффектам, в то время как нормальное выполнение текста программы до конца не дает таких же результатов. Однажды мы столкнулись с такой проблемой при использовании ESC -последовательностей для изменения цвета на цветном мониторе. Когда программа завершалась нормально, цвет не переустанавливался. Однако когда был сделан системный вызов exit, печатались некоторые ESC-последовательности, что переустанавливало отдельные части экрана. Очень странно!

Строки 29-38 управляют функцией выбора проекта. Имя проекта запрашивается и читается в переменную PROJ2. PROJ2 использована для временного хранения этого значения. Если был введен возврат каретки, оператор continue приводит к следующей итерации внешнего цикла while. Это позволяет пользователю прекратить выполнение этой функции при ошибочном вводе, оставаясь все же в timelog. Если ввод был непустым, файл проекта проверяется на существование и на наличие в нем данных. Если файл не существует, пользователя просят указать верное имя проекта.

Если имя файла правильное, то переменной PROJ присваивается значение PROJ2. Только после того, как командный файл с уверенностью знает, что имя, введенное пользователем, допустимо, оно назначается в качестве текущего имени проекта. Это предохраняет от потери выбора текущего проекта из-за ошибки пользователя. Теперь PROJ выводится в меню на экран.

Команда создания обрабатывается строками 39-50. Снова запрашивается имя и проверяется, не равно ли оно нулю. Если имя было введено, то проверяется, существует ли уже такой файл. Мы не хотим снова создавать и затирать уже имеющийся файл. Файл создается в строке 50. В этот файл выводятся отметка о времени его инициализации и начальное сообщение о том, что подсчет времени отключен.

Опция вывода списка выполняется в строках 51-53. Выводится заголовок, а затем команда ls используется для генерации списка. Если нет файлов нужного нам типа, то команда ls возвращает статус, отличный от нуля, тем самым включается оператор . В сущности этот фокус shell дает нам встроенный оператор if-then, который может использовать результаты предыдущей команды. Если выполнение команды ls неудачно (т.е. не найдены подходящие файлы), это сообщение об ошибке отбрасывается (не выводится) и выполняется оператор echo. Команда echo сообщает, что нет файлов, чтобы вы знали об этом.

Всякий выход команды ls пропускается через команду sed для отбрасывания расширения имени файла .time. Для сохранения места и для удобства пользователя мы хотим только посмотреть и напечатать имена проектов, а не имена файлов. Однако, мы хотим хранить имена файлов в специальном внутреннем формате так, чтобы мы могли проще обрабатывать их и поддерживать уникальные имена.

Команда просмотра выполняется в строках 54-60. Текущий файл проекта проверяется на то, было ли выбрано имя. Если нет, главное меню выводится снова. В противном случае печатается строка из черточек, выводится командой more файл проекта и печатается еще одна строка черточек для обрамления выведенной информации. Вы можете удивиться, почему первым символом оператора echo является двоеточие (:). Это некоторый казус, поскольку, если вы попытаетесь отобразить символ черточки (-) в качестве первого символа, то оператор echo "подумает", что это пустая опция и не выведет ее на экран. Вы просто должны поставить в первой позиции какой-то непустой символ, отличный от черточки.

Включение подсчета времени выполняется в строках 61-70. Текущее имя проекта проверяется на то, было ли оно выбрано. Если да, то проверяется, был ли отключен файл проекта. Мы выполняем это, используя команду tail для выделения последней строки файла, затем передаем по конвейеру эту строку команде cut, где мы изменяем символ-разделитель на символ : и отрезаем первое поле. Если в этом поле находятся символы OFF, все в порядке. После этого строка 69 выводит на экран сообщение для пользователя, а строка 70 вставляет в файл проекта строку ON, за которой следует текущая дата. Тем самым файл отмечается как включенный. Подсчет времени начался. Если эта операция уже была включена, мы сообщаем об этом пользователю и выходим из данной операции меню.

Строки 71-80 обрабатывают отключение подсчета времени. Здесь почти все идентично тексту программы, который включает эту операцию, только если там было слово "on", то здесь слово "off".

Строки 81-101 обрабатывают подчиненное меню выдачи отчетов и статистики. Как видите, экранное меню спланировано таким же образом: цикл while, печать меню, чтение ответа, выполнение оператора case в зависимости от выбранной команды и т.д. Команда r подобна главному меню, только сокращена для того, чтобы поместиться внутри оператора case. Вы также можете заметить, что в строках 96-99 выполняется не очень много обработки. Это то место, где вы должны выполнить некоторую работу.

Строка 102 выполняет обработку ошибок при любом неверном вводе.

Печатается сообщение об ошибке, оператор case выходит на следующую итерацию цикла while, и все начинается сначала.

МОДИФИКАЦИИ




Содержание  Назад  Вперед