Quand un script grandit, il devient comme un dossier d’enquête trop épais. Illisible. Pour garder la main, on découpe. On isole les routines, les tactiques récurrentes, dans des blocs nommés et réutilisables : les fonctions. Un nom de code pour une séquence d’actions. Le premier pas vers l’organisation, vers le professionnalisme dans l’ombre.
9.1 Définition de fonctions
Deux syntaxes. Un même but : encapsuler.
-
Syntaxe 1 : La plus claire, la plus moderne.
nettoyer_traces() { echo "[FONCTION] Nettoyage des traces en cours..." rm -f /tmp/*.log history -c echo " Terminé." } -
Syntaxe 2 : L’ancienne, qui rappelle d’autres langages.
function surveiller_port { echo "[FONCTION] Surveillance du port $1..." netstat -tulpn | grep ":$1" || echo " Port $1 : silencieux." }Le mot-clé
functionest optionnel mais parfois explicite. Préférez la première, elle est portable. -
Appel : Il suffit du nom, comme une commande.
# Dans le flux du script principal : echo "Début de l'opération 'Nuit Blanche'." nettoyer_traces surveiller_port 8080 surveiller_port 22 echo "Phase 1 achevée."
9.2 Paramètres de fonctions
Une fonction vit dans sa propre bulle. Ses paramètres sont $1, $2, etc., mais ils sont locaux à la fonction. Ils n’écrasent pas les $1, $2 du script principal.
-
Passage d’arguments :
journaliser() { local niveau=$1 local message=$2 echo "[$(date '+%H:%M:%S')] [$niveau] $message" >> /var/log/operation.log }Appel :
journaliser "INFO" "Script démarré." journaliser "ALERTE" "Mouvement détecté dans le secteur $zone."À l’intérieur de
journaliser,$1est"INFO"ou"ALERTE". -
Valeur de retour (
return) : Attention, piège.returndans une fonction Bash ne retourne pas une valeur comme dans d’autres langages. Il définit un code de retour numérique (0-255), exactement commeexitpour un script.verifier_acces() { local fichier="$1" if [[ -r "$fichier" && -w "$fichier" ]]; then return 0 # Succès : accès en lecture/écriture. else return 1 # Échec. fi } verifier_acces "/home/noir/plan.txt" if [[ $? -eq 0 ]]; then echo "Le fichier est accessible." else echo "Accès bloqué." >&2 fiPour « retourner » une chaîne ou un résultat complexe, il faut d’autres méthodes.
9.3 Portée des variables et local
Le vrai pouvoir, et le vrai danger. Par défaut, toute variable dans une fonction est globale. Elle modifie la variable du même nom dans tout le script.
-
Le problème :
compteur=0 incrementer() { compteur=5 echo "Dans la fonction, compteur = $compteur" } echo "Avant : compteur = $compteur" # Affiche 0 incrementer # Affiche "Dans la fonction, compteur = 5" echo "Après : compteur = $compteur" # Affiche 5 ! La variable globale a été modifiée. -
La solution :
local. Le mot-clélocallimite la portée de la variable à la fonction et à ses enfants.compteur=0 incrementer_local() { local compteur # Déclaration en local compteur=5 echo "Dans la fonction, compteur local = $compteur" } echo "Avant : compteur global = $compteur" # Affiche 0 incrementer_local # Affiche "Dans la fonction, compteur local = 5" echo "Après : compteur global = $compteur" # Affiche 0 ! Le global est protégé.On déclare et assigne souvent en une ligne :
traiter_fichier() { local fichier_source="$1" local dossier_backup="/backup/$(basename "$fichier_source")" local date_limite=$(date -d "yesterday" '+%Y%m%d') # ... logique utilisant ces variables locales ... }Utilisez
localsystématiquement pour éviter les effets de bord qui transforment un script en champ de mines.
Les fonctions sont vos alliés silencieux. Elles structurent, elles masquent la complexité, elles permettent la réutilisation. Un script bien découpé en fonctions est comme un réseau de cellules dormantes : chacune sait faire une chose, et ne réveille les autres que lorsque c’est nécessaire. C’est la marque d’un planificateur qui pense à l’après, à la maintenance, à l’évolution dans l’ombre.
Définissez. Appelez. Contrôlez la portée. Et gardez votre code global propre.