bash функции с параметрами

Bash Функции

Bash Functions

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

Определение функций Bash

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

Первый формат начинается с имени функции, за которым следуют скобки. Это предпочтительный и более используемый формат.

Несколько моментов, которые следует отметить:

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

Давайте проанализируем код построчно:

Область действия переменных

Локальные переменные могут быть объявлены в теле функции с local ключевым словом и могут использоваться только внутри этой функции. Вы можете иметь локальные переменные с одинаковыми именами в разных функциях.

Чтобы лучше проиллюстрировать, как работает область видимости переменных в Bash, давайте рассмотрим этот пример:

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

Из приведенного выше вывода можно сделать вывод, что:

Возвращаемые значения

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

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

Вывод

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

Источник

BASH: использование функций, примеры

По сути функция в bash является обычной переменной, но с более широкими возможностями.

Основное применение — в тех случаях, когда один и тот же код необходимо использовать несколько раз и/или в разных связанных скриптах.

Объявление и вызов функции

Объявляется функция так:

И старайтесь никогда не использовать третий вариант:

Вызвать функцию можно просто указав её имя в теле скрипта:

Важно, что бы объявление функции было выполнено до того, как она будет вызвана, иначе будет получена ошибка:

Вызов функции с аргументами

Перейдём к более сложной функции, и рассмотрим вызов функции с аргументами.

Для примера — возьмём функцию, которая вызывается в том месте кода, где необходимо получить ответ от пользователя:

В данном случае, функция answer ожидает ответа от пользователя в стиле Yes или No (или любая вариация, заданная в выражении [yY][eE][sS]|[yY] или [nN][oO]|[nN] ), и в зависимости от ответа выполняет определённое действие.

Или попробуем ответить No:

Вызов команд непосредственно из аргументов, а тем более из переменных, считается не самым хорошим решением, поэтому — давайте перепишем её и вызовем с операторами && (в случае успешного выполнения, то есть при получении кода 0) и || — в случае ошибки и получения кода ответа 1:

Соответственно, вместо echo можно выполнить любую другую команду:

Важно учитывать, что в случае если первая команда завершится неудачно (в данном примере — не найдёт указанный PID ) — то функция вернёт код 1, и будет выполнена вторая часть:

Переменные в функциях

В аргументах так же можно использовать переменные.

Например — можно определить несколько вариантов ответов в разных переменных, и использовать нужную в разных случаях:

Как и с обычными переменными — функции используют «позиционные агрументы», т.е.:

Например — создадим такой скрипт с функцией, которая должна вывести количество переданных аргументов:

Или — просто вывести на экран все переданные ей аргументы:

А можно аргументы передавать прямо при вызове функции, а не при вызове скрипта как в примере выше:

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

Математические операции в функциях

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

К примеру такая функция:

Более сложный вариант — с использованием нескольких переменных и вычислением их значения:

Ещё вариант — с использованием аргументов:

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

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

Такая функция будет бесконечно вызывать сама себя, пока её выполнение не будет прервано вручную:

Экспорт функций

Что бы передать функцию в следующий скрипт, вызываемом в новом (дочернем) экземпляре shell — её необходимо экспортировать.

Для примера возьмём два файла — в файле 1.sh мы объявим функцию, а в файле 2.sh — попробуем её выполнить:

Другой вариант — вызывать следующий скрипт в том же экземпляре шела:

Оба варианта равнозначны и дадут один результат:

Проверка наличия функций

Если задать имена функций в качестве аргументов — declare просто выведет их мена:

Читайте также:  Актив в тик ток это что

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

Запустим скрипт для проверки:

А теперь — попробуем добавить одну «лишнюю» функцию:

declare обнаружил отсутствие функции с именем three и вернул код 1, что вызвало срабатывание оператора ||.

Источник

Bash-функции и их имена, которые могут быть практически всем чем угодно

С Bash связано одно распространённое заблуждение, которое заключается в том, что имена bash-функций должны быть составлены по тем же правилам, что и имена переменных. В руководстве по Bash даже даётся следующее определение термина name (имя):

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

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

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

Вот результаты его работы:

