Цель урока: Понять, что такое функции и какую пользу они приносят в скриптинге. Научиться объявлять и вызывать свои собственные функции, передавать в них аргументы (данные) и получать из них результат. Это фундаментальный навык, который позволяет писать чистый, структурированный и легко поддерживаемый код, избегая повторений.
Часть 1: Теория. Зачем упаковывать код?
Представьте, что вы пишете большой скрипт для резервного копирования. В разных частях скрипта вам нужно выводить на экран текущее время и сообщение. Вы, очевидно, можете каждый раз писать необходимую для этого команду echo "[$(date +'%Y-%m-%d %H:%M:%S')] Сообщение...". Но что если вы захотите изменить формат даты? Вам придется искать и исправлять эту строку по всему скрипту. Это неудобно и чревато ошибками.
Функция - это именованный блок кода, который вы можете "вызвать" (запустить) в любом месте вашего скрипта просто по его имени.
Основные преимущества использования функций:
-
Принцип DRY (Don't Repeat Yourself / Не повторяйся): Вы пишете код один раз и используете его многократно. Если нужно что-то изменить, вы меняете это только в одном месте - внутри функции.
-
Читаемость: Длинный и сложный скрипт можно разбить на логические части, каждая из которых - это функция с говорящим названием (например, check_disk_space, create_archive, send_report). Такой код гораздо легче читать и понимать.
-
Переиспользование: Хорошо написанную функцию можно легко скопировать из одного скрипта в другой для решения похожих задач.
Часть 2: Практика. Объявление и вызов простой функции
Синтаксис:
Существует два равнозначных способа объявить функцию. Мы будем использовать второй, так как он более распространен.
# Способ 1
function имя_функции {
# Команды внутри функции
}
# Способ 2 (рекомендуемый)
имя_функции() {
# Команды внутри функции
}
-
имя_функции() - придуманное вами имя с обязательными круглыми скобками после него.
-
{ ... } - фигурные скобки, которые обрамляют тело функции.
Как вызвать функцию:
Просто напишите ее имя в скрипте, как будто это обычная команда.
Пример 1: Функция для вывода разделителя
Давайте создадим скрипт с простой функцией, которая печатает красивую линию-разделитель.
Шаг 1: Создание файла
Перейдем в наш каталог со скриптами и создадим новый файл.
cd ~/scripts
nano function_example_1.sh
Шаг 2: Вставка кода
#!/bin/bash
# =======================================================
# Объявляем нашу первую функцию.
# Лучшей практикой считается объявлять все функции
# в начале скрипта, до основного кода.
# =======================================================
print_separator() {
echo "========================================="
}
# =======================================================
# Основной код нашего скрипта
# =======================================================
echo "Начинаем выполнение важной задачи..."
# Вызываем нашу функцию в первый раз
print_separator
echo "Задача №1 выполнена."
echo "Подготовка к задаче №2..."
# Вызываем нашу функцию во второй раз
print_separator
echo "Задача №2 выполнена."
# И в третий раз...
print_separator
Шаг 3: Сохранение, права и запуск
-
В nano сохраните файл (Ctrl+O, Enter) и выйдите (Ctrl+X).
-
Сделайте скрипт исполняемым:
chmod +x function_example_1.sh
-
Запустите скрипт:
./function_example_1.sh
Вы увидите, как ваша линия-разделитель была напечатана трижды, хотя вы написали команду echo всего один раз внутри функции.
Часть 3: Практика. Передача данных в функции (Аргументы)
Функции могут принимать данные для обработки, точно так же, как скрипты принимают аргументы командной строки. Внутри функции они доступны как позиционные параметры: $1 (первый аргумент), $2 (второй) и так далее.
Пример 2: Функция, которая здоровается с кем угодно
Шаг 1: Создание файла
nano function_example_2.sh
Шаг 2: Вставка кода
#!/bin/bash
# Функция, которая принимает один аргумент - имя.
greet() {
# $1 - это первый аргумент, переданный функции greet
local name=$1
echo "Привет, $name! Добро пожаловать в мир функций."
}
# Основной код
echo "--- Начало работы скрипта ---"
# Вызываем функцию, передавая ей разные аргументы
greet "Анна"
greet "Виктор"
echo "--- Скрипт завершен ---"
Что нового и важного:
-
local name=$1: Ключевое слово local создает переменную, которая видна только внутри этой функции. Это очень хорошая практика, которая предотвращает случайное изменение одноименных переменных в остальной части скрипта. Старайтесь всегда использовать local для переменных внутри функций.
Шаг 3: Сохранение, права и запуск
-
Сохраните и выйдите из nano.
-
Дайте права:
chmod +x function_example_2.sh
-
Запустите:
./function_example_2.sh
Часть 4: Практика. Получение результата от функции (Return vs Echo)
Это очень важный момент. В Bash есть два способа "вернуть" что-то из функции, и они служат разным целям.
1. return: для возврата кода завершения (статуса)
Команда return работает так же, как exit для всего скрипта, но действует только для функции. Она возвращает число от 0 до 255. По соглашению: 0 - успех, не 0 - ошибка.
Пример 3: Функция, проверяющая существование файла
Шаг 1: Создание файла
nano function_example_3.sh
Шаг 2: Вставка кода
#!/bin/bash
# Функция проверяет, существует ли файл.
# Возвращает 0 (успех), если да, и 1 (ошибка), если нет.
check_file_exists() {
local filename=$1
if [ -f "$filename" ]
then
# Файл существует, возвращаем успех
return 0
else
# Файл не существует, возвращаем ошибку
return 1
fi
}
# Основной код
# Вызываем функцию и СРАЗУ ЖЕ проверяем ее код завершения ($?) с помощью if
if check_file_exists "/etc/hosts"
then
echo "Проверка успешна: файл /etc/hosts существует."
else
echo "Проверка провалилась: файл /etc/hosts НЕ существует."
fi
if check_file_exists "/etc/nonexistentfile"
then
echo "Проверка успешна: файл /etc/nonexistentfile существует."
else
echo "Проверка провалилась: файл /etc/nonexistentfile НЕ существует."
fi
Шаг 3: Сохранение, права и запуск
-
Сохраните, выйдите, дайте права
chmod +x function_example_3.sh
, запустите./function_example_3.sh
-
Вы увидите, как if смог "поймать" результат работы функции и выполнить правильный блок кода.
2. echo: для возврата данных (текста, чисел)
Если вам нужно, чтобы функция вернула не статус, а какие-то данные (например, строку текста), правильный способ - это напечатать эти данные в стандартный вывод (stdout) с помощью echo. А в основном коде "поймать" этот вывод с помощью командной подстановки $(...).
Пример 4: Функция, которая создает форматированную строку с датой
Шаг 1: Создание файла
nano function_example_4.sh
Шаг 2: Вставка кода
#!/bin/bash
# Эта функция не выводит ничего на экран сама.
# Она "возвращает" отформатированную строку даты через stdout.
get_timestamp() {
date +'%Y-%m-%d %H:%M:%S'
}
# Основной код
echo "Начинаем скрипт..."
# "Ловим" вывод функции get_timestamp в переменную
current_time=$(get_timestamp)
echo "Текущее время, полученное от функции: $current_time"
echo "Скрипт завершен."
Шаг 3: Сохранение, права и запуск
-
Сохраните, выйдите, дайте права
chmod +x function_example_4.sh
, запустите./function_example_4.sh
Итоги урока
-
Что мы освоили:
-
Что функции помогают избежать повторения кода и делают его более читаемым.
-
Как объявлять (my_func() { ... }) и вызывать (my_func) функции.
-
Как передавать в них аргументы ($1, $2) и использовать внутри local переменные.
-
Два способа "вернуть" результат: return для статуса (0/1) и echo для данных (текста).
-
Как "ловить" данные от функции с помощью конструкции variable=$(my_function).
-
На следующем, 16-м уроке, мы глубоко погрузимся в одну из самых мощных команд Linux - find. Мы научимся искать файлы и каталоги не просто по имени, а по множеству критериев: размеру, дате изменения, правам доступа, владельцу, а также выполнять над найденными файлами произвольные команды. Это выведет нашу способность к автоматизации на совершенно новый уровень.
Перейти к просмотру - УРОК №16.
Промо-код: PROMO15 - скидка 15%!
Введите при оформлении первого заказа на сайте: Hosting-VDS.com