Добавить в цитаты Настройки чтения

Страница 58 из 187

Если вы написали программу на языке shell или каком-то ином языке, она может оказаться полезной и другим пользователям вашей системы. Однако требования, которым, по мнению других, должна удовлетворять программа, обычно оказываются более строгими, чем предъявляемые к ней вами. Поэтому важнейший аспект программирования на языке shell — обеспечение надежности программы, чтобы она могла выполняться даже при неверно заданных входных данных и выдавать полезную информацию об ошибках.

5.1 Совершенствование команды cal

Типичная задача программирования на языке shell сводится к изменению взаимодействия между пользователем и программой, чтобы сделать это взаимодействие более удобным. В качестве примера рассмотрим команду cal(1):

$ cal

usage: cal [month] year Пока хорошо

$ cal october

Bad argument            Уже не так хорошо

$ cal 10 1983

  October 1983

  S  M  Tu W  Th F  S

                    1

  2  3  4  5  6  7  8

  9 10 11 12 13 14 15

 16 17 18 19 20 21 22

 23 24 25 26 27 28 29

 30 31

$

Досадно, что месяц нужно задавать числом, и к тому же, как оказалось, команда cal 10 выдает календарь на весь 10-й год, а не на октябрь текущего года. Поэтому всегда следует указывать год, если вы хотите получить календарь на один месяц.

Указанные выше неудобства связаны с тем, что взаимодействие пользователя с программой было реализовано без привлечения команды cal. Вы можете изменить характер этого взаимодействия, не меняя самой программы. Если поместить команду в ваш собственный каталог bin, то возможен более удобный способ перевода аргументов в те, которые нужны настоящей команде cal. Вы можете даже вызывать свою версию команды, и тогда вам меньше придется запоминать.

Первый шаг разработки — определить функции усовершенствованной команды cal. В основном мы хотим от нее разумного поведения. Месяц нужно распознавать по названию. При наличии двух аргументов она должна делать то же, что делала прежняя версия, за исключением перевода названия месяца в его номер. В случае одного аргумента следует печатать календарь месяца или года (в зависимости от того, что вам требуется), а при отсутствии аргументов — календарь текущего месяца, так как большей частью именно для этого и обращаются к команде. Поэтому задача сводится к тому, чтобы определить, сколько аргументов задано, и преобразовать их в те параметры, которые требуются стандартной команде cal.

Язык shell имеет оператор case, который успешно применяется в таких ситуациях:

case слово in

шаблон) команды ;;

шаблон) команды ;;

...

esac

В операторе case слово сравнивается поочередно со всеми шаблонами от начала до конца и выполняются команды, связанные с первым (и только первым) шаблоном, соответствующим слову. Шаблоны составляются по правилам соответствия шаблонов, которые в некоторой степени обобщают правила задания имен файлов. Каждое действие завершается двумя символами ;; (для последнего варианта можно обойтись без ;;, но обычно мы ставим их для удобства редактирования).

В нашей версии команды определяется число заданных аргументов, обрабатываются названия месяцев, затем происходит обращение к настоящей команде cal. В переменной интерпретатора $# хранится число аргументов, с которыми была вызвана программа; другие специальные переменные интерпретатора перечислены в табл. 5.1.