Funkce dělají skriptování mnohem jednodušší a překlednější. Rozdělují totiž program do jednodušších menších kousků. Funkce provádí vámi definované příkazy a také může vracet hodnotu. Funkce můžete volat z hlavního programu. Doteď jsme totiž psali všechno do hlavního programu. Funkce umožňují dílčí úkoly rozložit do menších částí kódu, které lze volat v programu, a to i vícekrát. Před pokračováním si uvedeme příklad funkce, která pouze vypíše text:
#!/bin/bash
hello()
{
echo "Nyní jsme ve funkci hello()"
}
echo "Nyní se zavolá funkce hello()..."
hello
echo "Nyní jsme zase mimo funkci hello()"
Nyní se na funkci podíváme blíže. Funkce zde v našem konkrétním případě plní účel vypsání textu, který nás pouze informuje o tom, že je funkce prováděna. Funkce samozřejmě může dělat mnohem komplikovanější úlohy, ale právě zde jen vytiskne text. Funkci vždy voláme napsáním jejího jména do programu, jejíž jméno může být libovolné. V našem programu se jmenuje hello, a volá se:
hello
Když je tento řádek vykonáván, bash
prohledá skript, zdali je v něm funkce hello(). Nalezne-li jí, tak provede příkazy, které jsou v ní zapsány.
Samotná funkce je určena svým názvem po kterém následuje dvojice kulatých závorek (). Blok příkazů ve funkci je uzavřen složenými závorkami {...}. Ty značí začátek a konec funkce. Veškerý kód funkce bude vykonán pouze, bude-li funkce zavolána. Funkce by také měla být vždy definována ještě před tím, než bude zavolána. Je též přípustné, že před názvem funkce může být slovo function. Funkce tedy vypadá takto:
hello()
{
echo "Nyní jsme ve funkci hello()"
}
Nebo další možný zápis je:
function hello()
{
echo "Nyní jsme ve funkci hello()"
}
Jak to tedy funguje?
Skript se začne normálně provádět od začátku, jak jsme zvyklí, takže nic nového. Když ale narazí na konstrukci [ 'function' ] hello (), ví, že se jedná o definici funkce jménem hello. Zapamatuje si, že hello odkazuje na funkci a pokračuje v provádění příkazů po odpovídající složené závorce. Jakmile narazí na řádek foo, vi, že má provést dříve definovanou funkci. Po skončení funkce se pokračuje na řádku, který následuje po volání funkce foo.
Dříve než funkci vyvoláte, ji vždy musíte nejprve definovat, podobně jako v jazyce Pascal, jen s tou výjimkou, že v shellu neexistuje žádná deklarace forward. To ale nebývá problém, protože se všechny skripty provádějí od začátku, takže pokud umístíte všechny funkce před první volání libovolné funkce, budou vždy všechny funkce před prvním volání definovány.
Při volání funkce jsou poziční parametry skriptu $*, $@, $#, $1, $2 atd. nahrazeny parametry funkce. Pomocí nich pak čtete parametry předané funkci. Po skončení funkce jsou hodnoty všech parametrů zase obnoveny. Tyto parametry se používají stejně jako proměnné.
Funkce mohou pomocí příkazu return
vracet číselnou hodnotu. Pokud je potřeba vrátit řetězec, uloží se do proměnné, kterou lze po skončení funkce použít. Případně můžete řetězec vypsat příkazem echo a výsledek odchytit jako v následujícím příkladu:
#!/bin/bash
foo()
{
echo Ahoj
}
...
result="$(hello)"
Uvnitř shellu můžete za pomoci klíčového slova local
deklarovat lokální proměnné. Proměnná pak existuje jen v rámci dané funkce. Jinak může funkce přistupovat k jiným proměnným shellu, které jsou v podstatě globální. Pokud má lokální proměnná stejný název jako globální, pak tuto proměnnou potlačí, ale jen v rámci příslušné funkce. Abychom si to demonstrovali, ukážeme si následující příklad:
#!/bin/bash
vzorový_text="globální proměnná"
foo()
{
local vzorový_text="lokální proměnná"
echo "Provádí se funkce foo"
echo $vzorový_text
}
echo "Začátek skriptu"
echo $vzorový_text
foo
echo "Konec skriptu"
echo $vzorový_text
exit 0
Pokud funkce neobsahuje příkaz return
, vrací návratový kód posledního provedeného příkazu.
V následujícím příkladu si ukážeme způsob předávání parametrů funkci a také způsob jakým mohou funkce vracet hodnoty true
a false
.
#!/bin/bash
yes_or_no() {
echo "Je tvé jméno $* ?"
while true
do
echo -n "Napiš ano nebo ne: "
read x
case "$x" in
a | ano ) return 0;;
n | ne ) return 1;;
* ) echo "Napiš ano nebo ne"
esac
done
}
echo "Původní parametr je $*"
if yes_or_no "$1"
then
echo "Ahoj $1, pěkné jméno"
else
echo "Nikdy"
fi
exit 0
Tento příklad funguje tak, že po spuštění skriptu je definována funkce yes_or_no
, ale není provedena. V příkazu if
provede skript funkci yes_or_no
, které předá jako parametry zbytek řádku, kde zápis $1 nahradí prvním parametrem skriptu. Funkce pak pracuje s těmito parametry, které jsou nyní uloženy v pozičních proměnných $1, $2 atd. a vrátí hodnotu volajícímu příkazu. Příkaz if
v závislosti na návratové hodnotě provede příslušní příkaz.