355 500 произведений, 25 200 авторов.

Электронная библиотека книг » Дэвид Тейнсли » Linux и UNIX: программирование в shell. Руководство разработчика » Текст книги (страница 17)
Linux и UNIX: программирование в shell. Руководство разработчика
  • Текст добавлен: 15 октября 2016, 00:39

Текст книги "Linux и UNIX: программирование в shell. Руководство разработчика"


Автор книги: Дэвид Тейнсли



сообщить о нарушении

Текущая страница: 17 (всего у книги 25 страниц)

return 1

fi

case $_MONTH in

1|01|Jan)_FULL="January";;

2|02|Feb)_FULL="February";;

3|03|Mar)_FULL="March";;

4|04|Apr)_FULL="April";;

5|05|May)_FULL="May";;

6|06|Jun)_FULL="June";;

7|07|Jul)_FULL="July";;

8|08|Aug)_FULL="August;;

9|09|Sep|Sept)_FULL="September";;

10|Oct)_FULL="October";;

ll|Nov)_FULL="November;;

l2|Dec)_FULL="December";;

*) echo "months: Unknown month"

return 1

;;

esac

echo $_FULL

}

Для вызова функции months можно применить одни из следующих методов.

months 04

В результате отобразится наименование месяца "April". Можно также вызвать функцию из сценария:

MY_MONTH=`months 06`

echo "Generating the Report for Month End $MY_MOMTH"

В результате отобразится название месяца "June".

19.10.4. Подведение итогов

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

Многие из функций выполняют обычные задачи. Они не предназначены для осуществления "прорыва" в деле создания сценариев, а просто экономят ваше время, позволяя не вводить одинаковые фрагменты кода. Только благодаря этому использование функций, несомненно, полезно.

В начале главы было рассмотрено, каким образом функции могут применяться в интерпретаторе shell. При первом знакомстве с применением функций говорилось о значениях, возвращаемых функциями.

В приведенных примерах функций использовались различные методы для вызова и проверки результатов, возвращаемых функциями. Поэтому, если у вас возникают какие‑либо проблемы в этой области, просмотрите еще раз примеры и вспомните, каким образом функции возвращают и проверяют значения.

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

19.11. Вызов функций

В завершение этой главы рассмотрим два различных способа работы с функциями: вызов функций из исходного файла и применение функций, размещенных в сценариях.

19.11.1. Вызов функций, размещенных в сценариях

Чтобы использовать функцию в сценарии, ее нужно создать, затем убедиться в том, что конструкция, вызывающая эту функцию, находится после программного кода самой функции. Ниже приводится сценарий, из которого вызываются две функции. Сценарий уже рассматривался ранее; здесь осуществляется проверка существования каталога.

$ pg direc_check

#!/bin/sh

# файл функций

is_it_a_directory()

