Dublje u složenost funkcija s skriptiranjem ljuske – dio VII
Moj prethodni članak o “Razumijevanje i pisanje funkcija u skriptama ljuske” možda vam je dao osnovnu ideju o tome kako pisati funkcije u skriptama ljuske. Sada je vrijeme da uđemo dublje u funkcionalne značajke poput upotrebe lokalnih varijabli i rekurzije.
Lokalne varijable
Što varijablu čini lokalnom? Ovisi o tom određenom bloku u kojem je varijabla deklarirana. Varijabla deklarirana kao lokalna bit će dostupna iz onog bloka koda u kojem se pojavljuje, tj. njen opseg je lokalni. Kako bismo objasnili ovu stvar, pogledajmo jedan primjer u nastavku.
#!/bin/bash
func( ) {
local i=10
j=20
echo "i from func = $i"
echo "j from func = $j"
}
echo "i outside func = $i"
echo "j outside func = $j"
func
echo "i outside func = $i"
echo "j outside func = $j"
exit 0
Prilikom izvršavanja gornje skripte izlaz će biti.
i outside func =
j outside func =
i from func = 10
j from func = 20
i outside func =
j outside func = 20
To je zato što funkcija func još nije pozvana dok su prve 2 echo izjave bile izvršene. Nakon poziva funkcije func iste 2 echo izjave daju drugačiji rezultat. Sada se varijabli j, koja je deklarirana unutar func a ne local, moglo pristupiti naknadno.
Tako vrijednost za j postaje 20. Što je s lokalnom varijablom i? Budući da je njezin opseg bio unutar funkcije func, vrijednosti 10 nije se moglo pristupiti izvana. Imajte na umu da je varijabla j koja se obično deklarira unutar func prema zadanim postavkama globalna.
Sada ste upoznati s lokalnim varijablama i kako ih koristiti unutar funkcijskih blokova. Prijeđimo na najzanimljiviji dio pod funkcijama, rekurziju.
Što je rekurzija?
Sam poziv funkcije općenito se naziva rekurzijskom procedurom. Ili se može definirati kao izražavanje algoritma korištenjem jednostavnije verzije tog istog algoritma. Razmotrimo primjer nalaženja faktorijela broja. Znamo ton!=1 x 2 x 3 x … x (n-1) x n. Stoga možemo napisati odnos ponavljanja kao:
n! = (n-1)! x n
Dakle, lako nam je rekurzivno pozvati istu funkciju i koristiti povratnu vrijednost iz svakog poziva za množenje s prethodnim rezultatom, tj.
5! = 4! x 5
4! = 3! x 4
3! = 2! x 3
2! = 1! x 2
1! = 0! x 1
Rekurzija korištenjem lokalnih varijabli
Ovdje pokušavamo napisati skriptu za pronalaženje faktorijela broja koristeći lokalne varijable i rekurziju.
#!/bin/bash
fact( ) {
local num=$1
if [ $num -eq 0 ]; then
ret=1
else
temp=$((num-1))
fact $temp
ret=$((num*$?))
fi
return $ret
}
fact 5
echo "Factorial of 5 = $?"
exit 0
num je lokalna varijabla koja se koristi za pohranjivanje svake vrijednosti n-1 pri svakom pozivu. Ovdje osnovni uvjet provjerava je li broj jednak nuli ili ne (jer je 0!=1 i faktorijel nije definiran za negativne brojeve). Kada dođe do ovog osnovnog uvjeta, vraća vrijednost 1 svom pozivatelju. Sada num=1 i ret=1 x 1.
U ovom trenutku pozivatelju vraća 1. Sada num=2 i ret=2 x 1 i tako dalje. Konačno, kada je num=5 povratna vrijednost će biti 24, a konačni rezultat je ret=5 x 24. Konačni rezultat 120 prenosi se do početne izjave pozivatelja i prikazuje se.
Postoji jedan problem u gornjoj skripti. Kao što sam objasnio u prethodnom članku, funkcije ne mogu vratiti velike cijele brojeve. Stoga je prepušteno korisnicima da pronađu rješenje za gornji problem.
P. Možemo li izvesti rekurziju bez korištenja lokalnih varijabli? Odgovor jeDa.
Rekurzija bez lokalnih varijabli
Pogledajte sljedeći primjer za prikaz Fibonaccijevog niza pomoću rekurzije. Osnovna relacija ponavljanja je:
fib(0) = 0
fib(1) = 1
else
fib(n) = fib(n-1) + fib(n-2)
Fibonacci series using recursion
#!/bin/bash
fib( ) {
a=$1
if [ $a -lt 2 ]; then
echo $a
else
((--a))
b=$(fib $a)
((--a))
c=$(fib $a)
echo $((b+c))
fi
}
for i in $(seq 0 15)
do
out=$(fib $i)
echo $out
done
exit 0
U gornjoj skripti ne koriste se lokalne varijable. Nadam se da možete razumjeti tijek skripte tijekom izvođenja.
Ovdje vrijednost 15 predstavlja broj članova u Fibonaccijevom nizu koji će se prikazati. Jeste li primijetili nešto posebno u vezi s izvršavanjem gornje skripte. Potrebno je neko vrijeme, zar ne? Rekurzija u skripti je sporija od rekurzije u programskim jezicima kao što je C.
Ovim člankom planiram zaključiti dio s funkcijama u skriptiranju ljuske. Budite u tijeku s Tecmintom kako biste imali nadolazeće članke o nizovima i još mnogo toga…