Функции и локальные переменные

Разбиваем скрипт на переиспользуемые блоки — функции.

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

Объявление и вызов

Функция объявляется именем и фигурными скобками. Вызывается как обычная команда — без скобок, аргументы через пробел.

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

greet Аня
greet Борис

Вывод:

Привет, Аня!
Привет, Борис!

Внутри функции $1, $2, $@ — это аргументы ФУНКЦИИ, а не скрипта. Это удобно: один и тот же синтаксис.

Локальные переменные

По умолчанию все переменные в Bash глобальные — даже объявленные внутри функции. Это источник коварных багов. Слово local делает переменную видимой только внутри функции:

counter=0

increment() {
  local counter=100
  counter=$((counter + 1))
  echo "внутри: $counter"
}

increment
echo "снаружи: $counter"

Вывод:

внутри: 101
снаружи: 0

Без local функция затёрла бы глобальный counter. Всегда объявляйте внутренние переменные функции через local.

Как функция «возвращает» результат

В Bash функция не возвращает значение как в других языках. Есть два механизма. Первый — напечатать результат через echo и поймать подстановкой команд:

square() {
  echo $(( $1 * $1 ))
}

result=$(square 5)
echo "Квадрат: $result"

Вывод:

Квадрат: 25

Второй — return N задаёт КОД ВОЗВРАТА (0..255), это статус успеха, а не данные. Его проверяют через if или $?.

Как работает под капотом

Функция выполняется в той же оболочке, что и скрипт (не в под-оболочке), поэтому она видит и может менять глобальные переменные — отсюда важность local. return кладёт число в $? и завершает функцию, не трогая stdout. А echo внутри функции пишет в stdout, который перехватывает $(...). Поэтому «данные» возвращают через echo, а «успех/неудачу» — через return.

Частые ошибки

  • Ждать число от return. return 25 — это код возврата, а не результат; для чисел больше 255 он не годится. Печатайте через echo.
  • Забыть local. Переменная функции затрёт глобальную с тем же именем.
  • Вызывать функцию со скобками. greet("Аня") — синтаксис других языков; в Bash greet Аня.

Итог

  • Функция — это name() { ... }, вызывается как name арг1 арг2; внутри аргументы — $1, $@.
  • local ограничивает переменную функцией — используйте всегда.
  • Данные возвращают через echo + $(...), а код успеха — через return (0..255).
Проверьте себя
1. Как внутри функции получить её первый аргумент?
A$arg1
B$1
C${func:1}
Dargs[0]
2. Зачем объявлять переменную через local внутри функции?
AЧтобы она работала быстрее
BЧтобы она не затирала глобальную переменную с тем же именем
Clocal обязателен по синтаксису
DЧтобы вернуть значение
3. Как функция в Bash возвращает вычисленное число, например квадрат?
Areturn результат
BПечатает через echo, а вызывающий ловит через $(...)
CЧерез массив
DЧерез глобальную переменную RESULT обязательно