Bash функции · 7 min read · Dec 07, 2025
Часть V: Функции в Bash
Привет! Добро пожаловать в серию учебников по сценариям оболочки от HowToForge. Если вы хотите прочитать предыдущие выпуски учебника, не стесняйтесь нажать здесь для части1, части2, части3 и части4 учебника. В этой части вы научитесь эффективно структурировать свои сценарии, создавая функции. К концу этого учебника вы сможете создавать функции в оболочке Linux Bash, передавать параметры вашим функциям и возвращать некоторые значения из функции в ваш основной код. Давайте начнем!
Введение
Функция, также известная как подпрограмма в языках программирования, представляет собой набор инструкций, выполняющих конкретную задачу для основной программы [1]. Это позволяет программистам разбивать сложный и длинный код на небольшие части, которые можно вызывать по мере необходимости. Каждую функцию необходимо вызывать из основной программы, чтобы она работала, таким образом, она изолирована от других частей вашего кода, что создает простой способ тестирования кода. Кроме того, функции могут вызываться в любое время и многократно, что позволяет вам повторно использовать, оптимизировать и минимизировать ваш код. Как и большинство языков программирования, оболочка bash также поддерживает функции.
Общий синтаксис:
- Синтаксис 1:
function function_name { ##### набор команд } - Синтаксис 2:
function_name() { #### набор команд }
Создание функций
Bash поддерживает две структуры для функций. При использовании первого синтаксиса вам нужно использовать ключевое слово function, за которым следует имя вашей функции и открывающие и закрывающие скобки и фигурные скобки, чтобы отделить содержимое ваших функций от вашей основной программы. Вы найдете этот синтаксис знакомым, если у вас есть опыт работы с PHP, потому что функции в PHP объявляются аналогичным образом. Другой синтаксис состоит только из имени функции, открывающих и закрывающих скобок и фигурных скобок.
#!/bin/bash
myfunction(){
echo "Моя функция работает!"
}
myfunction
Я использовал второй синтаксис в нашем примере. После создания функции myfunction она была вызвана, вызвав ее имя функции в нашей основной программе. Основная программа будет находиться в любом месте нашего сценария, которое не было определено как часть нашей функции.
Теперь давайте перестроим наш код, чтобы проверить, могут ли функции быть объявлены в любом месте нашего сценария. Рассмотрим код ниже:
#!/bin/bash
echo "тестирование моей функции"
myfunction
myfunction(){
echo "Моя функция работает!"
}
Строка 3 в приведенном выше коде возвращает ошибку “команда не найдена”. Это только означает, что:
Функция работает только если она объявлена до вашей основной программы. Интерпретатор вернет ошибку, если вы объявили вашу функцию после вашей основной программы.Реструктурирование кода с использованием функций
Одной из лучших функций является возможность повторного использования кода. Когда процедура требует многократного выполнения команд, но не может быть структурирована с использованием операторов циклов, то функция может быть решением.
Например, рассмотрим код ниже:
#!/bin/bash
while(true)
do
clear
printf "Выберите одну из следующих операций: \n"
printf "[a]добавление\n[b]вычитание\n[c]умножение\n[d]деление\n"
printf "################################\n"
read -p "Ваш выбор: " choice
case $choice in
[aA])
read -p "Введите первое целое число: " int1
read -p "Введите второе целое число: " int2
res=$((int1+int2))
;;
[bB])
read -p "Введите первое целое число: " int1
read -p "Введите второе целое число: " int2
res=$((int1-int2))
;;
[cC])
read -p "Введите первое целое число: " int1
read -p "Введите второе целое число: " int2
res=$((int1*int2))
;;
[dD])
read -p "Введите первое целое число: " int1
read -p "Введите второе целое число: " int2
res=$((int1/int2))
;;
*)
res=0
echo "неправильный выбор!"
esac
echo "Результат: " $res
read -p "Хотите продолжить? [y]es или [n]o: " ans
if [ $ans == 'n' ]
then
echo "Выход из сценария. Хорошего дня!"
break
else
continue
fi
done
Сценарий работает хорошо, однако обратите внимание, что строки для ввода данных повторяются в каждом шаблоне в нашем операторе switch.
#!/bin/bash
inputs(){
read -p "Введите первое целое число: " int1
read -p "Введите второе целое число: " int2
}
exitPrompt(){
read -p "Хотите продолжить? [y]es или [n]o: " ans
if [ $ans == 'n' ]
then
echo "Выход из сценария. Хорошего дня!"
break
else
continue
fi
}
while(true)
do
clear
printf "Выберите одну из следующих операций: \n"
printf "[a]Добавление\n[b]Вычитание\n[c]Умножение\n[d]Деление\n"
printf "################################\n"
read -p "Ваш выбор: " choice
case $choice in
[aA])
inputs
res=$((int1+int2))
;;
[bB])
inputs
res=$((int1-int2))
;;
[cC])
inputs
res=$((int1*int2))
;;
[dD])
inputs
res=$((int1/int2))
;;
*)
res=0
echo "неправильный выбор!"
esac
echo "Результат: " $res
exitPrompt
done
Мы улучшили наш код, создав подсекции inputs и exitPrompt. Он работает точно так же, как и наш предыдущий код, однако наш текущий код легче отлаживать, потому что он правильно структурирован.
Передача параметров в функции
Как и в большинстве языков программирования, вы можете передавать параметры и обрабатывать эти данные в функциях в bash. Приведенный ниже код показывает процедуру передачи значений в сценариях оболочки:
#!/bin/bash
myfunction(){
echo $1
echo $2
}
myfunction "Привет" "Мир"
Обратите внимание, что в нашем примере мы добавили значения “Привет” и “Мир“ после того, как вызвали myfunction. Эти значения передаются в myfunction как параметры и хранятся в локальной переменной. Однако, в отличие от других языков, интерпретатор сохраняет переданные значения в предопределенные переменные, которые называются в соответствии с последовательностью передачи параметров, 1 как начальное имя до порядка передачи. Обратите внимание, что слово “Привет” хранится в переменной 1, а значение “Мир“ хранится в переменной 2.
Примечание: 1 и 2 в нашем примере являются локальными переменными и, следовательно, недоступны для других частей сценария, кроме функции, в которой передаются параметры.
Например,
#!/bin/bash
myfunction(){
echo $1
echo $2
}
myfunction "Привет" "Мир"
echo $1
echo $2
Команды echo $1 и echo $2 в последних двух строках нашего сценария не отображаются, поскольку интерпретатор не распознает обе переменные, потому что они обе локальны для myfunction.
Возвращение значений из функций
Помимо создания функций и передачи параметров в них, функции bash могут передавать значения локальной переменной функции в основную программу, используя ключевое слово return. Возвращенные значения затем хранятся в переменной по умолчанию $?. Например, рассмотрим следующий код:
#!/bin/bash
add(){
sum=$(($1+$2))
return $sum
}
read -p "Введите целое число: " int1
read -p "Введите целое число: " int2
add $int1 $int2
echo "Результат: " $?
В примере мы передаем параметры int1 и int2 в функцию add. Затем функция add обрабатывает их через строку sum=$(($1+$2)). Затем значение переменной sum передается в основную программу через строку return $sum. По умолчанию значения $sum будут храниться в переменной по умолчанию $?. Наконец, строка echo “Результат: “ $? выводит результат.
Примечание: Сценарии оболочки могут возвращать только одно значение.В отличие от других языков программирования, сценарии оболочки не могут возвращать несколько значений из функции. Давайте посмотрим на этот пример:
#!/bin/bash
add(){
sum=$(($1+$2))
dif=$(($1-$2))
return $sum
}
read -p "Введите целое число: " int1
read -p "Введите целое число: " int2
add $int1 $int2
echo "Результат: " $?
echo "Результат: " $?
Подводя итог
Давайте рассмотрим еще один пример, который использует функции, передает параметры в них и возвращает значение.
#!/bin/bash
#####################
#Автор: HowtoForge #
#####################
clear(){
clear
}
bin(){
bin1=$(echo "obase=2;$1"|bc)
echo $bin1
}
dec(){
dec1=$(echo "ibase=2;$1"|bc)
return $dec1
}
########Основной#########
printf "Выберите одну из следующих операций:\n[1]Преобразование десятичного в двоичное\n"
printf "[2]Преобразование двоичного в десятичное\n"
read -p "Ваш выбор: " op
case $op in
1)
read -p "Введите целое число: " int
bin $int
;;
2)
read -p "Введите двоичное число: " int
dec $int
echo "Десятичный эквивалент $int равен $?"
;;
*)
echo "Неправильный выбор!"
esac