{

#is_it_a_directory(

#вызов: is_it_a_directory имя_каталога

_DIRECTORY_NAME=$1

if [ $# -lt 1 ]; then

echo "is_it_a_directory: I need a directory name to check"

return 1

fi

# это каталог?

if [ ! —d $_DIRECTORY_NAME ]; then

return 1

else

return 0

fi

}

#

error_msg

{

#error_msg

#сигнал; сообщение; повторный сигнал

echo -e "07"

echo $@

echo -e "07"

return 0

}

### END OF FUNCTIONS

echo -n "enter destination directory :"

read DIREC

if is_it_a_directory $DIREC

then :

else

error_msg "$DIREC does not exist…creating it now"

mkdir $DIREC > /dev/null 2>&1

if [ $? != 0 ]

then

error_msg "Could not create directory: check it out!"

exit 1

else :

fi

fi # не каталог

echo "extracting files…"

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

19.11.2. Вызов функций из файла функций

Мы уже рассматривали, каким образом функции вызываются из командной строки. Эти типы функций обычно используются утилитами, создающими системные сообщения.

А теперь воспользуемся снова описанной выше функцией, но в этом случае поместим ее в файле функций. Назовем этот файл functions.sh, где "sh" означает "shell scripts" (сценарии интерпретатора shell).

$ pg functions.sh

#!/bin/sh

#functions.sh

#основные функции

is_it_a_directory () (

#is_it_a_directory

#вызов: is_it_a_directory имя_каталога #

if [ $# -lt 1 ]; then

echo "is_it_a_directory: I need a directory name to check"

return 1

fi

# это каталог ?

DIRECTORY_NAME=$1

if [ ! -d $DIRECTORY_NAME ]; then

return 1 else

return D fi )

error_msg ()

{

echo -e "07"

echo $@

echo -e "07"

return 0

}

Создадим сценарий, вызывающий функции из файла functions.sh. Затем эти функции могут использоваться для выполнения каких‑либо задач. Обратите внимание, что файл функций загружается с помощью следующего формата команд:

. /<путь к файлу>

При использовании этого метода не создается порожденный интерпретатор shell; все функции остаются в текущем интерпретаторе shell.

$ pg dlrec_check

#!/bin/sh

# direc_check

# загрузка файла функций functions.sh # ниже точка, пробел и косая черта. /home/dave/bin/functions.sh

# теперь могут использоваться функции

echo -n "enter destination directory :"

read DIREC

if is_it_a_directory $DIREC

then : .

else

error_msg "$DIREC does not exist… creating it now"

mkdir $DIREC > /dev/null 2>$1

if [ $? ! – 0 ]

then

error_msg "Could not create directory: check it out!"

exit 1

else :

fi

fi # не является каталогом

echo "extracting files…"

При выполнении сценария получается тот же вывод, что и при встраивании функции в сценарий:

S direc_check

enter destination directory :AUDIT

AUDIT does not exist… creating it now

extracting files…

19.12. Загрузка файлов, которые состоят не только из функций

Загружаемый файл не обязательно должен содержать только функции; он может включать глобальные переменные, образующие файл конфигурации.

Предположим, что существует пара сценариев резервирования, которые архивируют различные части системы. Неплохой идеей в этом случае является разделение единого файла конфигурации. Все, что нужно для этого, -cоздать переменные внутри файла. Затем, когда начинает выполняться один из сценариев резервирования, можно загрузить эти переменные, если потребуется изменить любые настройки, заданные по умолчанию, перед началом выполнения сценария резервирования. Это может быть связано с тем, что пользователь захочет выполнять архивирование на различных носителях.

Подобный подход может применяться сценариями, разделяющими общие параметры конфигурации, с целью выполнения процесса. Ниже приведен пример. В следующем файле конфигурации содержатся переменные среды, заданные по умолчанию. Эти переменные используются несколькими сценариями резервирования. Вот содержимое этого файла:

$ pg backfunc

#!/bin/sh

   • name: backfunc

   • конфигурационный файл содержит настройки по умолчанию для систем архивации _CODE="comet"

_FULLBACKUP="yes" _LOGF1LE="/logs/backup/" _DEVICE="/dev/rmt/0n" _INFORM="yes" _PRINT_STATS="yes"

Комментарии разъясняют суть программы. Первое поле, _code, содержит кодовое слово. Для просмотра его содержимого и изменения значений пользователь должен ввести код, соответствующий значению code. В данном случае указывается слово "comet".

Ниже приведен сценарий, который в ответ на ввод пароля отображает конфигурацию, заданную по умолчанию:

$ pg readfunc

#!/bin/sh

# readfunc

if [ -r backfunc ]; then

# указание файла с параметрами

. /backfunc else

echo "`basename $0` cannot locate backfunc file" fi

echo -n "Enter the code name :"

# соответствует ли указанный код коду из файла backfunc?

if [ "${CODE}" != "${_CODE}" ]; then

echo "Wrong code…exiting..will use defaults" exit 1 fi

echo ." The environment config file reports"

echo "Full Backup Required : $_FULLBACKUP"

echo "The Logfile is : $_LOGFILE"

echo "The Device To Backup To is : $_DEVICE" echo "You Are To Be Informed by Mail : $_INFORM" echo "A Statistic Report To Be Printed: $_PRINT_STATS"

После запуска сценария на выполнение отобразится запрос на ввод кода. Если введенный код соответствует заданному кодовому слову, можно будет просмотреть настройки, заданные по умолчанию. Рабочий вариант сценария предоставит возможности для изменения настроек, заданных по умолчанию.

$ readfunc

Enter the code name :comet

The environment config file reports

Full Backup Required : yes

The Logfile ls : /logs/backup/

The Device To Backup To ls : /dev/rmt/0n You Are To Be Informed by Mail : yes A Statistic Report To Be Printed: yes

19.13. Заключение

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

После разработки набора требуемых функций необходимо разместить их в файле функций. В результате этого функциями смогут воспользоваться другие сценарии.

ГЛАВА 20

Передача параметров сценарию

В предыдущих главах рассматривались способы передачи параметров сценариям с помощью специальных переменных $1...$9. Специальная переменная $# указывает количество передаваемых параметров. Также обсуждалась конструкция usage. Эта конструкция применяется для информирования пользователя о том, как вызвать сценарий или функцию с помощью соответствующих параметров вызова. В этой главе будут рассмотрены следующие темы:

   • применение команды shift;

   • работа с командой getopts;

   • примеры использования команд shift и getopts.

Для проверки степени усвоения материала рассмотрим схему сценария, в котором используются параметры start и stop. При запуске сценария необходимо указать два параметра. Если они не заданы, отображается предупреждающее сообщение. Обратите внимание, что для обработки различных параметров, передаваемых сценарию, применяется конструкция case.

$ pg opt

#!/bin/sh

# opt

usage ()

{

echo "usage:`basename $0` start|stop process name"

}

OPT=$1

PR0CESSID=$1

#if [ $# -ne 2 ]

then

usage

exit 1 fi

case $OPT in

start|Start) echo "Starting..$PROCESSID"

# выполняется некоторая обработка

;;

stop|Stop) echo "Stopping..$PROCESSID" # выполняется некоторая обработка

