Chapitre 14. Fonctions shell

Table des matières

14.1. Définition d’une fonction
14.2. Suppression d’une fonction
14.3. Trace des appels aux fonctions
14.4. Arguments d’une fonction
14.5. Variables locales à une fonction
14.6. Commande interne return
14.7. Transmission du résultat d'une fonction
14.7.1. Utilisation d'une variable nameref
14.7.2. Substitution de fonction
14.8. Fonctions récursives
14.9. Exporter une fonction
14.10. Appels de fonctions dispersées dans plusieurs fichiers

14.1. Définition d’une fonction

Pour définir une fonction, le shell bash propose plusieurs syntaxes. Deux exemples de définitions possibles sont :


                   nomfct()                                          function nomfct
                   {                                       ou          { 
                       suite_de_commandes                        suite_de_commandes 
                   }                                                     }
                

Pour des raisons de lisibilité, nous utiliserons la deuxième forme.

nomfct spécifie le nom de la fonction. Le corps de celle-ci est suite_de_commandes.

Pour appeler une fonction, il suffit de mentionner son nom.

Comme pour les autres commandes composées de bash, une fonction peut être définie directement à partir d’un shell interactif.

$ function f0
> {
> echo Bonjour tout le monde !
> }
$
$ f0    => appel de la fonction f0
Bonjour tout le monde !
$

Les mots réservés function et } doivent être les premiers mots d'une commande pour qu’ils soient reconnus. Sinon, il suffit de placer un caractère point-virgule avant le mot-clé :


                   function nomfct
                   { suite_de_commandes ;}

La définition d’une fonction « à la C » est également possible :


                  function nomfct  {
                  suite_de_commandes
                  }

L'exécution d'une fonction s'effectue dans l'environnement courant, autorisant ainsi le partage de variables.

$ c=Coucou
$
$ function f1
> {
> echo $c    => utilisation dans la fonction d’une variable externe c
> }
$
$ f1
Coucou
$

Les noms de toutes les fonctions définies peuvent être listés à l'aide de la commande : declare -F

$ declare -F
  ...
declare -f f0
declare -f f1
  ...
$

Les noms et corps de toutes les fonctions définies sont affichés à l’aide de la commande : declare -f

$ declare -f
 ...
f0 ()
{
  echo Bonjour tout le monde !
}
f1 ()
{
  echo $c
}
 ...
$

Pour afficher le nom et corps d’une ou plusieurs fonctions : declare -f nomfct ...

$ declare -f f0
f0 ()
{
  echo Bonjour tout le monde !
}
$

Une définition de fonction peut se trouver en tout point d’un programme shell ; il n’est pas obligatoire de définir toutes les fonctions en début de programme. Il est uniquement nécessaire que la définition d’une fonction soit faite avant son appel effectif, c'est-à-dire avant son exécution :


                   function f1
                   { ... ;}

                   suite_commandes1

                   function f2
                   { ... ;}

                   suite_commandes2

Dans le code ci-dessus, suite_commandes1 ne peut exécuter la fonction f2 (contrairement à suite_commandes2). Cela est illustré par le programme shell appelAvantDef :

	#!/bin/bash
	#	@(#)	appelAvantDef 


	echo Appel Avant definition de fct
	fct        # fct non definie


	function fct
	{
	echo Execution de : fct
	sleep 2
	echo Fin Execution de : fct
	}


	echo Appel Apres definition de fct
	fct        # fct definie

Son exécution se déroule de la manière suivante :

$ appelAvantDef
Appel Avant definition de fct
./appelAvantDef: line 6: fct : commande introuvable
Appel Apres definition de fct
Execution de : fct
Fin Execution de : fct
$

Lors du premier appel à la fonction fct, celle-ci n’est pas définie : une erreur d’exécution se produit. Puis, le shell lit la définition de la fonction fct : le deuxième appel s’effectue correctement.

Contrairement au programme précédent, dans le programme shell pingpong, les deux fonctions ping et pong sont définies avant leur appel effectif :

	#!/bin/bash
	@(#)	pingpong


	function ping
	{
	echo ping
	if (( i > 0 ))
	  then
	    ((i--))
	    pong
	fi
	}


	function pong
	{
	echo pong
	if (( i > 0 ))
	  then
	    ((i--))
	    ping
	fi
	}


	declare -i i=4
	ping    # (1) ping et pong sont definies

Au point (1), les corps des fonctions ping et pong ont été lus par bash : ping et pong sont définies.

$ pingpong
ping
pong
ping
pong
ping
$