Aller au contenu principal
LinuxBashScriptingFormationDevOps

Bash scripting : les bases

30 min de lecture Apprendre Linux & Bash — Chapitre 3

Apprends les bases du scripting Bash : variables, conditions, boucles et l'anatomie d'un script.

Tu sais naviguer dans un terminal, lancer des commandes, te déplacer dans l’arborescence. Maintenant, on passe à l’étape qui transforme un utilisateur Linux en vrai DevOps : écrire des scripts Bash.

Un script, c’est simplement une suite de commandes que tu aurais tapées à la main — sauf que le système les exécute pour toi, sans erreur, à 3h du matin un dimanche. C’est la différence entre “je sais utiliser Linux” et “Linux travaille pour moi”.


Pourquoi le scripting Bash change tout

Dans la vraie vie DevOps, tu ne tapes pas les mêmes 15 commandes chaque matin pour vérifier tes serveurs. Tu les scripts une fois, et ensuite c’est automatique.

Bash est partout. Chaque serveur Linux a Bash installé par défaut — pas besoin de Python, pas besoin de Ruby, pas de dépendances. C’est le couteau suisse qui est toujours dans ta poche.

Concrètement, le scripting Bash te permet de :

  • Automatiser les tâches répétitives (backups, rotations de logs, déploiements)
  • Orchestrer des commandes qui dépendent les unes des autres
  • Réagir à des conditions (disque plein ? → alerte + nettoyage automatique)
  • Documenter tes procédures sous forme de code exécutable

💡 Tip DevOps : Un script Bash bien écrit, c’est de la documentation qui s’exécute. Quand un nouveau collègue arrive, il lit le script et comprend exactement ce qui se passe sur le serveur.


Comprendre l’anatomie d’un script

Chaque script Bash commence par un shebang — cette ligne magique qui dit au système quel interpréteur utiliser. Ensuite, c’est juste des commandes, comme dans ton terminal.

Voici un premier script complet qui crée un répertoire de travail et affiche un résumé de l’environnement :

#!/bin/bash
# setup-workspace.sh — Prépare un espace de travail projet

projet="mon-projet"
dossier="/tmp/${projet}"

mkdir -p "$dossier"/{src,logs,config}
echo "Workspace créé pour : $projet"
echo "Utilisateur : $(whoami)"
echo "Date : $(date '+%d/%m/%Y %H:%M')"
echo "Contenu :"
ls -la "$dossier"

Pour l’exécuter, rends-le exécutable puis lance-le :

chmod +x setup-workspace.sh
./setup-workspace.sh

⚠️ Attention : pas d’espace autour du = quand tu déclares une variable. nom="Dany" fonctionne, nom = "Dany" plante. C’est l’erreur numéro 1 des débutants en Bash.

Trois choses essentielles sur les variables :

  • Double quotes "$var" : la variable est interprétée → toujours les utiliser
  • Simple quotes '$var' : tout est littéral, rien n’est interprété
  • $(commande) : exécute une commande et insère le résultat

🧠 À retenir : mets toujours tes variables entre double quotes. "$fichier" gère les espaces dans les noms, $fichier non. Cette habitude t’évitera des heures de debug.


Les commandes essentielles du scripting

Conditions : prendre des décisions

Les conditions te permettent de faire réagir ton script à son environnement. Tu vérifies un fichier, tu testes un code retour, tu compares des valeurs.

Ce script vérifie si Nginx est installé et si sa config est valide avant de tenter un reload :

#!/bin/bash
# check-nginx.sh — Vérifie et recharge Nginx

config="/etc/nginx/nginx.conf"

if [ ! -f "$config" ]; then
    echo "❌ Nginx n'est pas installé"
    exit 1
elif nginx -t 2>/dev/null; then
    echo "✅ Config valide — rechargement"
    systemctl reload nginx
else
    echo "⚠️ Config invalide — pas de reload"
    exit 2
fi

Les opérateurs les plus utilisés : -f (fichier existe), -d (répertoire existe), -z (chaîne vide), -eq/-ne/-gt/-lt (comparaisons numériques), =/!= (comparaisons de chaînes).

Boucles : répéter intelligemment

La boucle for itère sur une liste, la boucle while tourne tant qu’une condition est vraie. Voici un script qui parcourt des serveurs et vérifie leur connectivité :

#!/bin/bash
# check-servers.sh — Ping une liste de serveurs

serveurs=("web-01" "web-02" "db-01" "cache-01")
down=0

for srv in "${serveurs[@]}"; do
    if ping -c 1 -W 2 "$srv" &>/dev/null; then
        echo "$srv — OK"
    else
        echo "$srv — DOWN"
        ((down++))
    fi
done

echo "---"
echo "Résultat : $down serveur(s) injoignable(s) sur ${#serveurs[@]}"

La boucle while est parfaite pour attendre qu’un service soit prêt :

#!/bin/bash
# wait-for-service.sh — Attend qu'une app réponde

url="http://localhost:8080/health"
max_attempts=30
attempt=0