;;

*) usage

;;

esac

Приведенный сценарий при вводе данных выдает такие результаты:

$ opt start named

Starting…named

$ opt start

usage:opt start|stop process name

Общий формат произвольной команды UNIX или Linux: команда опции файлы

Часть опции может принимать до 12 различных значений. Как показано в примере со сценарием opt, для работы с командными опциями следует создавать большой объем программного кода. В данном случае мы имеем дело лишь с двумя опциями, start и stop.

К счастью, интерпретатор команд поддерживает команду shift, с помощью которой можно выбирать различные опции. Команда shift позволяет устранить ограничение, состоящее в том, что при передаче параметров применяются только специальные переменные $1…$9.

20.1. Команда shift

При передаче сценарию параметров потребуется соответствующий метод обработки, использующий возможности команды shift. В результате выполнения этой команды позиционные аргументы смещаются влево на один элемент. Чтобы уточнить принцип действия команды shift, рассмотрим простой сценарий. Здесь применяется цикл while, обеспечивающий отображение на экране всех аргументов, переданных сценарию.

$ pg opt2

#!/bin/sh

# opt2

loop=0

while [ $# -ne 0 ] # цикл выполняется до тех пор, пока остаются аргументы

do

echo $1 done

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

$ opt2 файл1 файл2 файлЗ

файл1 файл1 файл1

20.1.1. Простой способ использования команды shift

Для обработки каждого передаваемого аргумента достаточно воспользоваться командой shift. Ниже приводится соответствующий сценарий:

$ pg opt2

#!/bin/sh

# oPt2

1оор=0

while [ $# -ne 0 ] # цикл выполняется до тех пор, пока остаются аргументы do

echo $1

shift

done

Теперь, при выполнении этого сценария можно получить более приемлемый результат:

$ opt2 файл1 файл2 файл3

файл1 файл2 файл3

20.1.2. Последний параметр командной строки

Несмотря на то что команда eval еще не обсуждалась, можно воспользоваться ею, если требуется уточнить последний параметр командной строки (обычно в качестве этого параметра используется имя файла). Получить последний параметр командной строки вы можете двумя способами. Во–neрвых, с помощью команды eval echo $$#, а во–вторых, путем применения команды shift `expr $# – 2`.

20.1.3. Преобразования файла с помощью команды shift

Использование возможностей команды shift значительно облегчает работу с опциями командной строки. Рассмотрим сценарий, выполняющий преобразование регистра символов. При этом будет применяться команда tr.

При выполнении сценария используются две опции:

–l для нижнего регистра -u для верхнего регистра

С помощью команды shift можно запустить на выполнение сценарий, работающий с опциями -l и -u. Ниже приводится первый вариант этого сценария.

$ pg tr_case

#!/bin/sh

#tr_case

#преобразование регистра usage ()

{

# сообщение usage

echo "usage:`basename $0` -[l|u] file [files]" >&2

exit 1

}

if [ $# -eq 0 ]; then

# параметры не переданы!

usage

fi

while [ $# -gt 0 ]

do

case $1 in

–u|-U) echo " -uoption specified"

# здесь укажите все установки переменных для нижнего регистра, затем

# примените команду shift shift

;;

–l|-L) echo " -l option specified"

# здесь укажите все установки переменных для верхнего регистра, затем

# примените команду shift shift

;;

*) usage

;;

esac

done

Вначале выполняется проверка, имеются ли аргументы в сценарии. Если они отсутствуют, выводится сообщение usage. При обработке аргументов с помощью конструкции case отображается значение каждой передаваемой опции. После этого применяется команда shift, выполняющая вывод в командной строке очередной опции. Если все опции обработаны, отображается сообщение usage.

А теперь посмотрим, как выглядят выводимые результаты при передаче сценарию двух некорректных аргументов.

$ tr_case -u -l -к

– и option specified

–l option specified

usage: tr_case —[l|u] file [files]

На следующем этапе обрабатываются файлы, передающиеся после обработки опций с помощью конструкции case. Для реализации этой задачи достаточно выполнить небольшие изменения. В конструкции case шаблон * заменяется шаблоном -*, что позволяет передавать некорректные опции, например -p или -q.

Чтобы с помощью цикла for обрабатывать каждый файл, следует для всех передаваемых имен файлов указывать шаблон *. Кроме того, с помощью опции -f проверяется наличие всех требуемых имен файлов.

Итак, улучшенный вариант конструкции case имеет следующий вид:

case

...

–*) usage

