Жанр: Учеба

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

сторінка №17

екоторое программное
обеспечение, которое манипулирует с ними. Однако всегда есть место
для дополнительного программного обеспечения, работающего со временем.
Такие средства могут быть написаны как на языке Си, так и на
shell-языке.
Как мы извлекаем и выделяем время с помощью командного файла интерпретатора
shell? Доступно много способов, но стандартная команда
UNIX date, видимо, является наилучшим способом. В случае языка Си вы
должны программно управлять преобразованием времени и временными зонами.
Команда date делает это для вас.
Важна также единица времени. Должны ли мы различать секунды, минуты,
часы, дни или недели? Это все зависит от требуемого приложения.
В нашем простом примере мы различаем только три части суток: утро,
день и вечер. Мы определили эти периоды так: с полуночи до полудня, от
полудня до шести часов и от шести часов до полуночи соответственно.

ЧТО ДЕЛАЕТ greet?

Greet - это утилита, которая приветствует пользователя различными
сообщениями в зависимости от времени суток. Выводимые сообщения не так
важны. Они в основном использованы как примеры, показывающие, как могут
быть выполнены какие-то команды. Если вы работаете в одиночестве и
хотели бы поболтать, эти сообщения могли бы читаться периодически из
соответствующих файлов для создания иллюзии автоматической письменной
болтовни в зависимости от времени суток.
Действительной же целью является создание каркаса программы, которая
может переключаться в зависимости от параметров времени. Путем
расширения концепции времени вы можете создать другие утилиты, которые
знают, когда им работать (в какой промежуток времени) и могут вести
себя иначе в соответствии со временем.
Greet не требует ничего в командной строке. Не выполняется никакой
проверки на наличие ошибок, поэтому и нет в программе синтаксической
подсказки. Выход команды greet может быть переадресован в файл
или передан по конвейеру другому процессу.

ПРИМЕРЫ

1. $ if greet | fgrep 'morn' " /dev/null
" then morning_routine
" fi

Выполняется greet. Стандартный вывод greet по конвейеру передается
на стандартный ввод fgrep. Производится поиск символьной строки
"morn". Весь выход переадресовывается в никуда, так что он не засоряет
экран. Если выходной статус команды fgrep равен нулю (она нашла нужную
строку), выполняется файл morning_routine.

2. $ at 10:30 greet; at 13:50 greet

Вы могли бы вставить это в ваш .profile. Два процесса at будут
выполняться на вашей машине в фоновом режиме до тех пор, пока не
наступит время их запуска - тогда они поприветствуют вас на вашем терминале.
Правда, это может причинить небольшое неудобство. Сообщение
может появиться, когда вы работаете в редакторе, и нарушить содержимое
экрана, но на самом деле оно не изменит ваш редактируемый файл.

ПОЯСНЕНИЯ

Вся программа представляет собой один большой оператор if
-then-else в строках 4-9. Логика программы выглядит на псевдокоде следующим
образом:

if it is morning если утро
then echo morning statement то вывести "утреннее"
приветствие
else if it is noon иначе если день
then echo noon statement то вывести "дневное"
приветствие
else echo evening statement иначе вывести "вечернее"
приветствие

