Страница:
Если в строке 10 число позиционных параметров равно одному, то мы
знаем, что либо этот параметр должен быть опцией -l, либо это ошибка.
Следующий оператор if в строке 11 проверяет, является ли первый пози-
ционный параметр опцией -l. Если да, то в файл $HOME/.lastlog добавля-
ется текущая дата и lastlog вызывается снова без аргументов для печати
предыдущей даты регистрации. (Мы только что видели, как это делается.)
Если это не был аргумент -l, то строки 14-16 выполняют обработку ошиб-
ки.
Если число позиционных параметров равно нулю, выполняется опера-
тор else в строке 18. Отсутствие опций означает, что мы хотим найти
время нашей последней регистрации на машине и распечатать его. Это ка-
жется довольно простым, но кто сказал, что машины просты?
Если вы помните последовательность работы, то мы сперва регистри-
руем новое время, а затем хотим найти время нашей предыдущей регистра-
ции. Для файла .lastlog это означает, что наше текущее время регистра-
ции находится в самом конце файла, а наше предыдущее время регистрации
находится в строке непосредственно перед ним. Это значит, что мы долж-
ны получить вторую строку от конца файла. Да уж.
Как видно из строки 18, она занимается получением последних двух
строк. Команда tail красиво выполняет эту работу. Нам нужен такой
способ, чтобы мы могли прочитать именно первую строку, а вторую отб-
росить, что выполняется в строке 19. Мы передаем по конвейеру выход
команды tail подчиненному shell (указанному круглыми скобками), кото-
рый читает первую строку и затем отображает ее. А что же со второй
строкой? Она никогда не берется и пропадает. Другим способом может
быть передача выхода команды tail по конвейеру команде "head -1".
Поскольку эта команда не имеет других опций, мы не даем никаких
примеров. Тем не менее, давайте теперь рассмотрим наше другое средство
регистрации времени входа в систему.
--------------------------------------------------------
ИМЯ: timelog
--------------------------------------------------------
timelog Учет и статистика времени
Интерфейсное меню для слежения и сопровождения файлов регистрации
времени.
timelog
timelog Выводит на экран главное меню, из которого можно
выбирать необходимое действие
ТЕКСТ ПРОГРАММЫ timelog
1 :
2 # @(#) timelog v1.0 Time accounting and statistics
Author: Russ Sage
2а Учет и статистика времени
4 PROJ=""
6 while :
7 do
8 set `date`
9 echo "
11 $1, $2 $3 $4
13 Time Logger
14 ----------- Project: $PROJ
15 s) Select a project file
16 c) Create a new project file
17 l) List current project files
18 v) View the project file
19 n) Turn billing on
20 f) Turn billing off
21 r) Report ststistics
23 enter response (s,c,l,v,n,f,r,): \c"
25 read RSP
27 case $RSP in
28 "") break;;
29 s) echo "\Enter project name ( for exit): \c"
30 read PROJ2
31 if [ "$PROJ2" = "" ]
32 then continue
33 fi
34 if [ ! -s $PROJ2.time ]
35 then echo "you must specify a valid project
file"
36 continue
37 fi
38 PROJ="$PROJ2";;
39 c) echo "\nEnter the new project name ( to
exit): \c"
40 read PROJ2
41 if [ "PROJ2" = "" ]
42 then continue
43 fi
44 if [ -f "$PROJ2.time" ]
45 then echo "\n ** $PROJ2 already exists **"
46 continue
47 fi
48 PROJ="$PROJ2"
49 echo "\nProject file created: $PROJ"
50 echo "Project file created: `date`\nOFF: begin"
> $PROJ.time;;
51 l) echo "\nCurrent project files:\n"
52 ls -l *.time 2>/dev/null || echo "no project
files" |
53 sed "s/\.time//";;
54 v) if [ "$PROJ" = "" ]
55 then echo "you must select a project file
first"
56 continue
57 fi
58 echo "\n:----------------------------"
59 more $PROJ.time
60 echo ":---------------------------";;
61 n) if [ "$PROJ" = "" ]
62 then echo "you must select a project file
first"
63 continue
64 fi
65 if [ "`tail -1 $PROJ.time|cut -d: -f1`" !=
"OFF" ]
66 then echo "logging was not turned off"
67 continue
68 fi
69 echo "\nBilling turned on for project file:
$PROJ"
70 echo "ON: `date`" >> $PROJ.time;;
71 f) if [ "$PROJ" = "" ]
72 then echo "you must select a project file
first"
73 continue
74 fi
75 if [ "`tail -1 $PROJ.time|cut -d: -f1`" !=
"ON" ]
76 then echo "logging was not turned on"
77 continue
78 fi
79 echo "\nBilling turned off for project file:
$PROJ"
80 echo "OFF: `date`" >> $PROJ.time;;
81 r) while :
82 do
83 echo "
84 Statistics
85 ---------- Project: $PROJ
86 a) Accumulative time totals
87 n) All times on
88 f) All times off
90 enter response (a,n,f,): \c"
92 read RSP
94 case $RSP in
95 "") break;;
96 a) awk '/Total:/ { PRINT $0 }'
$PROJ.TIME;;
97 n) awk '/ON/ { print $0 }'
$PROJ.time;;
98 f) awk '/OFF/ { print $0 }'
$PROJ.time;;
99 *) echo "\n ** Wrong command,
try again **";;
100 esac
101 done;;
102 *) echo "\n ** Wrong command, try again **";;
103 esac
104 done
PROJ Содержит текущее имя проекта
PROJ2 Содержит временное имя проекта, введенное пользователем
RSP Содержит команду выбора из меню
ОПИСАНИЕ
ЗАЧЕМ НАМ НУЖЕН timelog?
Время - драгоценный товар. Его всегда не хватает, и если уж оно
использовано, то его никогда больше нельзя вернуть. Мы хотим быть уве-
рены, что наше время используется плодотворно. Мы можем и должны соз-
дать инструментальные средства, которые помогут нам управлять нашим
временем и фиксировать его.
Мы должны рассмотреть следующие вопросы: над какими проектами мы
работаем, в течение какого времени мы над ними работаем (т.е. начало и
окончание), и какую еще информацию нам нужно хранить.
Как раз почти все эти функции поддерживаются программой timelog.
Мы написали довольно длинную программу, но заметим, что на самом деле
работа над этим средством не окончена. Предлагаемый командный файл
timelog подготавливает вас к работе с системой управления временем.
Вам нужно вставить ваш собственный текст для выдачи отчетов, основан-
ных на статистике времени.
ЧТО ДЕЛАЕТ timelog?
Timelog относится к весьма важной области, связанной с фиксацией
времени и управлением временем. Отметим, что количество учетных сведе-
ний, которые можно создать, просмотреть и обработать, ограничено толь-
ко доступным пространством файловой памяти.
Timelog - это полностью управляемый с помощью меню интерфейс.
Системы с меню в UNIX - это нечто новое, они имеют свои преимущества и
недостатки. Одним из преимуществ является то, что вся работа над дан-
ными выполняется программно, а не вручную. Кроме того, каждую функцию
наглядно видно и легко выбрать. Вам нет необходимости запоминать опции
и имена файлов, достаточно просто нажать одну клавишу для выполнения
действия.
Недостатком является то, что меню работают медленнее, чем ручной
интерфейс (т.е. просто набор и непосредственное выполнение команд).
Это очень важное замечание, но мы должны также помнить, что программы
должны быть простыми в использовании, простыми для модификации и вы-
полнять множество мелочей, связанных с какой-либо идеей или областью
назначения. Потеря машинного времени чаще всего лучше, чем потеря вре-
мени человека! Другой недостаток - для того чтобы добраться до опреде-
ленной функции, вы должны пройти через несколько уровней меню.
Например, чтобы напечатать отчет, вы должны вызвать timelog, выб-
рать меню статистики, затем выбрать нужный вам отчет. Здесь три уров-
ня, а при наличии утилиты вы могли бы всего одной командой сказать
"report report_file".
Для утилит, выполняющих одну функцию, наличие одной команды с
несколькими опциями довольно эффективно. Такой подход применяется в
большинстве командных файлов интерпретатора shell. Но когда у вас есть
множуство небольших задач, выполняемых над группой объектов, меню бо-
лее удобны.
Некоторые системы предоставляют интерфейс, управляемый как меню,
так и командами. Это устраивает больший круг пользователей и позволяет
избежать большинства недостатков, упомянутых выше. Конечно, при таком
подходе неминуемы некоторые издержки и программа становится более
длинной.
При вызове timelog на экран выводится начальное меню, как показа-
но ниже.
---------------------
|
| Thu, Jun 19 21:32:12
|
| Time Logger
| ----------- Project:
| s) Select a project file
| c) Create a new project file
| l) List current project files
| v) View the project file
| n) Turn billing on
| f) Turn billing off
| r) Report statistics
|
| enter response (s,c,l,v,n,f,r,):
В левом верхнем углу показан день недели и дата. В правом верхнем
углу показано время. Это реальное время, и оно обновляется при каждом
вызове меню. Имя меню "Time Logger" (регистратор времени). "Report
statistics" (сообщить статистику) вызывает появление подчиненного ме-
ню.
Строка, в которой написано "Project:" (проект), показывает, что
текущее имя проекта нулевое. Для того чтобы работать над проектом, вы
сперва должны создать файл проекта или выбрать его, если он уже су-
ществует. Все действия, выполняемые после этого, относятся к текущему
файлу проекта.
Первый пункт меню s предназначен для выбора файла проекта. После
выбора этого пункта выводится сообщение:
---------------------------
|
| Enter project name ( for exit):
| Введите имя проекта ( для выхода):
Вы можете ввести любую текстовую строку в качестве имени проекта
или, если вам не нужна эта опция, нажать клавишу возврата каретки для
благополучного выхода. Если вы не помните имена проектов, вы можете
использовать опцию l, поясняемую ниже. После ввода имени существующего
проекта, текущему имени проекта (которое печатается справа вверху в
каждом меню) присваивается имя этого файла.
Следующей является опция c для создания файла проекта. Как уже
отмечалось, это должно быть первым, что вы делаете, начиная работать с
утилитой timelog, но после этого вы обычно выбираете существующие фай-
лы. Когда вы выбрали опцию c, печатается следующее приглашение:
---------------------------
|
| Enter the new project name ( to exit):
| Введите имя нового проекта ( для выхода):
Здесь нужно вводить то же самое, что и при выборе проекта. Для
выхода нажмите возврат каретки. После ввода имени текущее имя проекта
изменяется, создается файл проекта, запоминается время, и файл загру-
жается исходной информацией.
Следующая опция l предназначена для выдачи списка имен файлов
проектов. Поскольку каждый проект является файлом, отображается список
в виде, обычном для команды ls. Тем не менее, будьте внимательны.
Список нельзя получить прямо командой ls. Имена изменены для защиты от
наивных.
Каждый файл проекта хранится на диске в формате "project. time".
Часть project в каждом файле отличается и представляет собой имя, вве-
денное в опции создания. Все файлы имеют суффикс .time. Когда выво-
дится список, префикс .time отбрасывается, так что имена файлов явля-
ются просто проектами, которые вы ввели в опции выбора проекта. Здесь
все работает, но вы должны помнить, что если вы захотите просмотреть
файлы времен вручную, то имена не будут теми же самыми. Если нет ника-
ких файлов проектов, то об этом выводится сообщение.
Следующей опцией является v для просмотра файла проекта. Файлом,
который вы собираетесь просмотреть, является текущий файл проекта. Его
имя выводится в меню справа от слова "Project:". Если не появилось ни-
какого имени, вы должны сперва создать новый проект или выбрать су-
ществующий. Файл проекта выводится на экран командой UNIX more.
Следующей опцией является опция n для включения подсчета времени.
Это означает начало записи нового сеанса работы над проектом. Проверя-
ется имя проекта, чтобы выяснить, был ли выбран файл проекта. Если
нет, выводится сообщение о том, что нужно это сделать. Затем проверя-
ется, был ли файл проекта отключен предыдущей операцией. Если да, то
регистратор времени может быть включен. Вы не можете включить его
дважды. Вы должны отключить его, затем включить и т.д.
Следующая опция f отключает подсчет времени для файла проекта.
Текущее имя проекта сравнивается с нулевым, и если это так, то выво-
дится соответствующее сообщение. Затем проверяется, был ли предвари-
тельно включен подсчет времени для этого файла. Если был, то в файл
проекта добавляется запись о выключении подсчета.
Последней опцией является r для отчета и статистики. После ее вы-
бора на экран выводится подчиненное меню:
-----------------------
|
| 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, и все начинается сначала.
Основной возможностью для модификации является добавление факти-
ческой обработки информации о времени. Один из подходов к этому - зап-
росить почасовой тариф времени в момент создания файла проекта (если
считать, что вы работаете на таких основаниях). Этот тариф может хра-
ниться первым пунктом в файле проекта. Следующие две строки могут быть
отведены для "счета по текущему сеансу" и "общего счета" соответствен-
но. Когда подсчет времени работы над проектом отключается, можно проа-
нализировать текущее системное время и начальное время подсчета и за-
тем пересчитать в минуты (для упрощения арифметики) с использованием
команды expr (или, возможно, awk). Затем это значение можно умножить
на хранимый в файле тариф времени, а результат сохранить в записи о
текущем сеансе работы и ДОБАВИТЬ к совокупной общей записи.
-----------------------------------------------------
ИМЯ: today
------------------------------------------------------
today Печать календаря с подсвеченной сегодняшней датой
Модифицирует вывод утилиты cal для печати сегодняшней даты ин-
версным цветом.
today
today Печатает календарь на этот месяц с подсвеченной
сегодняшней датой
ТЕКСТ ПРОГРАММЫ today
1 :
2 # @(#) today v1.0 Calendar with today highlighted
Author: Russ Sage
2а Календарь с подсветкой сегодняшнего дня
4 SYSV=n
6 set `date`
8 if [ "$SYSV" = "y" ]
9 then RVR=`tput smso`
10 BLNK=`tput blink`
11 NORM=`tput rmso`
12 cal ${2} ${6} | sed "s/${3}/${RVR}${BLNK}${3}${NORM}
/g" -e "s/^/ /"
13 else RVR="^[[7m" # termcap so
14 NORM="^[[0m" # termcap se
15 cal ${2} ${6} | sed -e "s/ ${3}/ ${RVR}${3}${NORM}
/" -e "s/^/ /"
16 fi
ПЕРЕМЕННЫЕ СРЕДЫ ВЫПОЛНЕНИЯ
RVR Управляющий символ инверсного отображения для
вашего терминала
BLNK Управляющий символ мерцания для вашего терминала,
если таковой имеется
NORM Управляющий символ для возврата терминала в
обычный режим
ОПИСАНИЕ
ЗАЧЕМ НАМ НУЖЕН today?
Всегда приятно иметь инструментальные средства, предоставляющие
нам информацию о нашей среде. Тип информации, который мы здесь
рассматриваем - это модифицированный вывод календаря. Стандартная ко-
манда cal выводит дни месяца, но не сообщает вам, какой день сегодня.
Как мы это узнаем? Мы должны запустить команду date для определения
текущего дня. Довольно тривиальная задача, однако наше решение может
дать некоторую ценную графику, которая может добавить действительно
полезную информацию к календарю.
Для выполнения такой модификации нам необходимо выполнить постоб-
работку результата команды cal. Поскольку не все терминалы обладают
одинаковыми возможностями, эта программа должна быть приспособлена к
вашей машине.
ЧТО ДЕЛАЕТ today?
Today - это постпроцессор для команды cal, который делает ее ре-
зультат более информативным и графически наглядным. Выполнение модифи-
кации команды cal зависит от того, в какой системе вы работаете. Если
вы в системе UNIX System V (версия 2 или старше), то у вас есть утили-
та terminfo. Terminfo является заменой для файла termcap и поставля-
ется с несколькими утилитами, которые возвращают значения с информаци-
ей о ПРИЕМЫ ПРОФЕССИОНАЛЬНОЙ РАБОТЫ В UNIX
нальных характеристик. Если ваш компьютер работает не с системой
System V, то вам необходимо немного поисследовать тип ваших конкретных
терминалов и внести полученные значения в вашу программу.
Вся история с утилитами termcap и terminfo иллюстрирует эволюцию
работы в среде UNIX. UNIX с самых первых дней стремился быть независи-
мым от типов устройств. Первым шагом явилось использование файлов уст-
ройств и драйверов. Следующим шагом был файл termcap, который пре-
доставил единообразный способ получения информации о терминалах.
Последним этапом является утилита terminfo, предоставляющая эту инфор-
мацию таким способом, который лучше обеспечивает функциональный доступ
из программ.
Поскольку в пределах командного файла не так легко определить, с
какой системой работает ваш компьютер, использована переменная SYSV.
Эту переменную можно изменить при помощи редактора, поэтому today мо-
жет работать в разных системах. Способами выяснения системы могли бы
служить программа uname, существование определенных shell-программ в
каталоге /bin или какой-нибудь системный файл, содержащий номер
версии. По умолчанию переменная SYSV установлена так, чтобы утилита
today работала НЕ в системе System V. С этим связано существование
фрагмента программы, который нужно изменять вручную.
Как вы можете самостоятельно получить информацию о терминале?
Каждый терминал имеет свои специфические особенности. Все терминалы
характеризуются в основном файлом описания терминала termcap. В этом
файле каждая характеристика дается под своим именем вместе с аппарат-
ным кодом этой функции. Таким образом, мы можем, например, редактором
vi заглянуть в termcap и увидеть, как управлять терминалом, на котором
мы работаем. Файл termcap сильно зашифрован и загадочен. По данному
вопросу не очень много документации, что порождает множество экспери-
ментов и ошибок.
Переменными, которые нас интересуют, являются "so" для выделения
информации (инверсный режим) и "se" для завершения выделения (обычный
режим), а также режим мерцания, если он есть у вашего терминала.
Termcap, похоже, не содержит информацию о том, как включить режим мер-
цания, поэтому вам, вероятно, нужно будет для этого посмотреть доку-
ментацию на терминал. В системе System V (версия 2) команда tput возв-
ращает соответствующее значение.
По умолчанию в today выполнены установки для ANSI терминала, яв-
ляющегося консольным в системе XENIX. Эти коды были вручную извлечены
из файла /etc/termcap и вставлены в текст программы. Если ваши коды
знаем, что либо этот параметр должен быть опцией -l, либо это ошибка.
Следующий оператор if в строке 11 проверяет, является ли первый пози-
ционный параметр опцией -l. Если да, то в файл $HOME/.lastlog добавля-
ется текущая дата и lastlog вызывается снова без аргументов для печати
предыдущей даты регистрации. (Мы только что видели, как это делается.)
Если это не был аргумент -l, то строки 14-16 выполняют обработку ошиб-
ки.
Если число позиционных параметров равно нулю, выполняется опера-
тор else в строке 18. Отсутствие опций означает, что мы хотим найти
время нашей последней регистрации на машине и распечатать его. Это ка-
жется довольно простым, но кто сказал, что машины просты?
Если вы помните последовательность работы, то мы сперва регистри-
руем новое время, а затем хотим найти время нашей предыдущей регистра-
ции. Для файла .lastlog это означает, что наше текущее время регистра-
ции находится в самом конце файла, а наше предыдущее время регистрации
находится в строке непосредственно перед ним. Это значит, что мы долж-
ны получить вторую строку от конца файла. Да уж.
Как видно из строки 18, она занимается получением последних двух
строк. Команда tail красиво выполняет эту работу. Нам нужен такой
способ, чтобы мы могли прочитать именно первую строку, а вторую отб-
росить, что выполняется в строке 19. Мы передаем по конвейеру выход
команды tail подчиненному shell (указанному круглыми скобками), кото-
рый читает первую строку и затем отображает ее. А что же со второй
строкой? Она никогда не берется и пропадает. Другим способом может
быть передача выхода команды tail по конвейеру команде "head -1".
Поскольку эта команда не имеет других опций, мы не даем никаких
примеров. Тем не менее, давайте теперь рассмотрим наше другое средство
регистрации времени входа в систему.
--------------------------------------------------------
ИМЯ: timelog
--------------------------------------------------------
timelog Учет и статистика времени
Интерфейсное меню для слежения и сопровождения файлов регистрации
времени.
timelog
timelog Выводит на экран главное меню, из которого можно
выбирать необходимое действие
ТЕКСТ ПРОГРАММЫ timelog
1 :
2 # @(#) timelog v1.0 Time accounting and statistics
Author: Russ Sage
2а Учет и статистика времени
4 PROJ=""
6 while :
7 do
8 set `date`
9 echo "
11 $1, $2 $3 $4
13 Time Logger
14 ----------- Project: $PROJ
15 s) Select a project file
16 c) Create a new project file
17 l) List current project files
18 v) View the project file
19 n) Turn billing on
20 f) Turn billing off
21 r) Report ststistics
23 enter response (s,c,l,v,n,f,r,
25 read RSP
27 case $RSP in
28 "") break;;
29 s) echo "\Enter project name (
30 read PROJ2
31 if [ "$PROJ2" = "" ]
32 then continue
33 fi
34 if [ ! -s $PROJ2.time ]
35 then echo "you must specify a valid project
file"
36 continue
37 fi
38 PROJ="$PROJ2";;
39 c) echo "\nEnter the new project name (
exit): \c"
40 read PROJ2
41 if [ "PROJ2" = "" ]
42 then continue
43 fi
44 if [ -f "$PROJ2.time" ]
45 then echo "\n ** $PROJ2 already exists **"
46 continue
47 fi
48 PROJ="$PROJ2"
49 echo "\nProject file created: $PROJ"
50 echo "Project file created: `date`\nOFF: begin"
> $PROJ.time;;
51 l) echo "\nCurrent project files:\n"
52 ls -l *.time 2>/dev/null || echo "no project
files" |
53 sed "s/\.time//";;
54 v) if [ "$PROJ" = "" ]
55 then echo "you must select a project file
first"
56 continue
57 fi
58 echo "\n:----------------------------"
59 more $PROJ.time
60 echo ":---------------------------";;
61 n) if [ "$PROJ" = "" ]
62 then echo "you must select a project file
first"
63 continue
64 fi
65 if [ "`tail -1 $PROJ.time|cut -d: -f1`" !=
"OFF" ]
66 then echo "logging was not turned off"
67 continue
68 fi
69 echo "\nBilling turned on for project file:
$PROJ"
70 echo "ON: `date`" >> $PROJ.time;;
71 f) if [ "$PROJ" = "" ]
72 then echo "you must select a project file
first"
73 continue
74 fi
75 if [ "`tail -1 $PROJ.time|cut -d: -f1`" !=
"ON" ]
76 then echo "logging was not turned on"
77 continue
78 fi
79 echo "\nBilling turned off for project file:
$PROJ"
80 echo "OFF: `date`" >> $PROJ.time;;
81 r) while :
82 do
83 echo "
84 Statistics
85 ---------- Project: $PROJ
86 a) Accumulative time totals
87 n) All times on
88 f) All times off
90 enter response (a,n,f,
92 read RSP
94 case $RSP in
95 "") break;;
96 a) awk '/Total:/ { PRINT $0 }'
$PROJ.TIME;;
97 n) awk '/ON/ { print $0 }'
$PROJ.time;;
98 f) awk '/OFF/ { print $0 }'
$PROJ.time;;
99 *) echo "\n ** Wrong command,
try again **";;
100 esac
101 done;;
102 *) echo "\n ** Wrong command, try again **";;
103 esac
104 done
PROJ Содержит текущее имя проекта
PROJ2 Содержит временное имя проекта, введенное пользователем
RSP Содержит команду выбора из меню
ОПИСАНИЕ
ЗАЧЕМ НАМ НУЖЕН timelog?
Время - драгоценный товар. Его всегда не хватает, и если уж оно
использовано, то его никогда больше нельзя вернуть. Мы хотим быть уве-
рены, что наше время используется плодотворно. Мы можем и должны соз-
дать инструментальные средства, которые помогут нам управлять нашим
временем и фиксировать его.
Мы должны рассмотреть следующие вопросы: над какими проектами мы
работаем, в течение какого времени мы над ними работаем (т.е. начало и
окончание), и какую еще информацию нам нужно хранить.
Как раз почти все эти функции поддерживаются программой timelog.
Мы написали довольно длинную программу, но заметим, что на самом деле
работа над этим средством не окончена. Предлагаемый командный файл
timelog подготавливает вас к работе с системой управления временем.
Вам нужно вставить ваш собственный текст для выдачи отчетов, основан-
ных на статистике времени.
ЧТО ДЕЛАЕТ timelog?
Timelog относится к весьма важной области, связанной с фиксацией
времени и управлением временем. Отметим, что количество учетных сведе-
ний, которые можно создать, просмотреть и обработать, ограничено толь-
ко доступным пространством файловой памяти.
Timelog - это полностью управляемый с помощью меню интерфейс.
Системы с меню в UNIX - это нечто новое, они имеют свои преимущества и
недостатки. Одним из преимуществ является то, что вся работа над дан-
ными выполняется программно, а не вручную. Кроме того, каждую функцию
наглядно видно и легко выбрать. Вам нет необходимости запоминать опции
и имена файлов, достаточно просто нажать одну клавишу для выполнения
действия.
Недостатком является то, что меню работают медленнее, чем ручной
интерфейс (т.е. просто набор и непосредственное выполнение команд).
Это очень важное замечание, но мы должны также помнить, что программы
должны быть простыми в использовании, простыми для модификации и вы-
полнять множество мелочей, связанных с какой-либо идеей или областью
назначения. Потеря машинного времени чаще всего лучше, чем потеря вре-
мени человека! Другой недостаток - для того чтобы добраться до опреде-
ленной функции, вы должны пройти через несколько уровней меню.
Например, чтобы напечатать отчет, вы должны вызвать timelog, выб-
рать меню статистики, затем выбрать нужный вам отчет. Здесь три уров-
ня, а при наличии утилиты вы могли бы всего одной командой сказать
"report report_file".
Для утилит, выполняющих одну функцию, наличие одной команды с
несколькими опциями довольно эффективно. Такой подход применяется в
большинстве командных файлов интерпретатора shell. Но когда у вас есть
множуство небольших задач, выполняемых над группой объектов, меню бо-
лее удобны.
Некоторые системы предоставляют интерфейс, управляемый как меню,
так и командами. Это устраивает больший круг пользователей и позволяет
избежать большинства недостатков, упомянутых выше. Конечно, при таком
подходе неминуемы некоторые издержки и программа становится более
длинной.
При вызове timelog на экран выводится начальное меню, как показа-
но ниже.
---------------------
|
| Thu, Jun 19 21:32:12
|
| Time Logger
| ----------- Project:
| s) Select a project file
| c) Create a new project file
| l) List current project files
| v) View the project file
| n) Turn billing on
| f) Turn billing off
| r) Report statistics
|
| enter response (s,c,l,v,n,f,r,
В левом верхнем углу показан день недели и дата. В правом верхнем
углу показано время. Это реальное время, и оно обновляется при каждом
вызове меню. Имя меню "Time Logger" (регистратор времени). "Report
statistics" (сообщить статистику) вызывает появление подчиненного ме-
ню.
Строка, в которой написано "Project:" (проект), показывает, что
текущее имя проекта нулевое. Для того чтобы работать над проектом, вы
сперва должны создать файл проекта или выбрать его, если он уже су-
ществует. Все действия, выполняемые после этого, относятся к текущему
файлу проекта.
Первый пункт меню s предназначен для выбора файла проекта. После
выбора этого пункта выводится сообщение:
---------------------------
|
| Enter project name (
| Введите имя проекта (
Вы можете ввести любую текстовую строку в качестве имени проекта
или, если вам не нужна эта опция, нажать клавишу возврата каретки для
благополучного выхода. Если вы не помните имена проектов, вы можете
использовать опцию l, поясняемую ниже. После ввода имени существующего
проекта, текущему имени проекта (которое печатается справа вверху в
каждом меню) присваивается имя этого файла.
Следующей является опция c для создания файла проекта. Как уже
отмечалось, это должно быть первым, что вы делаете, начиная работать с
утилитой timelog, но после этого вы обычно выбираете существующие фай-
лы. Когда вы выбрали опцию c, печатается следующее приглашение:
---------------------------
|
| Enter the new project name (
| Введите имя нового проекта (
Здесь нужно вводить то же самое, что и при выборе проекта. Для
выхода нажмите возврат каретки. После ввода имени текущее имя проекта
изменяется, создается файл проекта, запоминается время, и файл загру-
жается исходной информацией.
Следующая опция l предназначена для выдачи списка имен файлов
проектов. Поскольку каждый проект является файлом, отображается список
в виде, обычном для команды ls. Тем не менее, будьте внимательны.
Список нельзя получить прямо командой ls. Имена изменены для защиты от
наивных.
Каждый файл проекта хранится на диске в формате "project. time".
Часть project в каждом файле отличается и представляет собой имя, вве-
денное в опции создания. Все файлы имеют суффикс .time. Когда выво-
дится список, префикс .time отбрасывается, так что имена файлов явля-
ются просто проектами, которые вы ввели в опции выбора проекта. Здесь
все работает, но вы должны помнить, что если вы захотите просмотреть
файлы времен вручную, то имена не будут теми же самыми. Если нет ника-
ких файлов проектов, то об этом выводится сообщение.
Следующей опцией является v для просмотра файла проекта. Файлом,
который вы собираетесь просмотреть, является текущий файл проекта. Его
имя выводится в меню справа от слова "Project:". Если не появилось ни-
какого имени, вы должны сперва создать новый проект или выбрать су-
ществующий. Файл проекта выводится на экран командой UNIX more.
Следующей опцией является опция n для включения подсчета времени.
Это означает начало записи нового сеанса работы над проектом. Проверя-
ется имя проекта, чтобы выяснить, был ли выбран файл проекта. Если
нет, выводится сообщение о том, что нужно это сделать. Затем проверя-
ется, был ли файл проекта отключен предыдущей операцией. Если да, то
регистратор времени может быть включен. Вы не можете включить его
дважды. Вы должны отключить его, затем включить и т.д.
Следующая опция f отключает подсчет времени для файла проекта.
Текущее имя проекта сравнивается с нулевым, и если это так, то выво-
дится соответствующее сообщение. Затем проверяется, был ли предвари-
тельно включен подсчет времени для этого файла. Если был, то в файл
проекта добавляется запись о выключении подсчета.
Последней опцией является r для отчета и статистики. После ее вы-
бора на экран выводится подчиненное меню:
-----------------------
|
| 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, и все начинается сначала.
Основной возможностью для модификации является добавление факти-
ческой обработки информации о времени. Один из подходов к этому - зап-
росить почасовой тариф времени в момент создания файла проекта (если
считать, что вы работаете на таких основаниях). Этот тариф может хра-
ниться первым пунктом в файле проекта. Следующие две строки могут быть
отведены для "счета по текущему сеансу" и "общего счета" соответствен-
но. Когда подсчет времени работы над проектом отключается, можно проа-
нализировать текущее системное время и начальное время подсчета и за-
тем пересчитать в минуты (для упрощения арифметики) с использованием
команды expr (или, возможно, awk). Затем это значение можно умножить
на хранимый в файле тариф времени, а результат сохранить в записи о
текущем сеансе работы и ДОБАВИТЬ к совокупной общей записи.
-----------------------------------------------------
ИМЯ: today
------------------------------------------------------
today Печать календаря с подсвеченной сегодняшней датой
Модифицирует вывод утилиты cal для печати сегодняшней даты ин-
версным цветом.
today
today Печатает календарь на этот месяц с подсвеченной
сегодняшней датой
ТЕКСТ ПРОГРАММЫ today
1 :
2 # @(#) today v1.0 Calendar with today highlighted
Author: Russ Sage
2а Календарь с подсветкой сегодняшнего дня
4 SYSV=n
6 set `date`
8 if [ "$SYSV" = "y" ]
9 then RVR=`tput smso`
10 BLNK=`tput blink`
11 NORM=`tput rmso`
12 cal ${2} ${6} | sed "s/${3}/${RVR}${BLNK}${3}${NORM}
/g" -e "s/^/ /"
13 else RVR="^[[7m" # termcap so
14 NORM="^[[0m" # termcap se
15 cal ${2} ${6} | sed -e "s/ ${3}/ ${RVR}${3}${NORM}
/" -e "s/^/ /"
16 fi
ПЕРЕМЕННЫЕ СРЕДЫ ВЫПОЛНЕНИЯ
RVR Управляющий символ инверсного отображения для
вашего терминала
BLNK Управляющий символ мерцания для вашего терминала,
если таковой имеется
NORM Управляющий символ для возврата терминала в
обычный режим
ОПИСАНИЕ
ЗАЧЕМ НАМ НУЖЕН today?
Всегда приятно иметь инструментальные средства, предоставляющие
нам информацию о нашей среде. Тип информации, который мы здесь
рассматриваем - это модифицированный вывод календаря. Стандартная ко-
манда cal выводит дни месяца, но не сообщает вам, какой день сегодня.
Как мы это узнаем? Мы должны запустить команду date для определения
текущего дня. Довольно тривиальная задача, однако наше решение может
дать некоторую ценную графику, которая может добавить действительно
полезную информацию к календарю.
Для выполнения такой модификации нам необходимо выполнить постоб-
работку результата команды cal. Поскольку не все терминалы обладают
одинаковыми возможностями, эта программа должна быть приспособлена к
вашей машине.
ЧТО ДЕЛАЕТ today?
Today - это постпроцессор для команды cal, который делает ее ре-
зультат более информативным и графически наглядным. Выполнение модифи-
кации команды cal зависит от того, в какой системе вы работаете. Если
вы в системе UNIX System V (версия 2 или старше), то у вас есть утили-
та terminfo. Terminfo является заменой для файла termcap и поставля-
ется с несколькими утилитами, которые возвращают значения с информаци-
ей о ПРИЕМЫ ПРОФЕССИОНАЛЬНОЙ РАБОТЫ В UNIX
нальных характеристик. Если ваш компьютер работает не с системой
System V, то вам необходимо немного поисследовать тип ваших конкретных
терминалов и внести полученные значения в вашу программу.
Вся история с утилитами termcap и terminfo иллюстрирует эволюцию
работы в среде UNIX. UNIX с самых первых дней стремился быть независи-
мым от типов устройств. Первым шагом явилось использование файлов уст-
ройств и драйверов. Следующим шагом был файл termcap, который пре-
доставил единообразный способ получения информации о терминалах.
Последним этапом является утилита terminfo, предоставляющая эту инфор-
мацию таким способом, который лучше обеспечивает функциональный доступ
из программ.
Поскольку в пределах командного файла не так легко определить, с
какой системой работает ваш компьютер, использована переменная SYSV.
Эту переменную можно изменить при помощи редактора, поэтому today мо-
жет работать в разных системах. Способами выяснения системы могли бы
служить программа uname, существование определенных shell-программ в
каталоге /bin или какой-нибудь системный файл, содержащий номер
версии. По умолчанию переменная SYSV установлена так, чтобы утилита
today работала НЕ в системе System V. С этим связано существование
фрагмента программы, который нужно изменять вручную.
Как вы можете самостоятельно получить информацию о терминале?
Каждый терминал имеет свои специфические особенности. Все терминалы
характеризуются в основном файлом описания терминала termcap. В этом
файле каждая характеристика дается под своим именем вместе с аппарат-
ным кодом этой функции. Таким образом, мы можем, например, редактором
vi заглянуть в termcap и увидеть, как управлять терминалом, на котором
мы работаем. Файл termcap сильно зашифрован и загадочен. По данному
вопросу не очень много документации, что порождает множество экспери-
ментов и ошибок.
Переменными, которые нас интересуют, являются "so" для выделения
информации (инверсный режим) и "se" для завершения выделения (обычный
режим), а также режим мерцания, если он есть у вашего терминала.
Termcap, похоже, не содержит информацию о том, как включить режим мер-
цания, поэтому вам, вероятно, нужно будет для этого посмотреть доку-
ментацию на терминал. В системе System V (версия 2) команда tput возв-
ращает соответствующее значение.
По умолчанию в today выполнены установки для ANSI терминала, яв-
ляющегося консольным в системе XENIX. Эти коды были вручную извлечены
из файла /etc/termcap и вставлены в текст программы. Если ваши коды