Функции в bash
Вызов функций
В bash функция вызывается также, как и любая другая команда/скрипт.
Для функции bash не запускает новый процесс, поэтому такой вызов эффективнее запуска внешней команды/сценария.
Вызовы функций в bash не возвращают значений, которые можно присвоить переменным.
Определение функций
Определение функций должно стоять до ее вызова.
В синтаксисе определения функций в bash есть необязательные элементы.
Три эквивалентных варианта объявления:
Второй вариант явно показывает объявление функции, напоминает, что в bash параметры функций не заключается в круглые скобки () и его легко найти w/ grep.
Тело функции идет в фигурных скобках после определения имени функции:
Параметры функций
В bash не определяются параметры функций - вызывая функцию, можно указать любое кол-во параметров.
Аргументы доступны в фукнции под именами $1, $2, $3 и т.д., как параметры сценария. Поэтому полезно в начале функции описывать входные параметры и их ожидаемый порядок.
Вызов функции не изменяет параметры сценария - их просто не видно внутри функции (если их не передать в функцию в агрументах, конечно).
FUNCNAME
Параметр $0 содержит имя сценария даже внутри функций. Есть специальная переменная-массив FUNCNAME, которая содержит стек вызовов функций. Имя текущей функции всегда находится в элементе 0, ⇒ получить имя функции можно w/
$FUNCNAME
(указание имени массива без индекса возвращает первый элемент).
Пример функции, которая выводит значения переданных ей аргументов:
Если передать меньше аргументов, чем ожидается - соответствующие параментры будут пустыми.
Возвращаемые значения функций
Возврващаемое значение функций в bash - это просто статус (код завершения) - то, что хранится в $?. In this case, в $? помещается статус последней команды, выполненной в функции.
Юзать это можно, передав результат функции куда-нибудь или сохранив вывод в переменной /w $() (которая запустит функцию в подоболочке).
Локальные переменные
Btw, здесь лучше юзать local -i
или declare -i
, чтобы объявить переменную целочисленной (внутри функции declare
работает так же, как local
).
Динамическая область видимости
Если объявить локальну переменную в функции, а потом вызвать из нее другую функцию, то последняя увидит локальную переменную первой, а не глобальную переменную с тем же именем. А если вызвать вторую функцию из основого сценария - она увидит глобальную переменную (и будет ее юзать).
Это опасное поведение - еще одна причина, почему скрипты bash должны быть простыми и документированными.
Оператор перенаправления после определения функции
В определение функции можно юзать оператор пернаправления i/o, который будет выполняться в момент вызова функции:
Получается, что достаточно один раз после закрывающей фигурной скобки указать оператор перенаправления, а не в каждой строке внутри функции…
Соус: Книга “Идиомы Bash” → Глава 6. “Функции”