Подобно "настоящим" языкам программирования, Bash тоже имеет функции, хотя и в несколько ограниченном варианте. Функция -- это подпрограмма, блок кода который реализует набор операций, своего рода "черный ящик", предназначенный для выполнения конкретной задачи. Функции могут использоваться везде, где имеются участки повторяющегося кода.
functionfunction_name {
command...
}
function_name () {
command...
}
Вторая форма записи ближе к сердцу C-программистам (она же более переносимая).
Как и в языке C, скобка, открывающая тело функции, может помещаться на следующей строке.
function_name ()
{
command...
}
Вызов функции осуществляется простым указанием ее имени в тексте сценария.
#!/bin/bash JUST_A_SECOND=1 funky () { # Это пример простейшей функции, которая выводит сообщение. echo "Это функция funky." } # Объявление функции должно предшествовать ее вызову. fun () { # Более сложная функция. i=0 REPEATS=30 echo echo "Теперь запускается функция fun." echo sleep $JUST_A_SECOND # Эй! Погодите секундочку! while [ $i -lt $REPEATS ] do echo "------------------РАБОТА------------------->" echo "---------------С ФУНКЦИЯМИ----------------" echo "------------ОЧЕНЬ УВЛЕКАТЕЛЬНА------------>" echo let "i+=1" done } # А теперь собственно вызов функций. funky fun exit 0
Функция должна быть объявлена раньше, чем ее можно будет использовать. К сожалению, в Bash нет возможности "опережающего объявления" функции, как например в C.
f1 # Эта строка вызовет сообщение об ошибке, поскольку функция "f1" еще не определена. declare -f f1 # Это не поможет. f1 # По прежнему -- сообщение об ошибке. # Однако... f1 () { echo "Вызов функции \"f2\" из функции \"f1\"." f2 } f2 () { echo "Функция \"f2\"." } f1 # Функция "f2", фактически, не вызывается выше этой строки, #+ хотя ссылка на нее встречается выше, до ее объявления. # Это допускается. # Спасибо S.C.
Допускается даже создание вложенных функций, хотя пользы от этого немного.
f1 () { f2 () # вложенная { echo "Функция \"f2\", вложенная в \"f1\"." } } f2 # Вызывает сообщение об ошибке. # Даже "declare -f f2" не поможет. echo f1 # Ничего не происходит, простой вызов "f1", не означает автоматический вызов "f2". f2 # Теперь все нормально, вызов "f2" не приводит к появлению ошибки, #+ поскольку функция "f2" была определена в процессе вызова "f1". # Спасибо S.C.
Объявление функции может размещаться в самых неожиданных местах.
ls -l | foo() { echo "foo"; } # Допустимо, но бесполезно. if [ "$USER" = bozo ] then bozo_greet () # Объявление функции размещено в условном операторе. { echo "Привет, Bozo!" } fi bozo_greet # Работает только у пользователя bozo, другие получат сообщение об ошибке. # Нечто подобное можно использовать с определенной пользой для себя. NO_EXIT=1 # Will enable function definition below. [[ $NO_EXIT -eq 1 ]] && exit() { true; } # Определение функции в последовательности "И-список". # Если $NO_EXIT равна 1, то объявляется "exit ()". # Тем самым, функция "exit" подменяет встроенную команду "exit". exit # Вызывается функция "exit ()", а не встроенная команда "exit". # Спасибо S.C.