Ve skriptování shellu Bash jsou funkce způsoby, jak seskupit sadu instrukcí dohromady, abyste získali konkrétní výsledek. Funkce si můžete představit jako mini skript. Funkce se v některých programovacích jazycích také nazývají procedury a metody. Funkce jsou skvělým způsobem, jak dosáhnout modularity a opětovné použitelnosti.
V tomto článku vysvětlím, jak používat funkce v bash skriptech v Linuxu na příkladech. Na konci tohoto článku budete s používáním bash funkcí docela pohodlně.
Jak definovat funkce v Bash
Při práci s funkcemi musíte pochopit dvě důležité věci.
- Definování funkce,
- Volání funkce.
Podobně jako když vytváříte bash skripty a spouštíte je, měli byste definovat funkci a zavolat ji, aby se funkce spustila.
Existují dva syntaktické způsoby, jak definovat funkci v bash. Prvním způsobem je použití vestavěného klíčového slova bash "function"
následovaný názvem funkce. Blok kódu bude zapsán uvnitř složených závorek {}
.
function [name] {
Block of code
}
Druhým způsobem je vytvoření funkce bez klíčového slova "function"
. Začněte názvem funkce následovaným závorkami.
[name](){
Block of Code
}
Kterou si vybrat? No, vždy je to osobní volba. Volba jednoho před druhým nemá žádné nevýhody.
Můžete také psát jednořádkové funkce, které se nazývají kompaktní funkce . V kompaktních funkcích je každý řádek kódu uvnitř složených závorek oddělen středníkem (;
) .
Spusťte svůj terminál a napište část víceřádkové funkce. Nyní stiskněte klávesu se šipkou nahoru a uvidíte, že vše, co jste napsali ve více řádcích, bude převedeno na kompaktní funkce.
[name](){ first_line; second_line; }
NEJLEPŠÍ POSTUP:
- Zkuste si vybrat libovolnou syntaxi a buďte s ní v souladu.
- Pokud pracujete v prostředí pro spolupráci, je důležité, aby všichni dodržovali stejný standard při kódování.
Konvence pojmenování
Když vytváříte funkci, musíte ji pojmenovat. Název funkce by měl být popisný a snažte se vyhnout názvům, které již používají jiné funkce, proměnné, konstanty atd. "Snake Case" je preferovaný způsob pojmenování funkce. V případě hada jsou slova oddělena podtržítky.
Podívejte se na níže uvedený příklad. Vytvořil jsem funkci s názvem "hello_world"
ve stylu hadího pouzdra, které jednoduše vytiskne ahoj světe na stdout (Terminál).
hello_world() { echo "Running Simple Hello World Function" } hello_world
Jak volat funkci v Bash
Vytvořme jednoduchou funkci čištění s názvem "log_cleanup"
. Účelem této funkce je odstranit ".log"
soubory, které jsou starší než 30 dní.
log_cleanup(){ echo "Running Cleanup On Older Logs - 30 days" find /home/karthick/Documents/Projects/logs/ -name "*.log" -type f -mtime +30 -delete echo "Cleanup Completed" }
Funkce je definována, ale bude to stačit, aby funkce dělala svou práci? Rozhodně ne. Aby byla funkce provedena, musíte funkci zavolat.
Chcete-li funkci zavolat, jednoduše zadejte název funkce za definici funkce:
#!/usr/bin/env bash #### FUNCTION DEFINITION #### log_cleanup(){ echo "Running Cleanup On Older Logs - 30 days" find /home/karthick/Documents/Projects/logs -name "*.log" -type f -mtime +30 -delete echo "Cleanup Completed" } # Calling the function log_cleanup
Pokud se pokusíte volat funkci před definicí funkce, zobrazí se následující chyba.
line 3: log_cleanup: command not found
Proč? Při spuštění skriptu bude kód interpretován řádek po řádku shora dolů. Načte funkci a načte ji do prostředí bash (paměti). Ale zde voláte funkci ještě předtím, než interpret vůbec čte a načte funkci do svého prostředí.
Když voláte funkci z jiné funkce, může být vaše definice funkce v libovolném pořadí kromě první funkce. Podívejte se na níže uvedený obrázek. Funkce func2 se volá z func1 a func3 se volá z func2 před jejich definicí. Ale func1 je nejprve definován a poté volán. V době func1 se nazývá všechny definice funkcí jsou již interpretovány a načteny do prostředí.
Stav ukončení a návratová hodnota
Každý příkaz systému Linux vrací stav ukončení (0-255). Říká se, že nula je úspěšná a zbytek výstupních kódů jsou údajně selhání s různými významy. Podobně, když spustíte funkci, vrátí také návratový stav posledního spuštěného příkazu ve funkci.
Dovolte mi znovu spustit stejnou funkci „čištění“. Ale dal jsem cestu, která není v mém počítači k dispozici, takže find
příkaz selže. Používám $?
abyste získali stav ukončení ve skriptu, jak je znázorněno na obrázku.
Running Cleanup On Older Logs - 30 days find: '/home/karthick/Documents/Projectss/logs': No such file or directory Cleanup Completed Exit status of function log_cleanup is ⇒ 0
Stav ukončení vrácený funkcí je z echo
příkaz, který běžel jako poslední příkaz uvnitř funkce. Toto není chování, které byste mohli očekávat.
K překonání tohoto chování můžete použít vestavěný bash "return"
prohlášení.
$ type -a return
return is a shell builtin
Return akceptuje celočíselnou hodnotu [N] a opustí funkce a předá návratovou hodnotu svému volajícímu (funkci). Před použitím příkazu return musíte pochopit několik pravidel, jak příkaz return používat. Jak bylo uvedeno dříve, return akceptuje celočíselné hodnoty od 0 do 255. Příkaz return použije stav ukončení posledního spuštěného příkazu, pokud není předán žádný argument (hodnota celého čísla) nebo hodnota překročí 255.
Dovolte mi použít návrat k opravě "cleanup"
funkční chování. Zde používám podmíněné příkazy spolu s příkazem return.
#!/usr/bin/env bash #### FUNCTION DEFINITION #### log_cleanup(){ echo "[ INFO ] - Running Cleanup On Older Logs - 30 days" if [[ -d "/home/karthick/Documents/Projectss/logs" ]] then find -name "*.log" -type f -mtime +30 -delete echo "[ SUCCESS] - Cleanup Completed" else echo "[ ERROR ] - Directory path wrong... Cleanup has not happened..." return 1 fi } # Calling the function log_cleanup echo "++ Exit status of log_cleanup function is ==> $?"
Podívejte se na výstup níže. Funkce vrací kód ukončení 1 z příkazu return.
[ INFO ] - Running Cleanup On Older Logs - 30 days
[ ERROR ] - Directory path wrong… Cleanup has not happened…
++ Exit status of log_cleanup function is ==> 1
Předávání argumentů funkci
Podobně jako předávání argumentů vašim bash skriptům, funkce také přijímají argumenty. Matoucí část je, že funkce používají stejný $1
…$9
speciální proměnné pro přístup k argumentům, což je stejné jako předání argumentu skriptu. Musíte pochopit, co se stane, když použijete tuto speciální proměnnou uvnitř i vně funkce.
cat > arg_test.sh #!/bin/bash echo "Value passed in \$1 is = $1" howdy(){ echo "value of \$1 inside function is = $1" } howdy # Function Call
Zkopírujte a spusťte výše uvedený úryvek, abyste viděli rozdíl. Řetězec "Howdy"
je předán jako první argument skriptu.
$ ./arg_test.sh howdy
Value passed in $1 is = howdy
value of $1 inside function is =
Z výstupu můžete vidět $1
uvnitř funkce tiskne prázdnou hodnotu, protože $1
uvnitř funkce se liší od $1
mimo funkci, ačkoli mají stejný název.
Chcete-li předat argumenty funkci, ponechte za názvem funkce mezeru a předejte své argumenty, jak je znázorněno na obrázku níže. Každý argument oddělený mezerou bude přiřazen s příslušnou proměnnou $1
…$N
a tuto proměnnou můžete použít uvnitř funkce ke zpracování argumentů.
log_cleanup $1 $2 ….. $N
Jak vidíte na výše uvedeném snímku obrazovky, předávám název adresáře a počet dní jako argumenty.
Proměnný rozsah pro funkci
Když vytvoříte proměnnou uvnitř funkce nebo vně funkce, lze k ní přistupovat globálně. Ve výchozím nastavení jsou proměnné vytvářeny v globálním rozsahu.
Podívejte se na níže uvedený příklad. Pokud se pokusíte získat přístup k oběma proměnným outside_function
a inside_function
, jejich hodnoty jsou dostupné. To znamená, že i když se funkce spustila a skončila, proměnná vytvořená uvnitř funkce je globálně přístupná.
#!/bin/bash outside_function="This variable is from outside the function" func1(){ inside_function="This variable is from inside the func1" } func1 echo $outside_function echo $inside_function
V některých programovacích jazycích to nemusí být toto chování a proměnné vytvořené uvnitř funkce budou dostupné během běhu funkce. Ale v bash je chování jiné.
Chcete-li vytvořit proměnné lokální pro funkci, můžete použít vestavěný bash "local"
klíčové slovo. Klíčové slovo local omezí rozsah proměnné z globální na místní a k proměnné lze přistupovat pouze během doby běhu funkce.
#!/bin/bash outside_function="This variable is from outside the function" func1(){ local inside_function="This variable is from inside the func1" } func1 echo $outside_function echo $inside_function
Doporučené čtení:
- Bash Scripting – proměnné vysvětlené na příkladech
Když je použito místní klíčové slovo, můžete použít stejné názvy proměnných v různých funkcích.
Pozor: Vždy byste se měli snažit vyhnout se používání identifikátorů, které se již používají jako proměnné, funkce, klíčová slova bash. Výše uvedený příklad je uveden pouze pro pochopení chování.
Modularita a resubaility
Funkce porozumění a psaní lze provést rychle. Ale psaní dobrých funkcí vyžaduje čas s lepším pochopením prostředí. Jak již bylo zmíněno v úvodní části, s bash funkcemi můžete dosáhnout velké míry modularity a znovupoužitelnosti.
Vezměme si příklad. Vytvořili jste 20 skriptů a do každého skriptu jste zahrnuli log_cleanup
funkce, kterou jsme viděli v předchozích částech pro provádění úkolů údržby. Místo zahrnutí této funkce do všech 20 skriptů můžete vytvořit jedinou definici funkce a importovat ji do 20 skriptů. Tímto způsobem dosáhnete modularity a také opakovaně použitelných funkcí. Je to podobné jako import příkazy v pythonu, zahrnout příkazy v C atd.
Podívejte se na níže uvedený obrázek. Vytvořil jsem dva skripty s názvem script1.sh
a script2.sh
a log_cleanup
funkce je zapsána do samostatného souboru s názvem cleanup.sh
.
Funkci importuji spuštěním source
příkaz. source
příkaz spustí soubor předaný jako jeho argument a načte proměnnou nebo funkce do aktuální relace bash. Tímto způsobem, když spustíte log_cleanup
z jiného souboru skriptu je funkce již načtena do aktuálního prostředí a přístupná.
Z výše uvedeného obrázku můžete pochopit, jak jsou argumenty užitečné. Existuje pouze jedna definice funkce a podle případu použití mohu funkci upravit tak, aby přijímala různé argumenty a v různých skriptech.
Pozor: Své shellové skripty můžete také spouštět pomocí source
příkaz, který spustí skript v aktuálním shellu namísto vytvoření podshell pro spuštění skriptu.
Závěr
V této příručce jsme diskutovali o funkcích Bash a o tom, jak definovat a volat funkci ve skriptech s příklady. Abyste se s funkcemi seznámili, musíte je procvičovat v různých případech použití. Máte-li jakékoli dotazy nebo zpětnou vazbu, dejte nám vědět prostřednictvím sekce komentářů níže.
Související čtení:
- Bash Scripting – pro smyčku vysvětlenou na příkladech
- Bash Scripting – smyčka Zatímco a dokud není vysvětlena příklady
- Rozdíl mezi definováním proměnných Bash s exportem a bez exportu
- Příkaz Bash Echo vysvětlený s příklady v Linuxu
- Výukový program Bash Heredoc pro začátečníky
- Přesměrování Bash vysvětleno na příkladech