while ! curl -sf "$url" > /dev/null 2>&1; do
    ((attempt++))
    if [ "$attempt" -ge "$max_attempts" ]; then
        echo "❌ Timeout après ${max_attempts} tentatives"
        exit 1
    fi
    echo "⏳ Tentative $attempt/$max_attempts..."
    sleep 2
done

echo "✅ Service disponible après $attempt tentative(s)"

Cas concret : script de backup en entreprise

🔥 Cas réel : tu gères 3 serveurs de production. Chaque nuit, tu dois sauvegarder les configs critiques, compresser le tout, et supprimer les archives de plus de 7 jours. Sans script, c’est 10 minutes de commandes manuelles. Avec un script, c’est un cron job qui tourne tout seul.

Ce script illustre un vrai workflow de backup qu’on retrouve en production :

#!/bin/bash
# backup-configs.sh — Sauvegarde quotidienne des configs

set -euo pipefail

BACKUP_DIR="/opt/backups"
DATE=$(date '+%Y-%m-%d_%H%M')
ARCHIVE="${BACKUP_DIR}/config-backup-${DATE}.tar.gz"
RETENTION=7

# Créer le répertoire si nécessaire
mkdir -p "$BACKUP_DIR"

# Archiver les configs critiques
tar czf "$ARCHIVE" \
    /etc/nginx/ \
    /etc/systemd/system/ \
    /etc/crontab \
    2>/dev/null

echo "✅ Backup créé : $ARCHIVE ($(du -h "$ARCHIVE" | cut -f1))"

# Nettoyage des anciennes sauvegardes
deleted=$(find "$BACKUP_DIR" -name "config-backup-*.tar.gz" -mtime +$RETENTION -delete -print | wc -l)
echo "🗑️  $deleted ancienne(s) sauvegarde(s) supprimée(s)"

💡 Tip DevOps : la ligne set -euo pipefail en haut du script est indispensable en production. -e stoppe le script à la première erreur, -u bloque sur les variables non définies, -o pipefail détecte les erreurs dans les pipes. Sans ça, ton script continue joyeusement même quand tout plante.


Pièges fréquents

Bash est puissant mais truffé de pièges. Voici ceux qui font perdre le plus de temps :

Variables non quotées — Le piège le plus courant. Si $fichier contient un espace, cat $fichier cherche deux fichiers différents. Toujours écrire cat "$fichier".

Espaces autour du =var="valeur" fonctionne, var = "valeur" lance une commande var avec les arguments = et valeur. Aucun message d’erreur clair.

[ ] vs [[ ]] — Les simples crochets [ ] sont POSIX mais fragiles. Les doubles [[ ]] gèrent mieux les espaces, supportent &&/|| et le pattern matching. Privilégie [[ ]] sauf si tu vises la portabilité POSIX stricte.

Oublier set -e — Sans cette option, un script continue après une erreur. Ta commande rm a échoué ? Pas grave, le script continue et écrase tes données. Toujours commencer par set -euo pipefail.

Le piège du cd — Si cd /un/dossier échoue silencieusement, toutes les commandes suivantes s’exécutent dans le mauvais répertoire. Écris cd /un/dossier || exit 1.

⚠️ Attention : ne fais jamais rm -rf $DOSSIER/ si la variable est vide — ça devient rm -rf /. Toujours protéger avec ${DOSSIER:?Variable non définie}.


Exercice pratique

Écris un script monitor.sh qui :

  1. Accepte un argument --threshold (pourcentage d’utilisation disque, défaut : 80)
  2. Vérifie l’espace disque de chaque partition avec df
  3. Affiche un warning pour chaque partition au-dessus du seuil
  4. Retourne un code de sortie 1 si au moins une partition dépasse le seuil, 0 sinon

Contraintes : utilise set -euo pipefail, quote toutes tes variables, et ajoute un message d’usage si l’argument est invalide.

Bonus : ajoute un flag --json qui sort le résultat au format JSON (utile pour un pipeline de monitoring).


À retenir

  • #!/bin/bash en première ligne, set -euo pipefail en deuxième — systématiquement
  • Variables : pas d’espace autour du =, toujours entre double quotes
  • Conditions : [[ ]] pour les tests, -f/-d/-e pour les fichiers, -eq/-gt pour les nombres
  • Boucles : for pour itérer sur des listes, while pour attendre ou lire ligne par ligne
  • $? contient le code retour de la dernière commande (0 = succès)
  • $(commande) capture la sortie d’une commande dans une variable

🧠 À retenir : Bash n’est pas un langage élégant. C’est un langage pragmatique. Apprends ses pièges, respecte ses conventions, et il te le rendra au centuple en temps gagné.

➡️ La suite : dans le prochain chapitre, on passe aux fonctions, aux pipes avancés, aux cron jobs et à des scripts DevOps du monde réel. On continue ! 🚀

🖥️ Pratique sur ton propre serveur

Pour suivre Apprendre Linux & Bash en conditions réelles, tu as besoin d'un VPS. DigitalOcean offre 200$ de crédit gratuit pour démarrer.

Obtenir 200$

Articles liés