В последующих разделах будет продемонстрировано большое количество разнообразных функций, а также рассмотрены различные способы применения возвращаемых и выводимых значений для функции.
После того, как будет создано несколько регулярно используемых функций, их можно поместить в файл функций, а затем загружать этой файл в среду интерпретатора shell.
В начале файла функции должна находиться конструкция #!/bin/sh. Этому файлу можно присвоить любое имя, но все же лучше использовать какое‑либо осмысленное наименование, например functions.main.
Как только файл будет загружен интерпретатором shell, появляется возможность вызова функций из командной строки либо из сценария. Чтобы просмотреть все определенные функции, воспользуйтесь командой set. Поток вывода будет содержать все функции, которые были загружены интерпретатором shell.
Для изменения любой из ранее определенных функций сначала примените команду
unset, после чего функция будет выгружена из интерпретатора shell. В результате этого данную функцию будет невозможно вызвать из пользовательских сценариев или интерпретатора команд, хотя физического удаления функции при этом не происходит. После внесения изменений в файл функций выполните его перезагрузку. Некоторые интерпретаторы команд могут распознавать изменения, и в этом случае применение команды unset вовсе не обязательно. Однако все же в целях безопасности всегда лучше использовать данную команду при модификации функций интерпретатора shell.
А теперь создадим файл функций, включающий одну функцию. Эта функция будет загружена интерпретатором команд, протестирована, изменена, а затем повторно загружена.
Создаваемый файл функций functions.main будет содержать следующий код:
$ 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). Причина отображения подобного сообщения заключается в том, что файл не является файлом сценария. В любом случае это сообщение не несет много информации для пользователя.
Команда подключения файла функций имеет следующий формат:
. /путь/имя_файла
Теперь, когда файл создан, настало время загрузить его содержимое в интерпретатор команд (подключить его). Введите команду:
$. functions.main
Если в результате выполнения этой команды возвращается сообщение 'file not found' (файл не найден), попытайтесь воспользоваться следующей командой:
$ . ./functions.main
В этом случае применяется нотация <точка><пробел><косая черта><имя файлах Теперь файл должен быть загружен интерпретатором команд. Если по–прежнему возникают ошибки, убедитесь в том, что было указано полное наименование пути к файлу.
Чтобы удостовериться в том, что функции были загружены интерпретатором команд, воспользуйтесь командой set, которая отображает все загруженные функции, доступные для сценария,
$ set
USER=dave
findit=()
{
if [ $# -lt 1 ]; then
echo "usage findit file";
return 1; fi; find / -name $1 -print
}
…
Для вызова функции просто введите ее имя (в данном случае findit) и укажите аргумент, в роли которого может выступать файл, размещенный в системе.
$ findit groups
/usr/bin/groups
/usr/local/backups/groups.bak
Теперь настало время немного изменить функцию. Сначала функция будет удалена, в результате чего она не будет доступна интерпретатору shell. Для выполнения этой операции применяется команда unset. При вызове данной команды используется следующий формат:
unset имя_функции $ unset findit
Если вы сейчас введете команду set, функция не будет найдена.
А теперь изменим файл fiinctions.main. Добавим в функцию цикл for, в результате чего сценарий сможет считывать более одного параметра из командной строки. Функция приобретет следующий вид: