Dybere ind i funktionskompleksiteter med Shell Scripting - del VII


Min tidligere artikel om “Forståelse og skrivning af funktioner i shell-scripts” har muligvis givet dig en grundlæggende idé om, hvordan du skriver funktioner under shell-scripts. Nu er det tid til at komme dybere ind i funktionelle funktioner som brugen af lokale variabler og rekursion.

Hvad gør en variabel lokal? Det afhænger af den pågældende blok, hvor variablen er deklareret. En variabel, der er deklareret som lokal , vil være tilgængelig fra den kodeblok, hvor den vises, dvs. dens omfang er lokalt. For at forklare denne ting skal vi se på et 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 udførelse af ovenstående script vil output være.

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

Dette skyldes, at funktionen func endnu ikke har kaldt, mens de første 2 ekkosætninger blev udført. Efter at have kaldt funktionen func giver de samme 2 ekko-udsagn et andet resultat. Nu kunne variablen j , som blev erklæret i func og ikke lokal, åbnes bagefter.

Således bliver værdi for j 20. Hvad med den lokale variabel i ? Da dets omfang var inde i funktionen func , kunne værdi 10 ikke åbnes udefra. Bemærk, at variablen j , der normalt er angivet i func , er global som standard.

Nu er du fortrolig med lokale variabler, og hvordan du bruger dem inde i funktionsblokke. Lad os gå videre til det mest interessante afsnit under funktioner, rekursion.

En funktion, der kalder sig selv, betegnes generelt som rekursionsproceduren. Eller det kan defineres som udtryk for en algoritme ved hjælp af en enklere version af den samme algoritme. Overvej eksemplet med at finde et nummer af en faktor. Vi ved, at n! = 1 x 2 x 3 x… x (n-1) x n. Således kan vi skrive en gentagelsesrelation som:

n! = (n-1)! x n

Så det er let for os at kalde den samme funktion rekursivt og bruge returværdien fra hvert opkald til at multiplicere med det foregående resultat, dvs.

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

Her prøver vi at skrive et manuskript til at finde et faktory af et tal ved hjælp af lokale variabler og rekursion.

#!/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, der bruges til at gemme hver n-1-værdi på hvert opkald. Her kontrollerer basisbetingelsen, om tallet er lig med nul eller ej (da 0! = 1 og faktor er ikke defineret for negative tal). Ved ankomsten til denne basistilstand returnerer den værdien 1 til sin opkalder. Nu num = 1 og ret = 1 x 1 .

På dette øjeblik vender den tilbage 1 til sin opkalder. Nu num = 2 og ret = 2 x 1 og så videre. Endelig når num = 5 returneringsværdien er 24, og det endelige resultat er ret = 5 x 24 . Det endelige resultat 120 sendes ned til den oprindelige opkaldserklæring og vises.

Der er et problem i ovenstående script. Som jeg forklarede i den foregående artikel, kan funktioner ikke returnere store heltal. Så det overlades til brugerne at finde en løsning til ovenstående problem.

Sp. Kan vi udføre rekursion uden at bruge lokale variabler? Svaret er ja.

Se på følgende eksempel for at få vist Fibonacci-serien ved hjælp af rekursion. Den grundlæggende gentagelsesrelation 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 bruges i ovenstående script. Jeg håber, du kan forstå strømmen af script under udførelse.

Her repræsenterer værdien 15 antallet af udtryk i Fibonacci-serien, der skal vises. Har du bemærket noget specielt med hensyn til udførelsen af ovenstående script. Det tager et stykke tid, ikke? Rekursion i et script er langsommere end en rekursion i programmeringssprog som C.

Med denne artikel planlægger jeg at afslutte funktionsdelen i shell-scripting. Bliv opdateret med Tecmint for at have de kommende artikler om arrays og meget mere ...