Первый шаг разработки — определить функции усовершенствованной команды cal
. В основном мы хотим от нее разумного поведения. Месяц нужно распознавать по названию. При наличии двух аргументов она должна делать то же, что делала прежняя версия, за исключением перевода названия месяца в его номер. В случае одного аргумента следует печатать календарь месяца или года (в зависимости от того, что вам требуется), а при отсутствии аргументов — календарь текущего месяца, так как большей частью именно для этого и обращаются к команде. Поэтому задача сводится к тому, чтобы определить, сколько аргументов задано, и преобразовать их в те параметры, которые требуются стандартной команде cal
.
Язык shell
имеет оператор case
, который успешно применяется в таких ситуациях:
case слово in
шаблон) команды ;;
шаблон) команды ;;
...
esac
В операторе case
слово сравнивается поочередно со всеми шаблонами от начала до конца и выполняются команды , связанные с первым (и только первым) шаблоном , соответствующим слову . Шаблоны составляются по правилам соответствия шаблонов, которые в некоторой степени обобщают правила задания имен файлов. Каждое действие завершается двумя символами ;;
(для последнего варианта можно обойтись без ;;
, но обычно мы ставим их для удобства редактирования).
В нашей версии команды определяется число заданных аргументов, обрабатываются названия месяцев, затем происходит обращение к настоящей команде cal
. В переменной интерпретатора $#
хранится число аргументов, с которыми была вызвана программа; другие специальные переменные интерпретатора перечислены в табл. 5.1.
$# |
Число аргументов |
$* |
Все аргументы, передаваемые интерпретатору |
$@ |
Аналогично $* ; см. разд. 5.7 |
$- |
Флаги, передаваемые интерпретатору |
$? |
Возвращение значения последней выполненной команды |
$$ |
Номер процесса интерпретатора |
$! |
Номер процесса последней команды, запущенной с помощью & |
$НOМЕ |
Аргумент, принятый по умолчанию для команды cd |
$IFS |
Список символов, разделяющих слова в аргументах |
$MAIL |
Файл, изменение которого приводит к появлению сообщения "you have a mail" ("У вас есть почта") |
$PATH |
Список каталогов, в которых осуществляется поиск команд |
$PS1 |
Строка приглашение, по умолчанию принята '$' |
$PS2 |
Строка приглашение при продолжении командной строки, по умолчанию принята '>' |
Таблица 5.1: Встроенные переменные интерпретатора
$ cat cal
# cal: nicer interface to /usr/bin/cal
case $# in
0) set `date`; m=$2; y=$6 ;; # no args: use today
1) m=$l; set `date`; y=$6 ;; #1 arg: use this year
*) m=$1; y=$2 ;; #2 args: month and year
esac
case $m in
jan*|Jan*) m=1 ;;
feb*|Feb*) m=2 ;;
mar*|Mar*) m=3 ;;
apr*|Apr*) m=4 ;;
may*|May*) m=5 ;;
jun*|Jun*) m=6 ;;
jul*|Jul*) m=7 ;;
aug*|Aug*) m=8 ;;
sep*|Sep*) m=9 ;;
oct*|Oct*) m=10 ;;
nov*|Nov*) m=11 ;;
dec*|Dec*) m=12 ;;
[1-9]|10|11|12) ;; # numeric month
*) y=$m; m="" ;; # plain year
esac
/usr/bin/cal $m $y # run the real one
$
В первом операторе case проверяется число аргументов $#
и выбирается подходящее действие. Последний шаблон в этом операторе задает вариант, выбираемый по умолчанию; если число аргументов не 0 и не 1, будет выполнен последний вариант. (Поскольку шаблоны просматриваются по порядку, вариант по умолчанию должен быть последним.) При наличии двух аргументов m
и y
принимают значение месяца и года, и наша команда cal
должна выполняться как исходная команда.
Первый оператор case
включает пару нетривиальных строк, содержащих
set `date`
Хотя это сразу и не очевидно, легко установить действие команды, запустив ее:
$ date
Sat Oct 1 06:05:18 EDT 1983
$ set `date`
$ echo $1
Sat
$ echo $4
06:05:20
$
Итак, мы имеем дело с встроенной командой интерпретатора, возможности которой многообразны. При отсутствии аргументов она выдает, как указывалось в гл. 3, значения переменных окружения. В случае обычных аргументов переопределяются значения $1
, $2
и т.д. Поэтому set `date`
присваивает $1
— день недели, $2
— название месяца и т.д. Таким образом, при отсутствии аргументов в первом case
месяц и год устанавливаются из текущей даты. Если был задан один аргумент, он используется в качестве месяца, а год берется из текущей даты.
Читать дальше
Конец ознакомительного отрывка
Купить книгу