Skip to content

Bash Scripting : Automatise Tout !

🎯 Objectifs de ce cours

À la fin, tu seras capable de :

Créer un script Bash : De ta première ligne à l'exécution
Utiliser les variables : Stocker et réutiliser des valeurs
Passer des paramètres : Rendre tes scripts flexibles
Ajouter des conditions : If/then/else pour la logique
Boucler : For et while pour répéter
Automatiser des tâches DevOps : Déploiements, backups, monitoring
Déboguer : Comprendre et corriger les erreurs


❌ Le Problème : Les Tâches Répétitives

Imagine ça :

Tous les jours, tu dois :
  1. Chercher les logs d'erreurs → grep "ERROR"
  2. Les archiver → tar -czf
  3. Les envoyer → scp vers un serveur
  4. Nettoyer l'espace → rm old files
  5. Notifier l'équipe → mail

⏰ 30 minutes à la main, CHAQUE JOUR
❌ Erreurs possibles
❌ Impossible à faire à 18h

Avec un script ?

./daily-cleanup.sh
# 1 seconde. Fini. Tous les jours via cron.
❌ Manuel ✅ Script
30 minutes par jour 2 secondes
Erreurs humaines Cohérent à 100%
Impossible à 18h Fonctionne 24/7
Pas versionnée Code source contrôlé

Les scripts c'est le fondement du DevOps. C'est INDISPENSABLE.


🧱 Qu'est-Ce Qu'Un Script ?

Un script, c'est simple :

Fichier texte contenant des commandes
         ↓
Bash les exécute une par une
         ↓
Les résultats sortent à l'écran (ou se sauvegardent)

Exemple :

#!/usr/bin/env bash
echo "Bonjour le monde !"
date
pwd
ls -la

C'est juste des commandes que tu tapes normalement, mais dans un fichier.

Le #!/usr/bin/env bash ? C'est le "shebang". Il dit "utilise Bash pour exécuter ce fichier".


📝 Créer Ton Premier Script

Étape 1 : Créer le fichier

nano hello.sh

Ça ouvre un éditeur vide. Tu tapes :

#!/usr/bin/env bash
echo "Hello DevOps !"

Étape 2 : Sauvegarder

  • Appuie sur Ctrl+X
  • Tape Y (oui)
  • Appuie sur Entrée

Étape 3 : Rendre exécutable

chmod +x hello.sh

Le +x = "ajoute la permission d'exécution".

Étape 4 : Lancer

./hello.sh

Résultat :

Hello DevOps !

Voilà ! Tu viens de créer un script. 🎉


🧮 Les Variables : La Mémoire De Ton Script

Une variable, c'est une boîte où tu stockes une valeur.

Créer Une Variable

#!/usr/bin/env bash

# Variables
user="tartempion"
server="192.168.1.100"
port=22

echo "Connexion à $server comme $user"

Règles importantes :
- Pas d'espace autour du = : user="deploy" (pas user = "deploy")
- Les $ permettent d'accéder à la valeur
- Mets des guillemets autour des strings

Utiliser Une Variable

#!/usr/bin/env bash

app_name="MyApp"
version="1.2.3"

echo "Application: $app_name"
echo "Version: $version"
echo "Déploiement de $app_name v$version"

Résultat :

Application: MyApp
Version: 1.2.3
Déploiement de MyApp v1.2.3

Variables Spéciales Utiles

$0      # Nom du script
$1      # 1er paramètre
$2      # 2e paramètre
$#      # Nombre total de paramètres
$?      # Code retour de la dernière commande (0=succès)
$$      # Le PID du script (son identifiant)

Exemples :

#!/usr/bin/env bash
echo "Je suis: $0"
echo "1er param: $1"
echo "J'ai $# paramètres"
ls /nonexistent
echo "Le ls a retourné: $?"

🎯 Les Paramètres : Passe Des Valeurs Au Script

Au lieu de coder les valeurs en dur, tu peux les passer quand tu lances le script.

Script Simple Avec Paramètres

