Как объявить функцию в Bash
Имеется два способа объявления функций в Bash:
function ИМЯ_ФУНКЦИИ { КОМАНДЫ... }
Второй вариант:
ИМЯ_ФУНКЦИИ () { КОМАНДЫ... }
Обратите внимание, что при использовании ключевого слова function после имени функции не используются круглые скобки, а без ключевого слова function круглые скобки используются после имени функции.
На самом деле, чтобы объявление функции было больше похоже на другие языки программирования, с ключевым словом function также можно использовать круглые скобки. То есть следующая нотация является корректной:
function ИМЯ_ФУНКЦИИ () { КОМАНДЫ... }
Версия с ключевым словом function является расширением, а другие формы работают во всех совместимых с POSIX оболочках. То есть используя синтаксис с ключевым словом function вы уменьшаете совместимость вашего скрипта.
Как вызвать функцию в Bash
Вызов функций в Bash больше похож на вызов команд оболочки, чем на вызов функций в других языках, с которыми вы можете быть знакомы (C/C++/Java/PHP/Python/Perl …). При вызове функции НЕ нужно указывать скобки, пример кода:
#!/bin/bash # Объявление функции talk function talk() { echo "hi!" } # Вызов функции talk talk
Если вы сохранили функцию в файл, но хотите вызвать её позже (то есть в файле функция не вызывается), то чтобы вызвать эту функцию нужно использовать команду source.
Допустим, эта функция сохранена в файл say.sh:
#!/bin/bash function talk() { echo "hi!" }
Для вызова функции talk нужно выполнить:
source say.sh; talk
Для вызова функции из другого скрипта bash:
#!/bin/bash source say.sh talk
Если вы хотите, чтобы функция всегда была доступна для вызова, то можно создать файл functions.sh (например, в директории ~/bin). В этом скрипте вы добавите ваши собственные объявления функций. Наконец, вам нужно просто добавить строку
source ~/bin/functions.sh
в ваш файл .bashrc. Таким образом вы сможете вызывать функцию в командной строке в любое время. Конечно, можно сразу прописать функции .bashrc, но это может загромоздить этот файл и сделать его плохо читаемым. Поэтому рекомендуется выносить функции во внешние файлы.
При любом использовании достаточно выполнить команду source только один раз, после этого вызывать функцию можно любое количество раз.
Ещё одно правило — функции можно вызывать после их объявления.
#!/usr/bin/env sh foo 1 # это завершится неудачей, поскольку функция foo ещё не объявлена. foo() { echo "Параметр #1 это $1" } foo 2 # это будет работать.
Как передать аргументы в функцию в Bash
Как мы уже выяснили, вызов функций в Bash больше похож на вызов команд оболочки, а не на вызов функций в привычном нам виде. Это справедливо и для передачи аргументов — их не нужно помещать в круглые скобки, их достаточно просто перечислить через пробел. Примерно как вы бы передали опции команде оболочки (например, ls -l). По сути, аргументы функции в bash обрабатываются как позиционные параметры ($1, $2..$9, ${10}, ${11}, и так далее).
Допустим, функция объявлена следующим образом:
function ИМЯ_ФУНКЦИИ { КОМАНДЫ... }
Или так:
function_name () { ИМЯ_ФУНКЦИИ... }
Для вызова функции с аргументами:
ИМЯ_ФУНКЦИИ "$arg1" "$arg2"
Функция ссылается на переданные аргументы по их позиции (не по имени), то есть $1, $2 и так далее. $0 - это имя самого скрипта.
Пример:
function_name () { echo "Параметр #1 это $1" }
Обратите внимание, что внутри функции вместо $* (означает все аргументы) нужно использовать $@. То есть обрабатывать аргументы можно примерно так.
function callingSomeFunction () { for value in "$@" # Используйте здесь "$@", а не "$*" !!!!! do : done }
Помните об области видимости переменных в функции! $1 за пределами функции и $1 внутри функции — это совершенно разные вещи! За пределами функциями $1 — это первый аргумент, переданный всему скрипту. А внутри функции $1 — это первый аргумент, переданный функции!
Можно использовать имена для переменных:
declare filename=$1 # declare даёт вам больше опций и ограничивает область видимости переменных
Как передать массив в качестве аргумента в функцию в Bash:
callingSomeFunction "${someArray[@]}" # Расширяется на все элементы массива.
Нужно передать величину и массив, но ещё и использовать "$@" внутри функции? Тогда так:
function linearSearch () { declare myVar="$1" shift 1 # удаляет $1 из списка параметров for value in "$@" # представляет оставшиеся параметры. do if [[ $value == $myVar ]] then echo -e "Found it!\t... after a while." return 0 fi done return 1 } linearSearch $someStringValue "${someArray[@]}"
Связанные статьи:
- В чем разница между командами source и export (РЕШЕНО) (84%)
- Как создавать диалоговые блоки в интерактивных shell скриптах (52.1%)
- Как в Bash реализовать «Нажмите любую кнопку для продолжения» (52.1%)
- Как в Bash проверить, содержит ли строка подстроку (52.1%)
- Что такое башизм (bashisms) (52.1%)
- Различия между Login shell и Non login shell (оболочка с входом и оболочка без входа) (RANDOM - 16%)