Dypere inn i funksjonskompleksiteter med Shell Scripting – Del VII


Min forrige artikkel om "Forstå og skrive funksjoner i Shell-skript" kan ha gitt deg en grunnleggende idé om hvordan du skriver funksjoner under skall-skript. Nå er det på tide å gå dypere inn i funksjonelle funksjoner som bruk av lokale variabler og rekursjon.

Lokale variabler

Hva gjør en variabel lokal? Det avhenger av den spesielle blokken hvor variabelen er deklarert. En variabel erklært som lokal vil være tilgjengelig fra den kodeblokken der den vises, dvs. omfanget er lokalt. For å forklare dette, la oss se på ett eksempel nedenfor.

#!/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

Ved utføring av skriptet ovenfor vil utgangen være.

i outside func = 
j outside func = 
i from func = 10 
j from func = 20 
i outside func = 
j outside func = 20

Dette er fordi funksjonen func ennå ikke har kalt mens de første 2 ekkosetningene ble utført. Etter å ha kalt funksjonen func gir de samme 2 ekkosetningene et annet resultat. Nå kunne variabelen j, som ble erklært inne i func og ikke lokal, nås etterpå.

Dermed blir verdien for j 20. Hva med den lokale variabelen i? Siden omfanget var innenfor funksjonen func, kunne ikke verdien 10 nås utenfra. Legg merke til at variabelen j som normalt er deklarert i func er global som standard.

Nå er du kjent med lokale variabler og hvordan du bruker dem i funksjonsblokker. La oss gå videre til den mest interessante delen under funksjoner, rekursjonen.

Hva er rekursjon?

En funksjon som kaller seg selv blir generelt betegnet som rekursjonsprosedyren. Eller det kan defineres som å uttrykke en algoritme ved å bruke en enklere versjon av den samme algoritmen. Tenk på eksempelet med å finne faktorial av et tall. Vi vet at n!=1 x 2 x 3 x … x (n-1) x n. Dermed kan vi skrive en gjentakelsesrelasjon som:

n! = (n-1)! x n

Så det er enkelt for oss å rekursivt kalle den samme funksjonen og bruke returverdien fra hvert kall for å multiplisere med det forrige resultatet, dvs.

5! = 4! x 5
4! = 3! x 4
3! = 2! x 3
2! = 1! x 2
1! = 0! x 1

Rekursjon ved bruk av lokale variabler

Her prøver vi å skrive et skript for å finne faktorial av et tall ved å bruke lokale variabler og rekursjon.

#!/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 er en lokal variabel som brukes til å lagre hver n-1 verdi for hvert anrop. Her kontrollerer grunnbetingelsen om tallet er lik null eller ikke (siden 0!=1 og faktorial ikke er definert for negative tall). Når den ankommer denne grunntilstanden, returnerer den verdien 1 til den som ringer. Nå num=1 og ret=1 x 1.

På dette øyeblikket returnerer den 1 til den som ringer. Nå num=2 og ret=2 x 1 og så videre. Til slutt når num=5 returnerer verdien 24 og sluttresultatet er ret=5 x 24. Det endelige resultatet 120 sendes videre til den første oppringeren og vises.

Det er ett problem i skriptet ovenfor. Som jeg forklarte i forrige artikkel, kan ikke funksjoner returnere store heltall. Så det er overlatt til brukerne å finne en løsning på problemet ovenfor.

Sp. Kan vi utføre rekursjon uten å bruke lokale variabler? Svaret erJa.

Rekursjon uten lokale variabler

Se på følgende eksempel for å vise Fibonacci-serien ved bruk av rekursjon. Den grunnleggende gjentakelsesrelasjonen er:

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

Ingen lokale variabler brukes i skriptet ovenfor. Jeg håper du kan forstå flyten av skriptet under utførelse.

Her representerer verdien 15 antall termer i Fibonacci-serien som skal vises. La du merke til noe spesielt angående utførelsen av skriptet ovenfor. Det tar litt tid, ikke sant? Rekursjon i et skript er tregere enn en rekursjon i programmeringsspråk som C.

Med denne artikkelen planlegger jeg å avslutte funksjonsdelen i shell-scripting. Hold deg oppdatert med Tecmint for å ha de kommende artiklene om arrays og mye mer...