В действительности программа гораздо сложнее, поэтому переведем
дыхание и приступим к делу.
В строке 4 проверяется текущее время на то, меньше ли оно 12
часов. Если да, то фраза команды expr выводит на стандартное устройство
вывода единицу ("1"). Поскольку символы ударения (`), которые
обрамляют эту фразу, перехватывают стандартный вывод, символ 1 становится
частью оператора проверки, что указано квадратными скобками
([]). Затем оператор test проверяет, равен ли выход команды expr литеральной
единице. Если они одинаковы, то в строке 5 выводится "утреннее"
сообщение.

Рассмотрим более подробно, как раскрывается оператор expr.
Во-первых, он заключен в символы ударения. Это означает, что он выполняется
перед оператором проверки. Затем его выход помещается для обработки
в оператор test. Однако внутри оператора expr имеется еще одно
выражение между знаками ударения, которое выполняется до оператора
expr. Такое старшинство выполнения управляется интерпретатором кода
внутри shell.
Внутренние знаки ударения сохраняются при начальном синтаксическом
разборе строки, поскольку они экранированы символами обратной
косой черты. Первой запускается команда date, имеющая в качестве выхода
только текущее значение часа в соответствии с форматом %H. Затем
expr использует данное значение часа для проверки, меньше ли оно 12.
Если да, expr печатает единицу. Если значение часа больше или равно
12, то возвращаемое значение равно 0. Такое понимание, что 1=истина и
0=ложь, соответствует синтаксису, используемому в языке Си.
Однако ранее мы замечали, что в среде программирования на языке
shell 1 означает ложь, а 0 - истину. Это происходит потому, что проверяемое
значение оператора if является в действительности статусом выхода
из предварительно выполненной команды. Нуль соответствует нормальному
завершению, поэтому 0 использован для переключения проверки в
состояние "истина" и выполнения оператора then. Для того, чтобы преобразовать
возвращаемый статус 1 (при условии, что значение часа меньше
12) в нуль (для переключения оператора then), мы используем команду
test. Возвращаемый статус единицы равен константе 1, поэтому команда
test возвращает 0, что представляет истину. Вот так!
Если бы не были использованы вложенные знаки ударения, то
единственным способом передачи данного типа информации другому процессу
было бы применение переменных shell. Использование вложенной командной
подстановки дает нам большую гибкость и простоту программирования.
Чем больше глубина вложенности, тем глубже экранирование знаков
ударения. Порядок экранирования символами обратной косой черты такой:
не нужно для внешней команды, один раз для второй внутренней команды,
пять раз для третьей внутренней команды. На четвертом уровне их должно
быть семь или девять (я еще не пробовал), но вероятно нет большой нужды
во вложенности такой глубины.
Если проверка в строке 4 дает "ложь", выполняется строка 6. Это
оператор else от первого if и одновременно следующий if. В таких особых
случаях синтаксис shell меняется. Ключевое слово "else" становится
ключевым словом "elif".
Второй if использует команду test точно так же, как и первый.
Проверяемое время здесь 18, что представляет собой 6 часов вечера.
Если вторая проверка также дает "ложь", выполняется последний оператор
в строке 8. Этот else не использует команду test, поскольку после выполнения
первых двух проверок мы можем сделать вывод, что остался
последний период времени, а именно период после 18:00.

---------------------------------------------------------------------------

ИМЯ: lastlog
---------------------------------------------------------------------------

lastlog Сообщает время последней регистрации

НАЗНАЧЕНИЕ

Записывает и выводит на экран день и время вашей последней регистрации
в системе.

ФОРМАТ ВЫЗОВА

lastlog [-l]

ПРИМЕР ВЫЗОВА

lastlog Печатает дату, когда вы последний раз регистрировались

ТЕКСТ ПРОГРАММЫ lastlog

1 :
2 # @(#) lastlog v1.0 Report last login time Author: Russ Sage
2а Сообщает время последней регистрации

4 if [ $# -gt 1 ]
5 then echo "lastlog: arg error" "&2
6 echo "usage: lastlog [-l]" "&2
7 exit 1
8 fi

10 if [ "$#" -eq "1" ]
11 then if [ "$1" = "-l" ]
12 then date "" $HOME/.lastlog
13 lastlog
14 else echo "lastlog: unrecognized option $1" "&2
15 echo "usage: lastlog [-l]" "&2
16 exit 1
17 fi
18 else echo "Time of last login : `tail -2 $HOME/.lastlog |
19 (read FIRST; echo $FIRST)`"
20 fi

ПЕРЕМЕННЫЕ СРЕДЫ ВЫПОЛНЕНИЯ

FIRST Хранит первую из двух введенных строк
HOME Хранит имя вашего регистрационного каталога

ОПИСАНИЕ

ЗАЧЕМ НАМ НУЖЕН lastlog?

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

ЧТО ДЕЛАЕТ lastlog?

Lastlog - это программа, которая записывает время вашей регистрации
при каждом входе в систему. Затем это время хранится в файле данных
в вашем регистрационном каталоге под именем $HOME/.lastlog. Имя
файла lastlog начинается с точки с той целью, чтобы сделать его невидимым
для команды ls. Укрытие "служебных" файлов от распечатки по
умолчанию несколько предохраняет от любопытных глаз, а также убирает
эти файлы с дороги, когда вы просматриваете что-то другое.
При вызове без опций lastlog печатает для нас дату последней регистрации,
получая запись из файла .lastlog.
Для выполнения новой записи в файл .lastlog необходимо вызвать
lastlog с опцией -l. При этом новое значение времени запишется в файл
.lastlog, а затем командный файл lastlog вызовет сам себя для вывода
на экран нового значения - небольшая рекурсия.
Для того, чтобы программа lastlog работала автоматически, вы
должны выполнять ее из вашего файла .profile во время регистрации. При
таком способе она запишет последнее время в файл .lastlog. В качестве
примера посмотрите файл .profile в первой главе.

ПОЯСНЕНИЯ

В строках 4-8 выполняется проверка на наличие ошибок. Если вы
вызвали lastlog с числом аргументов больше одного, то это приведет к
ошибке. Выводится сообщение на стандартное устройство регистрации ошибок,
и lastlog завершается со статусом ошибки 1.
Строки 10-20 представляют собой оператор if-then-else, который
показывает, был ли это вызов для записи нового значения времени или
для печати старых значений.
Если в строке 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

Список сторінок

Поділитися у соцмережах

☏ Замовлення реклами: +3805044-68-872

© Асоціація електронних бібліотек України

☝ Усі матеріали сайту (зокрема статті, зображення, рекламні оголошення тощо) призначені лише для попереднього ознайомлення. Усі права на публікації, представлені на сайті, належать їхнім законним власникам. Просимо Вас не зберігати копії інформації.