[о слонах] ...и луконских волов, змееруких и видом ужасных (Лукреций).

5 мин для чтенияBash для начинающих. Использование функций в Bash

FavoriteLoadingДобавить в избранное
1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (1 оценок, среднее: 5,00 из 5)
Загрузка...
28 августа 2020
Bash Heredoc
Когда ваши сценарии bash становятся все больше и больше, все может стать очень запутанным!

Вы можете снова и снова переписывать одни и те же фрагменты кода в разных частях ваших сценариев bash.

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

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

Кроме того, вы узнаете, как работают области видимости переменных и как определять рекурсивные функции.

 

Создание функций в bash

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

function_name () {
commands
}

 

Вторая менее часто используемая функция создания bash-функций начинается с зарезервированной рабочей функции, за которой следует имя функции, как показано ниже:

function function_name {
commands
}

 

Теперь есть пара вещей, о которых вы должны знать при работе с функциями:

  • Функция никогда не будет запускаться/выполняться, если вы не вызовете функцию.
  • Определение функции должно предшествовать любым вызовам функции.

Каждый раз, когда вы хотите, чтобы функция запускалась, вам просто нужно ее вызвать! Для вызова функции достаточно просто указать имя функции.

Взгляните на следующий сценарий bash fun.sh :

#!/bin/bash

hello () {
echo "Hello World"
}

hello
hello
hello

 

Мы определили функцию с именем hello, которая просто выводит на терминал строку «Hello World». Обратите внимание, что мы сделали три вызова функции hello, и поэтому, если вы запустите сценарий, вы увидите, что на экране трижды напечатана строка «Hello World»:

destroyer@andreyex:~$ ./fun.sh
Hello World
Hello World
Hello World

 

Возврат значений функции в bash

Во многих языках программирования функции возвращают значение при вызове; однако это не относится к bash, поскольку функции bash не возвращают значения.

Когда функция bash завершает выполнение, она возвращает статус выхода последней выполненной команды, записанный в $? переменная. Ноль указывает на успешное выполнение или ненулевое положительное целое число (1-255) указывает на сбой.

Вы можете использовать оператор return, чтобы изменить статус выхода функции. Например, взгляните на следующий сценарий error.sh:

#! /bin/bash

error () {
blabla
return 0
}

error
echo "Состояние возвращаемого значения ошибки функции: $?"

 

Если вы запустите bash-скрипт error.sh , вы можете быть удивлены результатом:

destroyer@andreyex:~$ ./error.sh
./error.sh: line 4: blabla: command not found
Состояние возвращаемого значения ошибки функции: 0

 

Читать  Понимание Crontab в Linux с примерами

Без оператора return 0 функция ошибки никогда бы не вернула ненулевой статус выхода, поскольку blabla приводит к ошибке команда не найдена .

Итак, как видите, хотя функции bash не возвращают значения, мы нашли обходной путь, изменив статусы выхода из функций.

Вы также должны знать, что оператор return немедленно завершает функцию.

 

Передача аргументов в функцию bash

Вы можете передавать аргументы функции так же, как вы можете передавать аргументы сценарию bash. Вы просто включаете аргументы при вызове функции.

Для демонстрации давайте взглянем на следующий сценарий bash iseven.sh :

#!/bin/bash

iseven () {
if [ $(($1 % 2)) -eq 0 ]; then
echo "$1 is even."
else
echo "$1 is odd."
fi
}

iseven 3
iseven 4
iseven 20
iseven 111

 

Функция iseven () проверяет, является ли число четным или нечетным. Мы сделали четыре вызова функций для iseven(). Для каждого вызова функции предоставили одно число, которое является первым дополнением к функции iseven() и на которое ссылается переменная $ 1 в определении функции.

Давайте запустим bash-скрипт iseven.sh, чтобы убедиться, что он работает:

destroyer@andreyex:~$ ./iseven.sh
3 is odd.
4 is even.
20 is even.
111 is odd.

 

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