Приведенный пример преобразует заданный ввод как в двоичное, так и в десятичное значение с использованием команд obase и ibase. Строка $(echo “obase=2;$1”|bc) преобразует заданное десятичное значение в двоичную цифру и сохраняет его в переменной bin1. Затем мы отображаем значение $bin1 с помощью команды echo.
Примечание: Лучше использовать echo напрямую при преобразовании из десятичного в двоичное, потому что когда вы возвращаете команду для передачи двоичного значения, bash преобразует двоичное значение в десятичное перед его возвратом.Кроме того, мы преобразовали двоичное значение в десятичное с помощью команды $(echo “ibase=2;$1”|bc).
Вы также должны помнить, что интерпретатор способен принимать только 8-битные двоичные цифры. Если вы введете цифры, превышающие предел 8 бит, это приведет к переполнению, и старший значащий бит цифры будет отброшен.
10-битная двоичная цифра 1000001010 возвращает 10, поскольку следуя правилу 8 бит, оставшиеся 2 бита справа (старший значащий бит) будут опущены, таким образом, 1000001010 станет равным 00001010, что равно 10. Если вы хотите операцию, которая принимает двоичные цифры, превышающие 8 бит, вам нужно создать код вручную.
Заключение
Bash имеет функции, которые очень похожи на языки программирования, чтобы предоставить пользователю множество инструментов и сделать системы Linux более мощными. В этой серии вы улучшили свои знания в сценариях оболочки через функции. Функции в сценариях оболочки обеспечивают модульность для пользователя, упрощая отладку сценариев и позволяя повторное использование кода.
Ссылка:
[1] Американский словарь английского языка, пятое издание. Авторские права © 2011 Houghton Mifflin Harcourt Publishing Company. Издано Houghton Mifflin Harcourt Publishing Company.
Get new posts in your inbox
No spam. Unsubscribe anytime.