Une fonction Bash est un bloc de commandes nommé, réutilisable à l’intérieur du script. Sans fonctions, chaque logique répétée — validation d’argument, affichage d’erreur, transformation de chaîne — doit être dupliquée. Avec des fonctions bien découpées, un script de 200 lignes devient lisible et testable, et les fonctions utilitaires peuvent être partagées entre scripts via source.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Déclarer et appeler une fonction avec et sans le mot-clé
function - Accéder aux arguments d’une fonction via
$1,$2,$@ - Utiliser
localpour éviter de polluer les variables globales - Retourner une valeur par
echocapturé avec$() - Renvoyer un code de sortie utilisable dans un
if - Organiser les fonctions utilitaires dans un fichier séparé et les charger avec
source
Dans quel contexte ?
Section intitulée « Dans quel contexte ? »Les fonctions apparaissent naturellement dès qu’un script dépasse une vingtaine de lignes :
- encapsuler la logique de validation d’un argument dans
verifier_arg()appelée pour chaque paramètre - centraliser la gestion des erreurs dans
erreur()pour ne pas dupliquer leecho >&2; exit 1 - extraire une transformation (récupérer l’extension d’un fichier, normaliser un nom) dans une fonction réutilisable
- partager des fonctions de log (
log_info,log_warn,log_error) entre plusieurs scripts grâce àsource
En préparation RHCSA, les fonctions sont souvent testées dans des exercices de refactoring de script : vous devrez encapsuler une portion de code existante en fonction et l’appeler.
Déclarer et appeler une fonction
Section intitulée « Déclarer et appeler une fonction »Deux syntaxes équivalentes :
# Syntaxe recommandée en Bashbonjour() { echo "Bonjour depuis une fonction !"}
# Syntaxe avec le mot-clé function (POSIX)function bonjour { echo "Bonjour depuis une fonction !"}L’appel s’écrit comme une commande — sans parenthèses :
bonjour# Bonjour depuis une fonction !Une fonction doit être déclarée avant son premier appel — contrairement à certains langages, Bash exécute les fichiers de haut en bas.
Arguments d’une fonction
Section intitulée « Arguments d’une fonction »Les fonctions reçoivent leurs arguments comme un script : $1, $2… $@, $#.
saluer() { local prenom="$1" local titre="${2:-M.}" # valeur par défaut si $2 absent echo "Bonjour $titre $prenom"}
saluer "Alice" # Bonjour M. Alicesaluer "Bob" "Dr." # Bonjour Dr. Bobshift — décaler les arguments
Section intitulée « shift — décaler les arguments »shift supprime $1 et décale tous les suivants d’un rang. Utile pour traiter le premier argument comme un titre, puis itérer sur les suivants :
afficher_liste() { local titre="$1" shift # $2 devient $1, $3 devient $2... echo "$titre :" for item in "$@"; do echo " - $item" done}
afficher_liste "Services" "nginx" "postgresql" "redis"# Services :# - nginx# - postgresql# - redisVariables locales avec local
Section intitulée « Variables locales avec local »Sans local, une affectation dans une fonction modifie la variable globale :
nom="global"
modifier() { nom="modifié dans la fonction" # modifie la variable globale !}
modifierecho "$nom" # modifié dans la fonctionAvec local, la portée est limitée à la fonction :
nom="global"
modifier() { local nom="local à la fonction" echo "Dans la fonction : $nom"}
modifierecho "Après : $nom"# Dans la fonction : local à la fonction# Après : globalRègle : déclarez toutes les variables internes d’une fonction avec local — c’est la forme défensive par défaut.
Retourner une valeur
Section intitulée « Retourner une valeur »Par echo + $()
Section intitulée « Par echo + $() »Bash ne dispose pas de return valeur_textuelle. La méthode standard consiste à echo la valeur dans la fonction, puis à la capturer avec $() :
extension() { local fichier="$1" echo "${fichier##*.}"}
ext=$(extension "rapport.tar.gz")echo "Extension : $ext"# Extension : gzdate_snapshot() { date '+%Y%m%d_%H%M%S'}
sauvegarde="/backup/app_$(date_snapshot).tar.gz"echo "$sauvegarde"# /backup/app_20260410_080812.tar.gzPar code de retour — pour les conditions
Section intitulée « Par code de retour — pour les conditions »return sans argument retourne le code de la dernière commande. return N retourne le code N (0 = succès, 1–255 = erreur).
fichier_lisible() { local f="$1" [[ -r "$f" ]] # retourne 0 si lisible, 1 sinon}
if fichier_lisible "/etc/passwd"; then echo "/etc/passwd : lisible"fi
if ! fichier_lisible "/etc/shadow"; then echo "/etc/shadow : non lisible (normal en user)"fi# /etc/passwd : lisible# /etc/shadow : non lisible (normal en user)Ce patron est très utilisé pour valider des préconditions :
service_actif() { systemctl is-active --quiet "$1"}
service_actif "nginx" || { echo "nginx arrêté — abandon." >&2; exit 1; }Retourner plusieurs valeurs
Section intitulée « Retourner plusieurs valeurs »Bash ne supporte pas les retours multiples. La convention consiste à affecter des variables globales avec un préfixe explicite :
calculer() { local a="$1" local b="$2" RESULT_SOMME=$((a + b)) RESULT_PRODUIT=$((a * b))}
calculer 6 7echo "Somme=$RESULT_SOMME, Produit=$RESULT_PRODUIT"# Somme=13, Produit=42Fonctions utilitaires courantes
Section intitulée « Fonctions utilitaires courantes »Fonction d’erreur
Section intitulée « Fonction d’erreur »Une fonction erreur() centralisée évite de dupliquer echo >&2; exit 1 partout :
erreur() { echo "ERREUR : $*" >&2 exit 1}
verifier_arg() { local val="$1" local nom="$2" [[ -n "$val" ]] || erreur "L'argument '$nom' est obligatoire."}
verifier_arg "monapp" "APP_NAME" # OKverifier_arg "" "APP_NAME" # ERREUR : L'argument 'APP_NAME' est obligatoire.$* dans erreur() concatène tous les arguments en une seule chaîne — pratique pour un message d’erreur composé.
Fonctions de log
Section intitulée « Fonctions de log »log_info() { echo "[INFO] $(date '+%H:%M:%S') $*"; }log_warn() { echo "[WARN] $(date '+%H:%M:%S') $*" >&2; }log_error() { echo "[ERROR] $(date '+%H:%M:%S') $*" >&2; }
log_info "Démarrage de l'application"log_warn "Configuration par défaut utilisée"log_error "Connexion à la base échouée"# [INFO] 08:08:12 Démarrage de l'application# [WARN] 08:08:12 Configuration par défaut utilisée# [ERROR] 08:08:12 Connexion à la base échouéeBibliothèque partagée avec source
Section intitulée « Bibliothèque partagée avec source »source (ou .) charge et exécute un fichier dans le contexte du shell courant — ses fonctions deviennent disponibles immédiatement :
erreur() { echo "ERREUR : $*" >&2; exit 1; }log_info() { echo "[INFO] $(date '+%H:%M:%S') $*"; }log_error() { echo "[ERROR] $(date '+%H:%M:%S') $*" >&2; }#!/bin/bashset -euo pipefail
# shellcheck source=lib/utils.shsource "$(dirname "$0")/lib/utils.sh"
log_info "Script démarré"[[ $# -ge 1 ]] || erreur "Usage : $(basename "$0") <argument>"log_info "Argument : $1"$(dirname "$0") pointe vers le répertoire du script courant — la bibliothèque est trouvée même si le script est appelé depuis un autre répertoire.
Dépannage
Section intitulée « Dépannage »| Symptôme | Cause probable | Solution |
|---|---|---|
| Variable non modifiée après l’appel | Déclarée avec local dans la fonction | Utiliser une variable globale avec un préfixe explicite (RESULT_) |
command not found à l’appel | Fonction déclarée après l’appel | Déplacer la déclaration avant le premier appel |
$(fonction) retourne vide | La fonction utilise return au lieu de echo | echo la valeur ; return ne sert qu’aux codes de sortie |
Modifications de $1 dans la fonction affectent le script | Pas de local | local arg="$1" puis utiliser $arg |
source lib.sh : No such file | Chemin relatif au répertoire courant | Utiliser source "$(dirname "$0")/lib.sh" |
À retenir
Section intitulée « À retenir »- La syntaxe
nom_fonction() { ... }est la forme recommandée en Bash. - Déclarez toujours les variables internes avec
local— c’est la forme défensive par défaut. - Pour retourner une valeur textuelle :
echodans la fonction +$(fonction)à l’appel. - Pour retourner un booléen : la fonction se termine par une commande ou un test
[[ ]]— utilisable directement dansif. sourcecharge une bibliothèque de fonctions dans le shell courant — le chemin doit être basé sur$(dirname "$0").