Если в имени функции содержится буква, то набор других символов, которые можно использовать в её имени, меняется. Вот — список допустимых символов, которые могут находиться в имени функции на второй позиции, учитывая то, что первым символом имени является буква a :

Имена функций, кстати, совершенно не ограничены ASCII-символами. Вот, например, функция, именем которой является смайлик:

Переопределение встроенных команд

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

Правда, я сразу же должен попросить вас так не поступать. Вызов этой функции приведёт к бесконечной рекурсии, которая завершится «убийством» процесса. Но если удалось успешно переопределить встроенную команду — её исходный вариант можно вызвать с помощью команды command. В результате следующая конструкция оказывается вполне работоспособной:

Какая от этого польза?

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

Вот, например, функция из jp, выводящая сведения об ошибках:

Можно ли счесть это удачным ходом? Если код рассчитан исключительно на Bash, то — да. Но такой код не отличается переносимостью (взгляните на стандарт POSIX). В частности — он не запустится в ash. Это — плохая новость для того, кто планирует запускать его в Docker-контейнерах, основанных на Busybox.

В Bash имеется полезный POSIX-режим. Его можно применять для запуска кода, в переносимости которого есть сомнения. Работа в этом режиме, кроме того, запрещает пользовательскому коду переопределение встроенных команд, определённых в POSIX.

Приходилось ли вам пользоваться Bash-функциями с необычными именами?

Источник

Функции Bash

Декларация функции Bash

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

Несколько моментов, которые следует отметить:

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

Давайте проанализируем код построчно:

Область переменных

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

Локальные переменные могут быть объявлены в теле функции с ключевым словом local и могут использоваться только внутри этой функции. Вы можете иметь локальные переменные с одинаковыми именами в разных функциях.

Чтобы лучше проиллюстрировать, как работает область видимости переменных в Bash, давайте рассмотрим пример:

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

Из приведенного выше вывода можно сделать вывод, что:

Возвращаемые значения

В отличие от функций в «реальных» языках программирования, функции Bash не позволяют вам возвращать значение при вызове. Когда функция bash завершает свою работу, ее возвращаемое значение является состоянием последнего оператора, выполненного в функции, 0 для успеха и ненулевого десятичного числа в диапазоне 1 – 255 для отказа.

Читайте также:  Visa classic paywave что это

Чтобы фактически вернуть произвольное значение из функции, нам нужно использовать другие методы. Самый простой вариант – присвоить результат функции глобальной переменной:

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

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

Заключение

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

Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии.

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

Источник

Bash-скрипты, часть 6: функции и разработка библиотек

Занимаясь разработкой bash-скриптов, вы рано или поздно столкнётесь с тем, что вам периодически приходится использовать одни и те же фрагменты кода. Постоянно набирать их вручную скучно, а копирование и вставка — не наш метод. Как быть? Хорошо бы найти средство, которое позволяет один раз написать блок кода и, когда он понадобится снова, просто сослаться на него в скрипте.

Оболочка bash предоставляет такую возможность, позволяя создавать функции. Функции bash — это именованные блоки кода, которые можно повторно использовать в скриптах.

Объявление функций

Функцию можно объявить так:

Функцию можно вызвать без аргументов и с аргументами.

Использование функций

Напишем скрипт, содержащий объявление функции и использующий её:

Результаты вызова функции

Функцию можно вызывать столько раз, сколько нужно. Обратите внимание на то, что попытавшись использовать функцию до её объявления, вы столкнётесь с ошибкой. Напишем демонстрирующий это скрипт:

Как и ожидается, ничего хорошего после его запуска не произошло.

Попытка воспользоваться функцией до её объявления

Придумывая имена для функций, учитывайте то, что они должны быть уникальными, иначе проблем не избежать. Если вы переопределите ранее объявленную функцию, новая функция будет вызываться вместо старой без каких-либо уведомлений или сообщений об ошибках. Продемонстрируем это на примере:

Как видно, новая функция преспокойно затёрла старую.

Использование команды return

Команда return позволяет задавать возвращаемый функцией целочисленный код завершения. Есть два способа работы с тем, что является результатом вызова функции. Вот первый:

Команда echo вывела сумму введённого числа и числа 10.

Вывод значения, возвращаемого функцией

