Objectifs
- Définir et appeler des fonctions pour organiser et réutiliser du code.
- Passer des arguments à une fonction.
- Renvoyer une valeur (un code de sortie ou une chaîne de caractères).
- Comprendre la portée des variables (
localvsglobal) pour écrire des fonctions sûres.
Explications détaillées
Notions clés
Une fonction est un bloc de code nommé que vous pouvez appeler à plusieurs reprises. C’est le principal outil pour structurer un script, éviter la duplication et améliorer la lisibilité.
Définir et Appeler une fonction
Il existe deux syntaxes pour définir une fonction. La première est la plus courante et portable.
# Syntaxe 1 (recommandée)
ma_fonction() {
# Commandes à l'intérieur de la fonction
echo "Hello depuis la fonction"
}
# Syntaxe 2 (avec le mot-clé 'function')
function une_autre_fonction {
echo "Une autre fonction"
}
# Pour appeler une fonction, il suffit d'utiliser son nom
ma_fonction
Passer des arguments
Les arguments sont passés à une fonction de la même manière qu’à un script. À l’intérieur de la fonction, ils sont accessibles via les variables positionnelles : $1 (premier argument), $2 (deuxième), $# (nombre d’arguments), $@ (tous les arguments).
saluer() {
local nom="$1"
echo "Bonjour, $nom !"
}
saluer "Alice"
saluer "Bob"
Renvoyer des valeurs
En Bash, une fonction peut “renvoyer” deux types de choses :
- Un code de sortie (succès/échec) : C’est un nombre entier entre 0 et 255.
0signifie succès, toute autre valeur signifie échec. On utilise le mot-cléreturn. C’est utile pour les tests conditionnels. - Une chaîne de caractères (des données) : Pour cela, la fonction doit écrire le résultat sur sa sortie standard (avec
echoouprintf). L’appelant doit alors capturer cette sortie avec une substitution de commande$(...).
La Portée des Variables : local est votre meilleur ami
Par défaut, toute variable que vous créez dans un script Bash est globale. Si vous la modifiez dans une fonction, la modification est visible partout. C’est une source majeure de bugs.
Pour créer une variable qui n’existe que à l’intérieur de la fonction, utilisez le mot-clé local.
Syntaxe / Usages
# Définition et appel
creer_rapport() {
echo "--- Rapport du $(date) ---"
}
creer_rapport
# Avec arguments
ajouter() {
# Notez l'utilisation de 'local'
local premier="$1"
local deuxieme="$2"
echo $((premier + deuxieme))
}
somme=$(ajouter 10 5) # Capture de la sortie stdout
echo "La somme est $somme"
# Avec un code de sortie
fichier_existe() {
if [[ -f "$1" ]]; then
return 0 # Succès
else
return 1 # Échec
fi
}
if fichier_existe "mon_fichier.txt"; then
echo "Le fichier a été trouvé."
else
echo "Le fichier est manquant."
fi
Exemples
# Exemple 1: Fonction avec variable locale
ma_fonction() {
local ma_variable_locale="Je suis locale"
ma_variable_globale="Je suis globale"
echo "Dans la fonction : $ma_variable_locale"
echo "Dans la fonction : $ma_variable_globale"
}
ma_fonction
# echo $ma_variable_locale # -> Ne fonctionne pas, affiche une ligne vide
echo "Hors de la fonction : $ma_variable_globale" # -> Fonctionne
# Exemple 2: Combiner code de sortie et sortie standard
obtenir_utilisateur() {
local id="$1"
if [[ -z "$id" ]]; then
echo "Erreur : ID manquant" >&2 # Écrit l'erreur sur stderr
return 1
fi
# Simule une recherche
echo "utilisateur-$id" # Écrit le résultat sur stdout
return 0
}
# On teste d'abord si la fonction a réussi
if resultat=$(obtenir_utilisateur "123"); then
echo "Utilisateur trouvé : $resultat"
else
echo "Échec de la recherche."
fi
Bonnes pratiques
- Utilisez
localpour toutes les variables à l’intérieur de vos fonctions. Toujours. Cela évite les effets de bord et rend vos fonctions autonomes et prévisibles. - Une fonction doit avoir une seule responsabilité. Si une fonction fait trop de choses, découpez-la en plusieurs petites fonctions.
- Utilisez
returnpour indiquer un statut (succès/échec) et la sortie standard (echo) pour renvoyer des données. Ne mélangez pas les deux. - Commentez vos fonctions : expliquez brièvement ce qu’elle fait, quels arguments elle attend et ce qu’elle renvoie.
Pièges courants
- Oublier
local: Modifier une variable globale par accident est un bug très difficile à tracer. - Confondre code de sortie et sortie standard :
return "mon résultat"ne fonctionnera pas comme prévu.returnne peut renvoyer qu’un nombre (0-255). - Appeler une fonction avant sa définition : Contrairement à certains langages, en Bash, une fonction doit être définie avant de pouvoir être appelée.
Exercices
-
Fonction de validation :
- Écrivez une fonction
est_nombrequi prend un argument. - Elle doit retourner
0(succès) si l’argument est un entier, et1(échec) sinon. - Testez-la avec un
if. (Indice : vous pouvez utiliser une expression régulière[[ "$1" =~ ^-?[0-9]+$ ]]).
- Écrivez une fonction
-
Fonction qui renvoie une chaîne :
- Créez une fonction
timestampqui ne prend aucun argument et qui renvoie la date et l’heure actuelles au formatYYYY-MM-DD_HH-MM-SS. - Appelez cette fonction pour créer un fichier de log avec un nom unique. Ex:
touch "log-$(timestamp).txt".
- Créez une fonction
-
Fonction et portée :
- Écrivez une fonction
calculqui déclare une variabletotallocale et une variablemessageglobale. - À l’extérieur, déclarez aussi une variable
total. - Appelez la fonction, puis affichez la valeur des deux variables
totalet demessageà l’extérieur pour bien visualiser la différence de portée.
- Écrivez une fonction