Выбрать главу

local temp=$(( $value + 5 ))

Если за пределами функции есть переменная с таким же именем, это на неё не повлияет. Ключевое слово local позволяет отделить переменные, используемые внутри функции, от остальных переменных.

Рассмотрим пример:

#!/bin/bash

function myfunc {

local temp=$[ $value + 5 ]

echo "The Temp from inside function is $temp"

}

temp=4

myfunc

echo "The temp from outside is $temp"

Запустим скрипт.

Локальная переменная в функции

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

Передача функциям массивов в качестве аргументов

Попробуем передать функции в качестве аргумента массив. Сразу хочется сказать, что работать такая конструкция будет неправильно:

#!/bin/bash

function myfunc {

echo "The parameters are: $@"

arr=$1

echo "The received array is ${arr[*]}"

}

myarray=(1 2 3 4 5)

echo "The original array is: ${myarray[*]}"

myfunc $myarray

Неправильный подход к передаче функциям массивов

Как видно из примера, при передаче функции массива, она получит доступ лишь к его первому элементу.

Для того, чтобы эту проблему решить, из массива надо извлечь имеющиеся в нём данные и передать их функции как самостоятельные аргументы. Если надо, внутри функции полученные ей аргументы можно снова собрать в массив:

#!/bin/bash

function myfunc {

local newarray

newarray=("$@")

echo "The new array value is: ${newarray[*]}"

}

myarray=(1 2 3 4 5)

echo "The original array is ${myarray[*]}"

myfunc ${myarray[*]}

Запустим сценарий.

Сборка массива внутри функции

Как видно из примера, функция собрала массив из переданных ей аргументов.

Рекурсивные функции

Рекурсия — это когда функция сама себя вызывает. Классический пример рекурсии — функция для вычисления факториала. Факториал числа — это произведение всех натуральных чисел от 1 до этого числа. Например, факториал 5 можно найти так:

5! = 1 * 2 * 3 * 4 * 5

Если формулу вычисления факториала написать в рекурсивном виде, получится следующее:

x! = x * (x-1)!

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

#!/bin/bash

function factorial {

if [ $1 -eq 1 ]

then

echo 1

else

local temp=$(( $1 - 1 ))

local result=$(factorial $temp)

echo $(( $result * $1 ))

fi

}

read -p "Enter value: " value

result=$(factorial $value)

echo "The factorial of $value is: $result"

Проверим, верно ли работает этот скрипт.

Вычисление факториала

Как видите, всё работает как надо.

Создание и использование библиотек

Итак, теперь вы знаете, как писать функции и как вызывать их в том же скрипте, где они объявлены. Что если надо использовать функцию, тот блок кода, который она собой представляет, в другом скрипте, не используя копирование и вставку?

Оболочка bash позволяет создавать так называемые библиотеки — файлы, содержащие функции, а затем использовать эти библиотеки в любых скриптах, где они нужны.

Ключ к использованию библиотек — в команде source. Эта команда используется для подключения библиотек к скриптам. В результате функции, объявленные в библиотеке, становятся доступными в скрипте, в противном же случае функции из библиотек не будут доступны в области видимости других скриптов.

У команды source есть псевдоним — оператор «точка». Для того, чтобы подключить файл в скрипте, в скрипт надо добавить конструкцию такого вида:

. ./myscript

Предположим, что у нас имеется файл myfuncs, который содержит следующее:

function addnum {

echo $(( $1 + $2 ))

}

Это — библиотека. Воспользуемся ей в сценарии:

#!/bin/bash

. ./myfuncs

result=$(addnum 10 20)

echo "The result is: $result"

Вызовем его.

Использование библиотек

Только что мы использовали библиотечную функцию внутри скрипта. Всё это замечательно, но что если мы хотим вызвать функцию, объявленную в библиотеке, из командной строки?

Вызов bash-функций из командной строки

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