Функции в 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. “Функции

bash