#!/bin/bash

fun () {
echo "$1 is the first argument to fun()"
echo "$2 is the second argument to fun()"
}

echo "$1 это первый аргумент к сценарию."
echo "$2 это второй аргумент к сценарию."

fun Yes 7

 

Запустите скрипт с парой аргументов и посмотрите на результат:

destroyer@andreyex:~$ ./funarg.sh Cool Stuff
Cool это первый аргумент к сценарию.
Stuff это второй аргумент к сценарию.
Yes is the first argument to fun()7 is the second argument to fun()

 

Как видите, даже если вы использовали одни и те же переменные $ 1 и $ 2 для ссылки как на аргументы скрипта, так и на аргументы функции, они дают разные результаты при вызове из функции.

 

Локальные и глобальные переменные в функциях bash

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

Чтобы продемонстрировать это, взгляните на следующий сценарий bash scope.sh :

#!/bin/bash

v1='A'
v2='B'

myfun() {
local v1='C'
v2='D'
echo "Inside myfun(): v1: $v1, v2: $v2"
}

echo "Before calling myfun(): v1: $v1, v2: $v2"
myfun
echo "After calling myfun(): v1: $v1, v2: $v2"

 

Читать  Как включить SSH в Ubuntu 20.04

Сначала мы определили две глобальные переменные v1 и v2 . Затем внутри определения myfun() мы использовали ключевое слово local для определения локальной переменной v1 и изменил глобальную переменную v2. Обратите внимание, что вы можете использовать одно и то же имя переменной для локальных переменных в разных функциях.

Теперь запустим скрипт:

destroyer@andreyex:~$ ./scope.sh
Before calling myfun(): v1: A, v2: B
Inside myfun(): v1: C, v2: D
After calling myfun(): v1: A, v2: D

 

Из вывода скрипта можно сделать следующие выводы:

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

 

Рекурсивные функции

Рекурсивная функция – это функция, которая вызывает сама себя! Рекурсивные функции пригодятся, когда вы пытаетесь решить проблему программирования, которую можно разбить на более мелкие подзадачи.

Факторный функция является классическим примером рекурсивной функции. Взгляните на следующий сценарий bash factorial.sh:

#!/bin/bash

factorial () {
if [ $1 -le 1 ]; then
echo 1
else
last=$(factorial $(( $1 -1)))
echo $(( $1 * last ))
fi
}

echo -n "4! is: "
factorial 4
echo -n "5! is: "
factorial 5
echo -n "6! is: "
factorial 6

 

Любая рекурсивная функция должна начинаться с базового случая, который обязательно должен завершать цепочку рекурсивных вызовов функций. В функции factorial() базовый случай определяется следующим образом:

if [ $1 -le 1 ]; then
echo 1

 

Теперь выведите рекурсивный случай для факториальной функции. Чтобы вычислить факториал числа n, где n – положительное число больше единицы, вы можете умножить n на факториал n-1 :

factorial(n) = n * factorial(n-1)

 

Давайте воспользуемся приведенным выше уравнением, чтобы записать этот рекурсивный случай:

last=$(factorial $(( $1 -1)))
echo $(( $1 * last ))

 

Теперь запустите скрипт и убедитесь, что получили правильные результаты:

destroyer@andreyex:~$ ./factorial.sh
4! is: 24
5! is: 120
6! is: 720

 

В качестве дополнительного упражнения попробуйте написать рекурсивную функцию для вычисления n-го числа Фибоначчи. Сначала попробуйте придумать базовый случай, а затем рекурсивный.

Потрясающие! Надеюсь, вам понравилось создавать функции в bash!

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Читайте также

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам:

Заполните форму и наш менеджер перезвонит Вам в самое ближайшее время!

badge
Обратный звонок 1
Отправить
galka

Спасибо! Ваша заявка принята

close
galka

Спасибо! Ваша заявка принята

close