Recherche de site Web

Approfondir les complexités des fonctions avec les scripts Shell – Partie VII


Mon article précédent sur « Comprendre et écrire des fonctions dans des scripts Shell » vous a peut-être donné une idée de base sur la façon d'écrire des fonctions sous des scripts Shell. Il est maintenant temps d'approfondir les fonctionnalités fonctionnelles telles que l'utilisation de variables locales et la récursivité.

Variables locales

Qu'est-ce qui rend une variable locale ? Cela dépend du bloc particulier où la variable est déclarée. Une variable déclarée comme locale sera accessible à partir du bloc de code où elle apparaît, c'est-à-dire que sa portée est locale. Afin d’expliquer cette chose, examinons un exemple ci-dessous.

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

Lors de l'exécution du script ci-dessus, la sortie sera.

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

En effet, la fonction func n'a pas encore été appelée alors que les deux premières instructions d'écho ont été exécutées. Après avoir appelé la fonction func, les mêmes 2 instructions echo produisent un résultat différent. Désormais, la variable j, qui était déclarée dans func et non locale, était accessible par la suite.

Ainsi, la valeur de j devient 20. Qu'en est-il de la variable locale i ? Comme sa portée était à l'intérieur de la fonction func, la valeur 10 n'était pas accessible de l'extérieur. Notez que la variable j normalement déclarée dans func est globale par défaut.

Vous êtes désormais familiarisé avec les variables locales et comment les utiliser dans les blocs fonctionnels. Passons à la section la plus intéressante sous les fonctions, la récursivité.

Qu’est-ce que la récursivité ?

Une fonction qui s'appelle elle-même est généralement appelée procédure de récursivité. Ou il peut être défini comme exprimant un algorithme en utilisant une version plus simple de ce même algorithme. Prenons l'exemple de la recherche de la factorielle d'un nombre. Nous savons que n!=1 x 2 x 3 x … x (n-1) x n. On peut donc écrire une relation de récurrence sous la forme :

n! = (n-1)! x n

Il est donc facile pour nous d'appeler récursivement la même fonction et d'utiliser la valeur de retour de chaque appel pour multiplier par le résultat précédent, c'est-à-dire

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

Récursivité utilisant des variables locales

Ici, nous essayons d'écrire un script pour trouver la factorielle d'un nombre en utilisant des variables locales et la récursion.

#!/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 est une variable locale utilisée pour stocker chaque valeur n-1 à chaque appel. Ici, la condition de base vérifie si le nombre est égal à zéro ou non (puisque 0 !=1 et que la factorielle n'est pas définie pour les nombres négatifs). En arrivant à cette condition de base, il renvoie la valeur 1 à son appelant. Maintenant num=1 et ret=1 x 1.

A cet instant il renvoie 1 à son appelant. Maintenant num=2 et ret=2 x 1 et ainsi de suite. Enfin, lorsque num=5, la valeur de retour sera 24 et le résultat final est ret=5 x 24. Le résultat final 120 est transmis à l'instruction initiale de l'appelant et est affiché.

Il y a un problème dans le script ci-dessus. Comme je l'ai expliqué dans l'article précédent, les fonctions ne peuvent pas renvoyer de grands entiers. Il appartient donc aux utilisateurs de trouver une solution au problème ci-dessus.

Q. Pouvons-nous effectuer une récursion sans utiliser de variables locales ? La réponse estOui.

Récursivité sans variables locales

Regardez l'exemple suivant pour afficher la série de Fibonacci en utilisant la récursion. La relation de récurrence de base est la suivante :

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

Aucune variable locale n'est utilisée dans le script ci-dessus. J'espère que vous pourrez comprendre le déroulement du script pendant l'exécution.

Ici la valeur 15 représente le nombre de termes de la série de Fibonacci à afficher. Avez-vous remarqué quelque chose de spécial concernant l'exécution du script ci-dessus. Cela prend du temps, n'est-ce pas ? La récursion dans un script est plus lente qu'une récursion dans des langages de programmation comme C.

Avec cet article, je prévois de conclure la partie fonctions des scripts shell. Restez à jour avec Tecmint pour avoir les prochains articles sur les matrices et bien plus encore…