Bash функции

Bash функции

Функция Bash — это, по сути, набор команд, который можно вызывать множество раз. Цель функции — помочь вам сделать ваши сценарии bash более читаемыми и избежать написания одного и того же кода.

По сравнению с большинством языков программирования, функции Bash сильно ограничены. В этом руководстве мы рассмотрим основы функций Bash и разберемся, как использовать их в скриптах оболочки shell.

Объявление функции Bash

Синтаксис объявления очень прост и похож на многие популярные языки программирования. Есть два основных формата объявления:

  1. Формат может начинаться с имени функции, за которым следуют круглые скобки. Это предпочтительный и наиболее популярный формат.
    function_name () {
      commands
    }

    Этот же код можно написать в одну строку:

    function_name () { commands; }
  2. Второй формат начинается с зарезервированного слова function, за которым следует имя функции.
    function function_name {
      commands
    }

    Версия в одну строку:

    function function_name { commands; }

Несколько моментов, которые следует запомнить:

  • Список команд, находящихся между фигурными скобками {} — это тело функции. Фигурные скобки, окружающие тело функции, должны быть отделены от тела пробелами или начинаться с новой строки.
  • Простое определение функции не выполняет её. Чтобы вызвать функцию bash, просто используйте имя созданной функции. Команды между фигурными скобками выполнятся, когда функция вызывается через shell оболочку.
  • Соблюдайте порядок написания кода. Определение функции должно быть перед её вызовом.
  • При использовании одно-строчных функций необходимо установить точку с запятой у последней команды.
  • Старайтесь давать имена, которые описывают процесс происходящий внутри тела функции. Чтобы в будущем понимать что делает программный код, взглянув лишь на название.

Чтобы лучше понять базовые правила, взглянем на следующий пример:

#!/bin/bash

hello_world () {
   echo 'привет, мир'
}

hello_world

Проанализируем написанный код:

  • В третьей мы определяем функцию с именем hello_world и открывая фигурную скобку {, которая отмечает начало тела функции.
  • Строка 4 — это тело функции. Обычно, тело занимает более одной строки.
  • В пятой строке стоит закрывающая фигурная скобка }. Она определяет конец функции.
  • В строке 7 мы выполняем созданную функцию. Выполнять ее можно столько раз, сколько вам нужно.

Если запустить такой скрипт в консоли, он выведет на экран строку:

привет, мир

Область переменных

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

Локальные переменные могут быть объявлены в теле функции с ключевым словом local, а использоваться могут только внутри неё. Вы можете иметь локальные переменные с одинаковым именем в разных функциях. Чтобы лучше понять, как работает область переменных в Bash, рассмотрим пример:

#!/bin/bash

var1='A'
var2='B'

my_function () {
  local var1='C'
  var2='D'
  echo "Внутри функции: var1: $var1, var2: $var2"
}

echo "Перед запуском: var1: $var1, var2: $var2"

my_function

echo "После запуска: var1: $var1, var2: $var2"

Этот скрипт начинается с определения двух глобальных переменных var1 и var2. Затем объявление функции, которая присваивает локальной переменной var1 и изменяет глобальную переменную var2.

Если вы запустите сценарий, вы увидите следующие строки:

Перед запуском: var1: A, var2: B
Внутри функции: var1: C, var2: D
После запуска: var1: A, var2: D

Из этого следует простой вывод:

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

Возвращаем значения

В отличие от функций на “реальных” языках программирования, функции в Bash не позволяют возвращать значение при вызове. Когда функция bash завершается, ее возвращаемое значение — это значение последнего оператора: 0 — успех, а ненулевое десятичное число в диапазоне от 1 до 255 включительно — для описания сбоя.

Статус возврата значения можно указать с помощью ключевого слова return и оно присваивается переменной $?. Оператор return завершает работу функции. Вы можете думать об этом как о способе выхода из функции.

#!/bin/bash

my_function () {
  echo "наш результат"
  return 13
}

my_function
echo $?
Вывод консоли:
наш результат
13

Как же, все-таки, вернуть значение из функции? Нам нужно использовать для этого небольшую хитрость — можно присвоить результат функции глобальной переменной:

#!/bin/bash

my_function () {
  func_result="наш результат"
}

my_function
echo $func_result

После выполнения этого кода, вы должны увидеть строку на экране:

наш результат

Другой, подходящий вариант для возврата значения из функции — отправить значение в stdout с помощью echo или printf, как показано ниже:

#!/bin/bash

my_function () {
  local func_result="это тест"
  echo "$func_result"
}

func_result="$(my_function)"
echo $func_result

Результат выполнения будет таким же.

Вместо того, чтобы просто выполнять функцию, которая будет печатать сообщение в stdout, мы присваиваем результат переменной func_result с помощью механизма $ (). Используя этот метод, глобальная переменная func_result будет содержать результат функции.

Передача аргументов

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

  • Переданные параметры $1, $2, $3 … $n, соответствуют номеру параметра по порядку, заданными после имени функции.
  • Переменная $0 зарезервирована для имени функции.
  • Переменная $# содержит общее количество аргументов, переданных функции.
  • Переменная $* или $@ содержит все параметры, переданные функции.

Пример передачи аргументов:

#!/bin/bash

greeting () {
  echo "Привет, $1"
}

greeting "Алиса"

Результатом выполнения этого кода будет строка:

Привет, Алиса

Теперь у вас есть некоторые знания для того, чтобы правильно писать функции bash.

Примеры

Функция таймер, которая считает сколько прошло времени:

timer() { local t; t=$(date '+%s'); test $# -gt 0 && let t-=$1; echo "$t"; }
...
t=$(timer)
...
...
t=$(timer $t)
echo "time used = $t secs"

Оставьте комментарий