Учтите, что максимальное число, которое может вернуть команда return — 255. Если функция должна возвращать большее число или строку, понадобится другой подход.

Запись вывода функции в переменную

Ещё один способ возврата результатов работы функции заключается в записи данных, выводимых функцией, в переменную. Такой подход позволяет обойти ограничения команды return и возвращать из функции любые данные. Рассмотрим пример:

Вот что получится после вызова данного скрипта.

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

Аргументы функций

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

Аргументы передают функции, записывая их после её имени:

Вот пример, в котором функция вызывается с аргументами и занимается их обработкой:

Вызов функции с аргументами

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

При его запуске, а точнее, при вызове объявленной в нём функции, будет выведено сообщение об ошибке.

Функция не может напрямую использовать параметры, переданные сценарию

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

Теперь всё работает правильно.

Передача функции параметров, с которыми запущен скрипт

Работа с переменными в функциях

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

Читайте также:  Что у нас в лесу на букву ш

Существуют два вида переменных:

▍Глобальные переменные

Глобальные переменные — это переменные, которые видны из любого места bash-скрипта. Если вы объявили глобальную переменную в основном коде скрипта, к такой переменной можно обратиться из функции.

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

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

Вот что выведет этот сценарий.

Обращение к глобальной переменной из функции

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

Что если такое поведение нас не устраивает? Ответ прост — надо использовать локальные переменные.

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

Переменные, которые объявляют и используют внутри функции, могут быть объявлены локальными. Для того, чтобы это сделать, используется ключевое слово local перед именем переменной:

Если за пределами функции есть переменная с таким же именем, это на неё не повлияет. Ключевое слово local позволяет отделить переменные, используемые внутри функции, от остальных переменных. Рассмотрим пример:

Локальная переменная в функции

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

Попробуем передать функции в качестве аргумента массив. Сразу хочется сказать, что работать такая конструкция будет неправильно:

Неправильный подход к передаче функциям массивов

Как видно из примера, при передаче функции массива, она получит доступ лишь к его первому элементу.

Для того, чтобы эту проблему решить, из массива надо извлечь имеющиеся в нём данные и передать их функции как самостоятельные аргументы. Если надо, внутри функции полученные ей аргументы можно снова собрать в массив:

Сборка массива внутри функции

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

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

Рекурсия — это когда функция сама себя вызывает. Классический пример рекурсии — функция для вычисления факториала. Факториал числа — это произведение всех натуральных чисел от 1 до этого числа. Например, факториал 5 можно найти так:

Если формулу вычисления факториала написать в рекурсивном виде, получится следующее:

Этой формулой можно воспользоваться для того, чтобы написать рекурсивную функцию:

Проверим, верно ли работает этот скрипт.

Как видите, всё работает как надо.

Создание и использование библиотек

Итак, теперь вы знаете, как писать функции и как вызывать их в том же скрипте, где они объявлены. Что если надо использовать функцию, тот блок кода, который она собой представляет, в другом скрипте, не используя копирование и вставку?

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

У команды source есть псевдоним — оператор «точка». Для того, чтобы подключить файл в скрипте, в скрипт надо добавить конструкцию такого вида:

Это — библиотека. Воспользуемся ей в сценарии:

Только что мы использовали библиотечную функцию внутри скрипта. Всё это замечательно, но что если мы хотим вызвать функцию, объявленную в библиотеке, из командной строки?

Вызов bash-функций из командной строки

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

Вызов функции из командной строки

Ещё приятнее то, что такая вот библиотека оказывается доступной всем дочерним процессам оболочки, то есть — ей можно пользоваться в bash-скриптах, не заботясь о подключении к ним этой библиотеки.

Тут стоит отметить, что для того, чтобы вышеприведённый пример заработал, может понадобиться выйти из системы, а потом войти снова. Кроме того, обратите внимание на то, что если имя функции из библиотеки совпадёт с именем какой-нибудь стандартной команды, вместо этой команды будет вызываться функция. Поэтому внимательно относитесь к именам функций.

Итоги

На сегодня это всё. В следующий раз поговорим об утилите sed — мощном средстве обработки строк.

Уважаемые читатели! А вы пользуетесь функциями собственной разработки для решения повседневных задач?

Источник

Образовательный портал