Функции в bash
Вызов функций
В bash функция вызывается также, как и любая другая команда/скрипт.
Для функции bash не запускает новый процесс, поэтому такой вызов эффективнее запуска внешней команды/сценария.
Вызовы функций в bash не возвращают значений, которые можно присвоить переменным.
Do_Something
Find_File 25 $MPATH $ECODE
Show_All $*
Определение функций
Определение функций должно стоять до ее вызова.
В синтаксисе определения функций в bash есть необязательные элементы.
Три эквивалентных варианта объявления:
function Helper ()
function Helper # лучший способ 4 me
Helper ()
Второй вариант явно показывает объявление функции, напоминает, что в bash параметры функций не заключается в круглые скобки () и его легко найти w/ grep.
Тело функции идет в фигурных скобках после определения имени функции:
function Say_So {
echo 'smth'
}
Параметры функций
В bash не определяются параметры функций - вызывая функцию, можно указать любое кол-во параметров.
Аргументы доступны в фукнции под именами \$1, \$2, \$3 и т.д., как параметры сценария. Поэтому полезно в начале функции описывать входные параметры и их ожидаемый порядок.
Вызов функции не изменяет параметры сценария - их просто не видно внутри функции (если их не передать в функцию в агрументах, конечно).
FUNCNAME
Параметр \$0 содержит имя сценария даже внутри функций. Есть специальная переменная-массив FUNCNAME, которая содержит стек вызовов функций. Имя текущей функции всегда находится в элементе 0, => получить имя функции можно w/ $FUNCNAME
(указание имени массива без индекса возвращает первый элемент).
Пример функции, которая выводит значения переданных ей аргументов:
function See2it {
echo "First: $1"
echo "Second: $2"
}
Если передать меньше аргументов, чем ожидается - соответствующие параментры будут пустыми.
Возвращаемые значения функций
Возврващаемое значение функций в bash - это просто статус (код завершения) - то, что хранится в \$?. In this case, в \$? помещается статус последней команды, выполненной в функции.
Юзать это можно, передав результат функции куда-нибудь или сохранив вывод в переменной /w \$() (которая запустит функцию в подоболочке).
Локальные переменные
function Summer {
local i
SUM=0
for((i=0; i<$1; i++)) {
let SUM+=1;
}
}
Btw, здесь лучше юзать local -i
или declare -i
, чтобы объявить переменную целочисленной (внутри функции declare
работает так же, как local
).
Динамическая область видимости
Если объявить локальну переменную в функции, а потом вызвать из нее другую функцию, то последняя увидит локальную переменную первой, а не глобальную переменную с тем же именем. А если вызвать вторую функцию из основого сценария - она увидит глобальную переменную (и будет ее юзать).
Это опасное поведение - еще одна причина, почему скрипты bash должны быть простыми и документированными.
Оператор перенаправления после определения функции
В определение функции можно юзать оператор пернаправления i/o, который будет выполняться в момент вызова функции:
function Usage_Message {
<тело функции>
} &>2
Получается, что достаточно один раз после закрывающей фигурной скобки указать оператор перенаправления, а не в каждой строке внутри функции...
Соус: Книга "Идиомы Bash" --> Глава 6. "Функции"