*) if [ -f $1 ]; then

FILES=$FILES" "$1 # присвоить переменной имена файлов

else

echo "`basename $0` cannot find the file $1"

fi

shift # получите следующий параметр !

esac

Следует также задать значения некоторых переменных в зависимости от указанной опции (-1, – u). При этом используются следующие переменные:


TRCASE

Указывает тип преобразования регистра (верхний или нижний регистр)

ЕХТ

Все преобразованные файлы имеют либо расширение .UC (для верхнего регистра), либо расширение .LC (для нижнего регистра). В исходный файл изменения не вносятся

OPT

При передаче опций принимает значение yes, в противном случае – no. Только тогда, когда опции не передаются, можно перехватить их значение и вывести на экран сообщение

Для выполнения реального преобразования достаточно добавить еще один фрагмент кода, включающий команду tr. Этот фрагмент кода добавляется в конец сценария. При этом для считывания имен файлов используется цикл for и конструкция case. Ниже приводится код созданного сценария:

$ pg tr_case

#!/bin/sh

#tr_case

#преобразование символов файлов либо в верхний, либо в нижний регистр

FILES=""

TRCASE=""

EXT=""

OPT=no

# вызывается при неудачном преобразовании

error_msg ()

{

_FILENAME=$1

echo "`basename $0`: Error the conversion failed on $_FILENAME"

}

if [ $# -eq 0 ] then

echo "For more info try `basename $0` —help"

exit 1

fi

while [ $# -gt 0 ]

do

case $1 in

# установите переменные на базе применяемой опции

–u)

TRCASE=upper

ЕХТ=".UС"

OPT=yes

shift

;;

–l)

TRCASE=lower

EXT=".LC"

OPT=yes

shift

;;

–help) echo "convert a file(s) to uppercase from lowercase" echo "convert a file(s) from lowercase to uppercase" echo "will convert all characters according to the" echo " specified command option," echo " Where option ls"

echo " -l Convert to lowercase"

echo " -uConvert to uppercase"

echo " The original file(s) ls not touched. A new file(s)"

echo "will be created with either a. UC or. LC extension"

echo "usage; $0 -[l|u] file [file..]"

exit 0

;;

–*) echo "usage: `basename $0` -[l|u] file [file..]"

exit 1

;;

*) # сбор файлов для обработки

if [ -f $1]

then

# добавьте имена файлов в список переменных

FILES=$FILES" "$1

else

echo "`basename $0`: Error cannot find the file $1"

fi

shift

;;

esac

done

# опции не заданы… помогите пользователю

if [ "$OРТ"="no" ]

then

echo "`basename $0`: Error you need to specify an option. No action taken"

echo " try `basename $0` –help"

exit 1

fi

#просмотр всех файлов

#используется переменная LOOP, такое красивое слово LOOP

for LOOP in $FILES

do

case $TRCASE in

lower) cat $LOOP | tr "[a‑z]" "[A‑Z]" >$LOOP$EXT

if [ $? != 0 ]

then

error_msg $LOOP

else

echo "Converted file called $LOOP$EXT"

fi

;;

upper} cat $LOOP|tr "[A‑Z]" "[a‑z]" >$LOOP$EXT

if [ $? != 0 ]

then

error_msg $LOOP

else

echo "Converted file called $LOOP$EXT"

fi

;;

esac

done

Если выполнять указанный сценарий с различными опциями в качестве входных данных, получим следующие результаты.

При передаче имени несуществующего файла:

$ tr_case -k cursor

usage: shiftl -[l|u] file [file..}

При передаче некорректных опций:

$ tr_case cursor

tr case:Error you need to specify an option. No action taken try tr_case -help

Если просто указать имя файла в надежде на ответную помощь сценария, результатом будет:

$ tr_case

For more info try tr_case -help

Если указать два имени существующих файлов, а третье – имя несуществующего файла, получим следующие результаты:

$ tr_case -l cursor sd ascii

tr case: Error cannot find the file sd

Converted file called cursor.LC

Converted file called ascii.LC

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

Предположим, что существует сценарий, выполняющий обработку различных опций командной строки:

command -1 -с 23 -v файл1 файл2

Здесь нельзя применить команду shift; вместо нее следует воспользоваться командой getopts.

20.2. Команда getopts

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

20.2.1. Пример сценария, использующего команду getopts

С командой getopts лучше ознакомиться на основе примеров. Ниже приводится простой сценарий getopts, использующий следующие параметры, или аргументы:


-a

Переменной all присваивается значение "истина"

-h

Переменной help присваивается значение "истина"

-f

Переменной file присваивается значение "истина"

-v

Переменной verbose присваивается значение "истина'

Как обычно, при всех установках переменных всегда предполагается худший вариант, поэтому изначально переменным присваивается значение «ложь»:

$ pg getopt1

#/bin/sh #getopt1

# присвоение значений переменным

ALL=false

HELP=false

FILE=false

VERBOSE=false

while getopts ahfgv OPTION do

case $OPTION in

a)ALL=true

echo "ALL is $ALL"

;;

h)HELP=true

echo "HELP is $HELP"

;;

f)FILE=true

echo "FILE is $FILE"

;;

v)VERBOSE=true

echo "VERBOSE is $VERBOSE"

;;

esac

done

Общий формат команды getopts:

getopts строка_параметров переменная

А теперь используем код из нашего примера:

while getopts ahfgv OPTION

Нетрудно заметить, что цикл while применяется для считывания в командной строке. Параметр строка параметров включает пять указанных опций (-a, —h, —f, —g, —v), а также переменную, которая в данном примере именуется OPTION. Заметьте, что не требуется при определении каждой одиночной опции указывать дефис.

При выполнении сценария с корректными и некорректными опциями получаются следующие результаты:

$ getopt1 -a -h

ALL is true

HELP is true

$ getopt1 -ah

ALL is true

HELP is true

$ getopt1 -a -h -p

ALL is true

HELP is true

./getopt1: illegal option —p

Обратите внимание, что возможно комбинирование различных опций.

20.2.2. Принцип работы команды getopts

Команда getopts считывает строку строка_параметров. При этом она выбирает корректные опции, которые могут быть применены в сценарии.

Команда getopts разыскивает все аргументы, начинающиеся дефисом, и определяет значения всех опций. Затем значение опции сравнивается со строкой строка_параметров. Если соответствие установлено, переменной присваивается значение option. В противном случае переменной присваивается значение ?. Этот процесс продолжается до тех пор, пока не будут обработаны все опции.

Завершив обработку всех аргументов, команда getopts возвращает ненулевое состояние. Это означает, что все аргументы были переданы. Переменная Optind содержит значение последнего обработанного аргумента. В следующем разделе мы рассмотрим, какую пользу эта переменная может принести при обработке аргументов.

20.2.3. Указание значений опций с помощью команды getopts

Иногда для сценариев требуется включение фактического значения одной из опций командной строки. При этом используется команда getopts. Все, что требуется для этого сделать, – вставить двоеточие после буквы опции параметра строка_параметров. Например:

getopts ahfvc: OPTION

Эта команда определяет передачу опций a, h, f, v без указания значений, но опция с должна иметь значение. После указании значения оно будет присвоено переменной OPTARG. Если попытаться передать данную опцию без этого значения, отобразится сообщение об ошибке. Стандартное сообщение об ошибке не является особо информативным, поэтому "подавите" его отображение и выполните следующее:

Укажите двоеточие перед параметром строка_параметров.

while getopts :ahfgvc: OPTION

Используйте оператор usage внутри конструкции case. При этом применяется символ ?, выполняющий функции перехвата ошибок.

case

?) # оператор usage

echo "`basename $0` -[a h f v] -[с value] file"

esac

Ниже представлен измененный сценарий getopt1:

$ pg getopt1

#!/bin/sh

#getopt1

# установка значений переменных

ALL=false

HELP=false

FILE=false

VERBOSE=false

COPIES=0 # значение опции -c равно нулю

while getopts :ahfgvc: OPTION do

case $OPTION in

a)ALL=true

echo "ALL is $ALL"

;;

h)HELP=true

echo "HELP is $HELP"

;;

f}FILE=true

echo "FILE is $FILE"

;;

v)VERBOSE=true

echo "VERBOSE" is $VERBOSE"

;;

C)COPIES=$OPTARG

echo "COPIES is $COPIES"

;;

?) # оператор usage

echo "`basename $0` —[ahfv] —[c value] file" >&2

;;

esac done

При выполнении указанного выше сценария с опцией -c, не содержащей значения, возникает ошибка. В этом случае отображается сообщение usage:

$ getopt1 -ah -с

ALL is true

HELP is true

getopt1 —[ahfv] -[c value] file

Теперь указываются все допустимые опции:

$ getopt1 -ah -с 3

ALL is true HELP is true COPIES is 3

20.2.4. Доступ к значениям

Команда getopts часто применяется для выполнения сценариев резервирования. Благодаря этому пользователь может указывать различные ленточные накопители, используемые для резервирования данных. Ниже приводится образец сценария, использующего команду getopts.

$ pg backups

#!/bin/sh

# backups

QUITE=n

DEVICE=awa

LOGFILE=/tmp/logbackup

usage ()

(

echo "Usage: `basename $0` -d [device] – l [logfile] – q"

exit 1

}

if [ $# – 0 ]

then

usage fi

while getopts :qd:l: OPTION do

case $OPTION in

q) QUIET=y

LOGFILE="/tmp/backup.log"

;;

d) DEVICE=$OPTARG

;;

l) LOGFILE=$OPTARG

;;

?) usage

;;

esac done

echo "you chose the following options..I can now process these"

echo "Quite=$QUITE $DEVICE $LOGFILE"

В данном сценарии при указании опции d нужно присваивать значение. Это значение представляет собой наименование пути для ленточного накопителя. Пользователь может также определить, создавать ли резервную копию, если весь вывод направляется в журнальный файл. Выполнение сценария, использующего указанные ниже входные данные, приводит к следующим результатам:

$ backups -d /dev/rmt0 -q

you chose the following options..

I can now process these Quite=у /dev/rmt0 /tmp/backup.log

После того как команда getopts завершит выполнение проверки, значения, присвоенные OPTARG, могут быть использованы а процессе обычной обработки. Конечно, если в сценарии имеются опции, они должны быть установлены для дальнейшей обработки и проверки значений.

Вот и все, что требуется знать о том, каким образом команда getopts обеспечивает передачу параметров командной строки.

Для фактической обработки файлов используется цикл for, подобно тому, как это было в сценарии tr case, где применялась команда shift для работы с опциями.

Применение команды getopts позволяет радикально сократить объем создаваемого кода по сравнению с использованием метода shift-

20.2.5. Использование команды getopts для преобразования файлов

А теперь воспользуемся сценарием tr_case, который преобразуем с помощью только что изученной команды getopts. Существует единственное отличие между методами getopts и shift, применяемыми для обработки опций командной строки. Это отличие заключается в том, что в первом случае используется опция verbose.

Переменная verbose имеет значение "по", заданное по умолчанию; но при перехвате значения опции командной строки с помощью конструкции case переменной verbose присваивается значение "yes". Отображение команд на экране осуществляется с помощью простой конструкции if.

if [ "VERBOSE"="on" ]; then

echo "doing upper on $LOOP..newflie called $LOOP$EXT"

fi

Если применяется оболочка для системных команд, которые всегда отображают результаты своих действий, то вывод, включающий произвольные ошибки, просто перенаправляется в /dev/null.

command > /dev/null 2>&1

