Литмир - Электронная Библиотека

$ pg functions.main

#!/bin/sh

# functions.main

#

findit: интерфейс для базовой команды find

findit () (

#findit

if [ $# -lt 1 ]; then

echo "usage: findit file"

return 1

find / -name $1 -print

Код, приведенный выше, ранее уже упоминался в книге, но теперь он включен в состав функции. Этот код лежит в основе интерфейса для базовой команды find . Если команде не передаются аргументы, то возвращается значение 1 (что свидетельствует о возникновении ошибки). Обратите внимание, что ошибочная конструкция фактически является отображенным именем функции (если же была использована команда $0, интерпретатор команд просто возвращает сообщение sh). Причина отображения подобного сообщения заключается в том, что файл не является файлом сценария. В любом случае это сообщение не несет много информации для пользователя.

19.8. Подключение файла функций

Команда подключения файла функций имеет следующий формат:

. /путь/имя_файла

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

$. functions.main

Если в результате выполнения этой команды возвращается сообщение 'file not found' (файл не найден), попытайтесь воспользоваться следующей командой:

$ . ./functions.main

В этом случае применяется нотация <точка><пробел><косая черта><имя файлах Теперь файл должен быть загружен интерпретатором команд. Если по–прежнему возникают ошибки, убедитесь в том, что было указано полное наименование пути к файлу.

19.9. Проверка загруженных функций

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

$ set

USER=dave

findit=()

{

if [ $# -lt 1 ]; then

echo "usage findit file";

return 1; fi; find / -name $1 -print

}

19.10. Вызов функций интерпретатора shell

Для вызова функции просто введите ее имя (в данном случае findit) и укажите аргумент, в роли которого может выступать файл, размещенный в системе.

$ findit groups

/usr/bin/groups

/usr/local/backups/groups.bak

19.10.1. Удаление shell–функций

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

unset имя_функции $ unset findit

Если вы сейчас введете команду set, функция не будет найдена.

19.10.2. Редактирование shell–функций

А теперь изменим файл fiinctions.main. Добавим в функцию цикл for, в результате чего сценарий сможет считывать более одного параметра из командной строки. Функция приобретет следующий вид:

$ pg functions.main

#!/bin/sh findit ()

{

# findit

#if [ $# -lt 1 3; then

echo "usage: findit file"

return 1 fi

for loop do

find / -name $LOOP -print done }

Снова загрузим исходный файл:

$ . ./functions.main

Используйте команду set, чтобы убедиться, что файл действительно загружен. Если интерпретатор shell корректно интерпретирует цикл for и воспринимает все требуемые параметры, на экране отобразится соответствующее сообщение.

$ set

findit=()

{

if [ $# -lt 1 ]; then

echo "usage :`basename $0` file";

return 1; fi;

for loop in "$@"; do

find / -name $LOOP -print; done }

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

$ findit LPSO.doc passwd

/usr/local/accounts/LPSO.doc

/etc/passwd

19.10.3. Примеры функций

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

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

Подтверждение ввода

Рассмотрим небольшой сценарий, который запрашивает имя и фамилию пользователя:

$ pg func2

#!/bin/sh

# func2

echo -n "What ls your first name :"

read F_NAME

echo -n "What ls your surname:"

read S_NAME

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

char_name()

{

#char_name

#вызов: char_name string

#назначение аргумента новой переменной

_LETTERS_ONLY=$1

#использование awk для проверки на наличие символов!

_LETTERS_ONLY=`echo $1 | awk '{if [$0~/[^a‑zA‑Z]/} print "1"}'`

if [ "$_LETTERS_ONLY" != "" ] then

# ошибки

return 1

else

# содержит только символы

return 0

fi }

Сначала переменной $1 будет присвоено более осмысленное имя. Затем применяется утилита awk, осуществляющая проверку, состоит ли переданная строка из одних литер. В результате выполнения возвращается код, включающий 1 (для символов, не являющихся литерами) и 0 — для символов–литер. Этот код присваивается переменной _LETTERS_ONLY.

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

Для проверки вывода функции можно использовать формат, применяемый для оператора if:

if char_name $F_NAME; then

echo "OK"

else

echo "ERRORS"

fi

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

name_error ()

# name_error

# отображение сообщения об ошибке

{

echo " $@ contains errors, it must contain only letters"

}

Функция name_error будет отображать сообщения об ошибках, игнорируя при этом все некорректные записи. Применение специальной переменной $@ позволяет отображать на экране значения всех аргументов. В рассматриваемом случае будет отображено либо значение f_name, либо значение $NAME. А теперь приведем завершенный сценарий, созданный с применением функций:

$ pg func2

#!/bin/sh

char_r.ame {)

# наименование_символа

# вызов: char_name строка

# проверка на предмет того, действительно ли $1 содержит только символы a‑z.,A‑Z

{

# присвоение аргумента новой переменной

_LETTERS_ONLY=$1

_:LETTERS_ONLY=`echo $1|awk '{ if ($0~/[^a‑zA‑Z]/) print "1"}`

if [ "$_LETTERS_ONLY" != "" ]

then

# присутствуют ошибки

return 1

else

# содержит только символы

return 0

fi }

name_error()

# отображение сообщения об ошибке

{

echo " $@ contains errors, it must contain only letters"

70
{"b":"273485","o":1}