#!/usr/bin/env bash

if [ $# -eq 0 ]; then
  echo "Usage: $0 <server> <user>"
  exit 1
fi

server=$1
user=$2

echo "Connecte à $server comme $user"
ssh $user@$server

Utilisation

./connect.sh 192.168.1.100 tartempion
# Résultat: Connecte à 192.168.1.100 en tant que tartempion

Cas d'usage DevOps :

# deploy.sh
#!/usr/bin/env bash
app=$1
version=$2
environment=$3

echo "Déploiement de $app version $version en $environment"
# ... rest of deployment logic
./deploy.sh myapp 1.2.3 production

🔀 Les Conditions : Prendre Des Décisions

Les conditions permettent de dire "SI ceci, ALORS fais cela".

Syntaxe de Base

if [ condition ]; then
  # Actions si vraie
else
  # Actions si fausse
fi

Comparaisons Courantes

# Chaînes
[ "$user" = "admin" ]           # Égal
[ "$user" != "guest" ]          # Pas égal
[ -z "$var" ]                   # Variable vide
[ -n "$var" ]                   # Variable non-vide

# Nombres
[ $count -eq 0 ]                # Égal
[ $count -ne 0 ]                # Pas égal
[ $count -gt 5 ]                # Plus grand que
[ $count -lt 10 ]               # Plus petit que
[ $count -ge 5 ]                # Supérieur ou égal
[ $count -le 10 ]               # Inférieur ou égal

# Fichiers
[ -f "$file" ]                  # Fichier existe
[ -d "$dir" ]                   # Dossier existe
[ -r "$file" ]                  # Fichier lisible
[ -w "$file" ]                  # Fichier writable
[ -x "$file" ]                  # Fichier exécutable

# Logique
[ "$a" = "true" ] && [ "$b" = "true" ]   # ET
[ "$a" = "true" ] || [ "$b" = "true" ]   # OU

Exemple : Vérifier Un Utilisateur

#!/usr/bin/env bash

user=$1

if [ "$user" = "admin" ]; then
  echo "Accès complet"
  sudo commands
elif [ "$user" = "tartempion" ]; then
  echo "Accès déploiement"
  deploy commands
else
  echo "Accès refusé"
  exit 1
fi

Exemple : Vérifier Si Un Fichier Existe

#!/usr/bin/env bash

config_file="/etc/myapp/config.yaml"

if [ -f "$config_file" ]; then
  echo "Config trouvée, lancement..."
  source "$config_file"
else
  echo "Config manquante ! Aborté."
  exit 1
fi

🔁 Les Boucles : Répéter Des Actions

Les boucles permettent de faire la même action plusieurs fois.

Boucle FOR : Itérer Sur Une Liste

#!/usr/bin/env bash

for server in web1 web2 web3; do
  echo "Ping vers $server"
  ping -c 1 $server
done

Itérer sur des fichiers :

#!/usr/bin/env bash

for file in /var/log/*.log; do
  echo "Archivant $file"
  gzip "$file"
done

Itérer sur une plage de nombres :

#!/usr/bin/env bash

for i in {1..10}; do
  echo "Itération $i"
done

Avec des pas :

for i in {0..100..10}; do
  echo $i  # 0, 10, 20, ..., 100
done

Boucle WHILE : Répéter Tant Qu'Une Condition Est Vraie

#!/usr/bin/env bash

counter=1
max=5

while [ $counter -le $max ]; do
  echo "Compteur: $counter"
  counter=$((counter + 1))
done

Lire un fichier ligne par ligne :

#!/usr/bin/env bash

while IFS= read -r line; do
  echo "Ligne: $line"
done < data.txt

Attendre qu'une condition soit vraie :

#!/usr/bin/env bash

while ! ping -c 1 192.168.1.100 > /dev/null 2>&1; do
  echo "Serveur pas accessible. Attente..."
  sleep 5
done

echo "Serveur accessible !"

📚 Cas D'Usage DevOps Réels

1️⃣ Déploiement Simple

#!/usr/bin/env bash

APP=$1
VERSION=$2

echo "📦 Déploiement de $APP v$VERSION"

# Télécharger
wget https://releases.example.com/$APP-$VERSION.tar.gz

# Extraire
tar -xzf $APP-$VERSION.tar.gz -C /opt/

# Redémarrer le service
systemctl restart $APP

echo "✅ Déploiement terminé"
./deploy.sh myapp 1.2.3

2️⃣ Backup Automatique

#!/usr/bin/env bash

SOURCE="/var/www/app"
BACKUP_DIR="/backups"
DATE=$(date +%Y-%m-%d)

echo "💾 Backup de $SOURCE"

tar -czf $BACKUP_DIR/app-$DATE.tar.gz $SOURCE

# Garder seulement les 7 derniers backups
find $BACKUP_DIR -name "app-*.tar.gz" -mtime +7 -delete

echo "✅ Backup fait: app-$DATE.tar.gz"

3️⃣ Monitoring Basique

#!/usr/bin/env bash

ALERT_EMAIL="devops@example.com"

# Vérifier l'espace disque
disk_usage=$(df / | awk 'NR==2 {print $5}' | sed 's/%//')

if [ $disk_usage -gt 80 ]; then
  echo "⚠️ ALERTE: Disque à $disk_usage%" | mail -s "Alert" $ALERT_EMAIL
fi

# Vérifier CPU
cpu_load=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}')
# (continuer le traitement)

4️⃣ Log Cleanup

#!/usr/bin/env bash

LOG_DIR="/var/log"
DAYS=30

echo "🧹 Nettoyage des logs (> $DAYS jours)"

# Supprimer les vieux logs
find $LOG_DIR -name "*.log" -mtime +$DAYS -delete

# Compresser les logs récents
for file in $LOG_DIR/*.log; do
  [ -f "$file" ] && gzip -9 "$file"
done

echo "✅ Logs nettoyés"

5️⃣ Configuration Management

#!/usr/bin/env bash

ENV=$1

case $ENV in
  production)
    echo "Configuration PROD"
    export DB_HOST="prod-db.internal"
    export DB_USER="prod_user"
    ;;
  staging)
    echo "Configuration STAGING"
    export DB_HOST="staging-db.internal"
    export DB_USER="staging_user"
    ;;
  *)
    echo "Environnement inconnu: $ENV"
    exit 1
    ;;
esac

echo "Déploiement en $ENV avec $DB_HOST"

🧬 Combiner Tout Ça : Un Script Complet

#!/usr/bin/env bash

# Variables
APP="myapp"
VERSION=$1
SERVERS=("web1" "web2" "web3")
BACKUP_DIR="/backups"

# Vérifier les paramètres
if [ -z "$VERSION" ]; then
  echo "Usage: $0 <version>"
  exit 1
fi

# Créer backup
echo "📦 Backup..."
tar -czf $BACKUP_DIR/$APP-$(date +%s).tar.gz /opt/$APP

# Déployer sur chaque serveur
for server in "${SERVERS[@]}"; do
  echo "🚀 Déploiement vers $server..."

  if ping -c 1 $server > /dev/null; then
    ssh deploy@$server "
      cd /opt/$APP
      git pull origin main
      ./build.sh
      systemctl restart $APP
    "
    echo "✅ $server OK"
  else
    echo "❌ $server injoignable"
  fi
done

echo "🎉 Déploiement complet de v$VERSION"

⚠️ Les Pièges Courants

❌ Erreur ✅ Solution
user=admin (pas de guillemets) user="admin" ou user='admin'
if [$user = "admin"] (pas d'espaces après [ et avant ]) if [ "$user" = "admin" ] (espaces APRÈS [ et AVANT ] obligatoires)
Oublier le #!/bin/bash Toujours commencer par le shebang
chmod 777 (trop de droits) chmod +x script.sh (juste exécution)
Pas de vérification de paramètres Toujours vérifier $# ou si les fichiers existent

🧠 Debugging : Quand Ça Casse

Voir Ce Qui Se Passe

# Exécuter avec traces
bash -x script.sh

# Ou ajouter au début du script
set -x    # Active le verbose
set -v    # Montre les commandes lues

Vérifier Les Erreurs

./script.sh
echo $?      # 0 = succès, autre = erreur

Ajouter Des Logs

#!/usr/bin/env bash

LOG_FILE="/var/log/script.log"

log() {
  echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE
}

log "Démarrage du script"
log "Erreur: fichier non trouvé"

🧾 Cheat Sheet : Les Constructions Essentielles

But Syntaxe Exemple
Variable var="value" app="myapp"
Utiliser $var echo $app
Paramètre 1 $1 server=$1
Nombre de params $# if [ $# -eq 0 ]
Code retour $? echo $?
Calcul $((a + b)) x=$((5 + 3))
String vide [ -z "$var" ] if [ -z "$user" ]
String non-vide [ -n "$var" ] if [ -n "$msg" ]
Fichier existe [ -f "$file" ] if [ -f "/etc/config" ]
Dossier existe [ -d "$dir" ] if [ -d "/var/log" ]
Nombre égal [ $a -eq $b ] if [ $count -eq 0 ]
Nombre > [ $a -gt $b ] if [ $age -gt 18 ]
Boucle for for i in list; do ... done for f in *.log
Boucle while while [ cond ]; do ... done while [ $x -lt 10 ]
If/else if [ cond ]; then ... else ... fi Condition
Sorties echo "text" echo "Hello"

🎯 Checklist : Tu Maîtrises Bash Quand...

  • ✅ Tu crées un script sans Googler
  • ✅ Tu utilises des variables correctement
  • ✅ Tu passes des paramètres à un script
  • ✅ Tu écris des conditions if/else
  • ✅ Tu boucles sur des listes ou des fichiers
  • ✅ Tu vérifies les erreurs avec $?
  • ✅ Tu logs tes actions dans un fichier
  • ✅ Tu debugges avec bash -x
  • ✅ Tu planifies tes scripts avec cron

🚀 Tips Pro

1️⃣ Toujours Vérifier Les Paramètres

#!/usr/bin/env bash

if [ $# -lt 2 ]; then
  echo "Usage: $0 <server> <action>"
  exit 1
fi

2️⃣ Utiliser set -e Pour Arrêter En Cas D'Erreur

#!/usr/bin/env bash
set -e  # Arrête si une commande échoue

cd /opt/app
npm install
npm build
systemctl restart app

# Si une ligne échoue, le script s'arrête

3️⃣ Créer Une Fonction Réutilisable

#!/usr/bin/env bash

log() {
  echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1"
}

log "Démarrage"
log "Milieu"
log "Fin"

4️⃣ Utiliser Des Chemins Absolus

# ❌ Mauvais
cd /tmp
./script.sh

# ✅ Bon
/opt/scripts/script.sh

5️⃣ Planifier Avec Cron

# Éditer crontab
crontab -e

# Exécuter chaque jour à 2h du matin
0 2 * * * /opt/scripts/daily-backup.sh

🚀 Prochaines Étapes

Maintenant que tu maîtrises Bash :

  • Apprendre les fonctions avancées : Modulariser tes scripts
  • Utiliser sed/awk/grep : Traiter les données dans tes scripts
  • Créer des pipelines : Combiner plusieurs scripts
  • Implémenter l'error handling : Gérer les erreurs proprement
  • Versionner tes scripts : Git pour tes automatisations
  • Utiliser Ansible : Orchestration multi-serveurs

Bash est le fondement du DevOps. Tout ce que tu fais en production, tu le fais via des scripts Bash (direct ou via Ansible/Terraform qui utilisent Bash en arrière-plan).

Les trois piliers : Terminal + sed/awk + Scripting = tu es un vrai DevOps ! 💪

Bienvenue dans l'automatisation totale ! 🚀