По умолчанию переменная verbose не установлена (нет отображения). Активизировать эту переменную можно посредством опции -v. Например, для преобразования серии файлов myfiles в символы нижнего регистра с помощью VERBOSE применяется следующий формат:

tr_case -1 -v myfilel myfile2…

либо

tr_case -v -1 myfilel myfile2…

Сразу же бросается в глаза заметное сокращение объема программного кода при использовании команды getopts. Код, применяемый для обработки файлов, аналогичен коду с командой shift.

Пример сценария:

$ pg tr_case2

#!/bin/sh

#tr_case2

# преобразование регистра, используется команда getopts

ЕХТ=""

TRCASE=""

FLAG=""

OPT="no"

VERBOSE="off"

while getopts :luv OPTION

do

case $OPTION in

l)

TRCASE="lower"

EXT=".LC"

OPT=yes

;;

u)

TRCASE="upper"

EXT=".UC"

OPT=yes

;;

v)

VERBOSE=on

;;

?) echo "usage: `basename $0`: -[l|u] —v file[s]"

exit 1

;;

esac

done

#следующий аргумент, пожалуйста

shift `expr $OPTIND -1`

#есть аргументы ???

if [ "$#"="0" ] || [ "$OPT"="no" ] then

echo "usage: `basename $0`: -[l|u] – v file[s]" >&2

exit 1

fi

for LOOP in "$@" do

if [ ! – f $LOOP ] then

echo "`basename $0`: Error cannot find file $LOOP" >&2

exit 1

fi

echo $TRCASE $LOOP

case $TRCASE in

lower)

if [ "VERBOSE"="on" ]; then

echo "doing…lower on $LOOP..newflie called $LOOP$EXT"

fi

cat $LOOP | tr "[a‑z]" "[A‑Z]" >$LOOP$EXT

;;

upper) if [ "VERBOSE"="on" ]; then

echo "doing upper on $LOOP..newflie called $LOOP$EXT"

fi

cat $LOOP | tr "[A‑Z]" "[a‑z]" >$LOOP$EXT

;;

esac

done

При указании опций командной строки в сценариях было бы неплохо придерживаться соглашений о наименовании, принятых в UNIX либо Linux. В следующей таблице описываются некоторые общие опции и их значения.

Опция

Значение

-a

добавление

-c

счетчик, копирование

-d

каталог, устройство

-e

выполнение

-f

имя файла, форсировать

-h

справка

-i

игнорировать регистр

-1

журнальный файл

-o

полный вывод

-q

полностью

-p

путь

-v

многословный

20.3. Заключение

Способность корректно обрабатывать опции командной строки придает сценариям профессиональный вид. Для пользователя эти опции выглядят точно так же, как любые другие системные команды. В этой главе были рассмотрены два метода, предназначенные для обработки опций командной строки, – shift и getopts. Размер программного кода, необходимого для внедрения метода getopts, является намного меньшим, чем в случае использования метода shift.

Метод shift также позволяет преодолеть ограничения параметров $1…$9, проявляющиеся при их передаче сценариям. При использовании метода shift сценарий просто выполняет "смещение" среди всех вызываемых аргументов, благодаря чему можно выполнять дальнейшую обработку.

ГЛАВА 21

Создание экранного вывода

С помощью shell–сценариев можно создавать профессионального вида экраны, позволяющие реализовать интерактивное взаимодействие пользователя с системой. Для этого достаточно располагать цветным монитором и использовать команду tput.

В главе рассматриваются следующие темы:

   • применение команды tput;

   • использование escape–последовательностей и генерирование управляющих кодов;

   • pабота с цветом.

Известно, что существует три различных варианта команды tput. Наилучшим из них является команда tput GNU. Если в системе отсутствует эта версия команды, загрузите и установите ее. Команда tput использует файл /etc/terminfo или файл /etc/termcap. В shell–сценариях можно применять большинство команд, поддерживаемых терминалом.

Команда tput не распознает настройки цвета. Для работы с цветом используются управляющие символы.

21.1. Применение команды tput

Чтобы применить команду tput, следует инициализировать установки терминала, обращаясь к команде tput с помощью сценариев или командной строки.

$ tput init

Команда tput генерирует три различных потока вывода: строки, числовые и булевы значения (истина/ложь). Далее будут рассмотрены некоторые наиболее часто используемые свойства каждого потока вывода.

21.1.1. Строчный поток вывода данных


    Ваша оценка произведения:

Популярные книги за неделю