Поиск…
Синтаксис
Определите функцию с ключевым словом
function:function f {}
Определить функцию с
():f(){}
Определите функцию с ключевым словом
functionи():function f(){}
Простая функция
helloWorld.sh
#!/bin/bash
# Define a function greet
greet ()
{
echo "Hello World!"
}
# Call the function greet
greet
При запуске скрипта мы видим наше сообщение
$ bash helloWorld.sh
Hello World!
Обратите внимание, что поиск файла с функциями делает их доступными в текущем сеансе bash.
$ source helloWorld.sh # or, more portably, ". helloWorld.sh"
$ greet
Hello World!
Вы можете export функцию в некоторые оболочки, чтобы она подвергалась дочерним процессам.
bash -c 'greet' # fails
export -f greet # export function; note -f
bash -c 'greet' # success
Функции с аргументами
В helloJohn.sh :
#!/bin/bash
greet() {
local name="$1"
echo "Hello, $name"
}
greet "John Doe"
# running above script
$ bash helloJohn.sh
Hello, John Doe
Если вы каким-либо образом не изменяете аргумент, нет необходимости копировать его в
localпеременную - простоecho "Hello, $1".Вы можете использовать
$1,$2,$3и т. Д., Чтобы получить доступ к аргументам внутри функции.Примечание: для аргументов более 9
$10не будет работать (bash будет читать его как $ 1 0), вам нужно сделать${10},${11}и так далее.$@ссылается на все аргументы функции:#!/bin/bash foo() { echo "$@" } foo 1 2 3 # output => 1 2 3Примечание. Вы всегда должны использовать двойные кавычки вокруг
"$@", как здесь.Опускание кавычек заставит оболочку расширять подстановочные знаки (даже если пользователь специально ссылался на них, чтобы избежать этого) и вообще вводит нежелательное поведение и потенциально даже проблемы с безопасностью.
foo "string with spaces;" '$HOME' "*" # output => string with spaces; $HOME *для аргументов по умолчанию используйте
${1:-default_val}. Например:#!/bin/bash foo() { local val=${1:-25} echo "$val" } foo # output => 25 foo 30 # output => 30для запроса аргумента используйте сообщение
${var:?error message}foo() { local val=${1:?Must provide an argument} echo "$val" }
Возвращаемое значение из функции
Оператор return в Bash не возвращает значение, подобное C-функциям, вместо этого он выходит из функции с возвратом. Вы можете думать о нем как о статусе выхода этой функции.
Если вы хотите вернуть значение из функции, отправьте значение в stdout следующим образом:
fun() {
local var="Sample value to be returned"
echo "$var"
#printf "%s\n" "$var"
}
Теперь, если вы это сделаете:
var="$(fun)"
выход fun будет храниться в $var .
Обработка флагов и дополнительных параметров
Встроенные функции getopts могут использоваться внутри функций для записи функций, которые содержат флаги и необязательные параметры. Это не представляет особых трудностей, но нужно должным образом обрабатывать ценности, затронутые getopts . В качестве примера мы определяем функцию сбоя, которая записывает сообщение на stderr и выходит с кодом 1 или произвольным кодом, поставляемым как параметр опции -x :
# failwith [-x STATUS] PRINTF-LIKE-ARGV
# Fail with the given diagnostic message
#
# The -x flag can be used to convey a custom exit status, instead of
# the value 1. A newline is automatically added to the output.
failwith()
{
local OPTIND OPTION OPTARG status
status=1
OPTIND=1
while getopts 'x:' OPTION; do
case ${OPTION} in
x) status="${OPTARG}";;
*) 1>&2 printf 'failwith: %s: Unsupported option.\n' "${OPTION}";;
esac
done
shift $(( OPTIND - 1 ))
{
printf 'Failure: '
printf "$@"
printf '\n'
} 1>&2
exit "${status}"
}
Эту функцию можно использовать следующим образом:
failwith '%s: File not found.' "${filename}"
failwith -x 70 'General internal error.'
и так далее.
Обратите внимание, что как и для printf , переменные не должны использоваться в качестве первого аргумента. Если сообщение для печати состоит из содержимого переменной, следует использовать спецификатор %s для его печати, например, в
failwith '%s' "${message}"
Код выхода функции - это код выхода последней команды
Рассмотрим эту примерную функцию, чтобы проверить, находится ли хост:
is_alive() {
ping -c1 "$1" &> /dev/null
}
Эта функция отправляет одиночный пинг на хост, указанный первым параметром функции. Выходной сигнал и вывод ошибки ping оба перенаправлены на /dev/null , поэтому функция никогда ничего не выводит. Но команда ping будет иметь код выхода 0 при успешном завершении и не равна нулю при сбое. Поскольку это последняя (и в этом примере единственная) команда функции, код выхода ping будет повторно использован для кода выхода самой функции.
Этот факт очень полезен в условных утверждениях.
Например, если хост graucho встал, то подключитесь к нему с помощью ssh :
if is_alive graucho; then
ssh graucho
fi
Другой пример: многократно проверяйте, пока хост graucho не встал, а затем подключитесь к нему с помощью ssh :
while ! is_alive graucho; do
sleep 5
done
ssh graucho
Распечатайте определение функции
getfunc() {
declare -f "$@"
}
function func(){
echo "I am a sample function"
}
funcd="$(getfunc func)"
getfunc func # or echo "$funcd"
Выход:
func ()
{
echo "I am a sample function"
}
Функция, которая принимает именованные параметры
foo() {
while [[ "$#" -gt 0 ]]
do
case $1 in
-f|--follow)
local FOLLOW="following"
;;
-t|--tail)
local TAIL="tail=$2"
;;
esac
shift
done
echo "FOLLOW: $FOLLOW"
echo "TAIL: $TAIL"
}
Пример использования:
foo -f
foo -t 10
foo -f --tail 10
foo --follow --tail 10