программой, на этот раз — чтобы добиться вывода сообщения только в тех случаях, когда почтовый ящик пополняется, а не просто изменяется. Иначе вы получите сообщение сразу после исключения письма. (Версия, встроенная в интерпретатор, имеет такой недостаток.)
Обычно интервал времени устанавливается равным 60 с, но если командная строка содержит параметр, например
$ chekmail 30
то интервал задается им. Переменная интерпретатора принимает в качестве значения заданное параметрами время или 60 с, если время не задано, с помощью присваивания
t=${1-60}
Это еще одна возможность языка
shell
.
${var}
эквивалентно
$var
и может использоваться для преодоления трудностей, связанных с появлением переменных внутри буквенно-цифровых строк:
$ var=hello
$ varx=goodbye
$ echo $var
hello
$ echo ${var}x
hellox
$
Определенные символы внутри фигурных скобок задают специальную обработку переменной. В том случае, когда переменная не определена и за ее именем идет знак вопроса, выдается строка, следующая за символом
?
, и интерпретатор прекращает работу (если только он не работает в диалоговом режиме). При отсутствии строки печатается стандартное сообщение:
$ echo ${var?}
hello
все в порядке, var определено
$ echo ${junk}
junk: parameter not set
стандартное сообщение
$ echo ${junk?error!}
junk: error!
строка задана
$
Отметим, что в сообщении, выдаваемом интерпретатором, всегда указывается имя неопределенной переменной.
В другой конструкции
${var-thing}
выбирается
$var
, если оно определено, и
thing
— в противном случае. В подобной конструкции
${var-thing}
значение
$var
также устанавливается равным
thing
:
$ echo ${junk-'Hi there'}
Hi there
$ echo ${junk?)
junk: parameter not set
значение junk не изменилось
$ echo {junk='Hi there'}
Hi there
$ echo ${junk?}
Hi there
junk принял значение Hi there
$
Правила получения значений переменных приведены в табл. 5.3. Возвращаясь к нашему исходному примеру
t=${1-60}
видим, что
t
присваивается
$1
или 60, если аргумент не задан.
$var
Значение
var
;
ничего, если
var
не определено
${var}
То же; полезно, если за именем переменной следует буквенно-цифровая строка
${var-thing}
Значение
var
, если оно определено; в противном случае —
thing
;
$var
не изменяется
${var=thing}
Значение
var
, если оно определено; в противном случае —
thing
. Если
var
не определено, то
$var
присваивается
thing
${var?строка}
Если
var
определено —
$var
; в противном случае выводится строка и интерпретатор прекращает работу. При пустой строке выводится:
var: parameter not set
${var+thing}
thing
, если
$var
определено; в противном случае — ничего
Таблица 5.3: Получение значений переменных в языке
Упражнение 5.9
Обратите внимание на реализацию команд
true
и
false
в
/usr/bin
или
/bin
. (Как бы вы определили, где они находятся?)
Упражнение 5.10
Измените команду
watchfor
так, чтобы пользователь мог задавать несколько имен, а не вводить
'joe|mary'
.
Упражнение 5.11
Напишите версию команды
watchwho
, которая использует команду
comm
вместо
awk
для сравнения новой и старой информации. Какая версия вам больше нравится?
Упражнение 5.12
Напишите версию команды
watchwho
, в которой вывод команды
who
хранится в переменных языка
shell
, а не в файлах. Какая версия лучше? Какая версия быстрее работает? Следует ли в командах
watchwho
и
checkmail
автоматически использовать операцию
&
?
Упражнение 5.13
В чем состоит различие между пустой командой языка
shell
: и символом примечания
#
? Нужны ли они?
5.4 Команда
trap
: обработка прерываний
Если во время выполнения команды
watchwho
нажать клавишу DEL (УДЛ) или отключить компьютер от сети, то один или несколько временных файлов останутся в каталоге
/tmp
. Команда
watchwho
удаляет временные файлы перед окончанием своей работы. Необходимы средства обнаружения таких ситуаций и восстановления после прерывания.