Aller au contenu principal

Exercices et projets


Table des matières

  1. Quiz récapitulatif
  2. Exercices guidés
  3. Mini-projets
  4. Projet final
  5. Ressources supplémentaires


1 - Quiz récapitulatif

Variables et expansion

Q1. Comment assigner une valeur par défaut si la variable est vide ?

Réponse

${var:-default} utilise default si var est vide ou non définie. ${var:=default} fait la même chose ET assigne default à var.

Q2. Comment obtenir le nom de fichier sans le chemin ?

Réponse

${path##*/} ou basename "$path"

Q3. Comment obtenir l'extension d'un fichier ?

Réponse

${filename##*.}

Conditions et boucles

Q4. Quelle est la différence entre [ ] et [[ ]] ?

Réponse

[[ ]] est spécifique à Bash avec :

  • Pattern matching (== avec *, ?)
  • Regex (=~)
  • Pas besoin d'échapper <, >
  • && et || intégrés

Q5. Comment lire un fichier ligne par ligne en préservant les espaces ?

Réponse
while IFS= read -r line; do
echo "$line"
done < fichier.txt

Fonctions et erreurs

Q6. Comment retourner une valeur depuis une fonction ?

Réponse

Via echo (capture avec $()), ou return N pour un code (0-255).

Q7. Que fait set -euo pipefail ?

Réponse
  • -e : Exit à la première erreur
  • -u : Erreur si variable non définie
  • -o pipefail : Erreur si n'importe quelle commande du pipe échoue

Regex et texte

Q8. Comment extraire toutes les adresses email d'un fichier ?

Réponse
grep -oE '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' fichier.txt

Q9. Comment remplacer tous les espaces par des underscores ?

Réponse

tr ' ' '_' ou sed 's/ /_/g'

Q10. Comment calculer la somme d'une colonne avec awk ?

Réponse

awk '{sum += $3} END {print sum}' fichier.txt

🔝 Retour à la table des matières



2 - Exercices guidés

Exercice 1 : Validateur de configuration

Créez un script qui valide un fichier de configuration.

Spécifications :

  • Vérifie que le fichier existe et est lisible
  • Vérifie que les clés obligatoires sont présentes
  • Affiche les erreurs de validation
Solution
#!/bin/bash
set -euo pipefail

readonly CONFIG_FILE="${1:?Usage: $0 <config_file>}"
readonly REQUIRED_KEYS=("host" "port" "database")

validate_config() {
local file="$1"
local errors=0

# Vérifier existence
if [ ! -f "$file" ]; then
echo "ERREUR: Fichier non trouvé: $file"
return 1
fi

# Vérifier clés obligatoires
for key in "${REQUIRED_KEYS[@]}"; do
if ! grep -qE "^${key}=" "$file"; then
echo "ERREUR: Clé manquante: $key"
((errors++))
fi
done

# Vérifier format des valeurs
while IFS='=' read -r key value; do
[[ "$key" =~ ^#.*$ ]] && continue # Ignorer commentaires
[[ -z "$key" ]] && continue # Ignorer lignes vides

if [ -z "$value" ]; then
echo "WARN: Valeur vide pour: $key"
fi
done < "$file"

if [ $errors -gt 0 ]; then
echo "Validation échouée avec $errors erreur(s)"
return 1
fi

echo "Configuration valide!"
return 0
}

validate_config "$CONFIG_FILE"

Exercice 2 : Moniteur de processus

Créez un script qui surveille un processus et le redémarre s'il tombe.

Solution
#!/bin/bash
set -uo pipefail

readonly PROCESS_NAME="${1:?Usage: $0 <process_name>}"
readonly CHECK_INTERVAL=5
readonly MAX_RESTARTS=3
readonly LOG_FILE="/var/log/monitor_${PROCESS_NAME}.log"

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

is_running() {
pgrep -x "$PROCESS_NAME" > /dev/null
}

restart_process() {
log "Tentative de redémarrage de $PROCESS_NAME"
systemctl restart "$PROCESS_NAME" 2>/dev/null || {
log "Échec du redémarrage via systemctl"
return 1
}
return 0
}

main() {
local restarts=0

log "Démarrage de la surveillance de $PROCESS_NAME"

while true; do
if ! is_running; then
log "ALERT: $PROCESS_NAME n'est pas en cours d'exécution!"

if [ $restarts -ge $MAX_RESTARTS ]; then
log "CRITICAL: Max restarts atteint ($MAX_RESTARTS)"
exit 1
fi

if restart_process; then
((restarts++))
log "Redémarrage réussi ($restarts/$MAX_RESTARTS)"
fi
else
restarts=0 # Reset si le process est OK
fi

sleep $CHECK_INTERVAL
done
}

main

Exercice 3 : Analyseur de logs

Créez un script qui analyse un fichier access.log et génère un rapport.

Solution
#!/bin/bash
set -euo pipefail

readonly LOG_FILE="${1:-/var/log/nginx/access.log}"

analyze_log() {
local log="$1"

[ -f "$log" ] || { echo "Fichier non trouvé: $log"; exit 1; }

echo "=== Analyse de $log ==="
echo ""

echo "--- Statistiques générales ---"
local total=$(wc -l < "$log")
echo "Total requêtes: $total"

echo ""
echo "--- Top 10 IPs ---"
awk '{print $1}' "$log" | sort | uniq -c | sort -rn | head -10

echo ""
echo "--- Codes HTTP ---"
awk '{print $9}' "$log" | sort | uniq -c | sort -rn

echo ""
echo "--- Top 10 URLs ---"
awk '{print $7}' "$log" | sort | uniq -c | sort -rn | head -10

echo ""
echo "--- Erreurs 5xx ---"
local errors=$(awk '$9 ~ /^5/ {count++} END {print count+0}' "$log")
echo "Total erreurs 5xx: $errors"

if [ "$errors" -gt 0 ]; then
echo "Détail:"
awk '$9 ~ /^5/ {print $1, $7, $9}' "$log" | head -10
fi
}

analyze_log "$LOG_FILE"

🔝 Retour à la table des matières



3 - Mini-projets

Projet 1 : Système de backup automatisé

Créez un système de backup complet avec :

  • Backup de fichiers et base de données
  • Rotation des backups (garder N derniers)
  • Notification en cas d'erreur
  • Restauration

Projet 2 : Outil de déploiement

Créez un outil de déploiement avec :

  • Backup avant déploiement
  • Déploiement depuis Git
  • Health check après déploiement
  • Rollback automatique si échec

Projet 3 : Dashboard monitoring

Créez un script qui génère un rapport HTML avec :

  • Utilisation CPU/RAM/Disque
  • État des services
  • Dernières erreurs des logs
  • Graphiques (avec gnuplot ou similar)

🔝 Retour à la table des matières



4 - Projet final : Outil DevOps complet

Spécifications

Créez un outil en ligne de commande devops-tool avec les fonctionnalités :

devops-tool <commande> [options]

Commandes:
deploy Déployer l'application
backup Sauvegarder les données
restore Restaurer depuis un backup
status Afficher l'état du système
logs Analyser les logs
clean Nettoyer les fichiers temporaires

Structure suggérée

devops-tool/
├── bin/
│ └── devops-tool # Point d'entrée
├── lib/
│ ├── common.sh # Fonctions communes
│ ├── deploy.sh # Module déploiement
│ ├── backup.sh # Module backup
│ ├── monitor.sh # Module monitoring
│ └── logs.sh # Module logs
├── conf/
│ └── config.sh # Configuration
└── README.md

Point d'entrée

#!/bin/bash
# bin/devops-tool

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LIB_DIR="$SCRIPT_DIR/../lib"

# Charger les modules
source "$LIB_DIR/common.sh"
source "$SCRIPT_DIR/../conf/config.sh"

usage() {
cat << EOF
Usage: $(basename "$0") <commande> [options]

Commandes:
deploy Déployer l'application
backup Sauvegarder les données
restore Restaurer un backup
status État du système
logs Analyser les logs
clean Nettoyer

Options:
-h, --help Afficher cette aide
-v Mode verbeux
EOF
}

main() {
[ $# -eq 0 ] && { usage; exit 1; }

local command="$1"
shift

case "$command" in
deploy)
source "$LIB_DIR/deploy.sh"
do_deploy "$@"
;;
backup)
source "$LIB_DIR/backup.sh"
do_backup "$@"
;;
restore)
source "$LIB_DIR/backup.sh"
do_restore "$@"
;;
status)
source "$LIB_DIR/monitor.sh"
show_status "$@"
;;
logs)
source "$LIB_DIR/logs.sh"
analyze_logs "$@"
;;
clean)
do_cleanup "$@"
;;
-h|--help)
usage
exit 0
;;
*)
echo "Commande inconnue: $command"
usage
exit 1
;;
esac
}

main "$@"

🔝 Retour à la table des matières



5 - Ressources supplémentaires

Documentation

Outils

  • ShellCheck : Linter pour Bash
  • bashdb : Debugger
  • shfmt : Formateur de code

Bonnes pratiques

Pratique

🔝 Retour à la table des matières



Félicitations !

Vous avez terminé le cours Linux 4 - Scripting Bash ! 🎉

Vous maîtrisez maintenant :

  • ✅ Variables, conditions, boucles
  • ✅ Fonctions et modularité
  • ✅ Manipulation de texte (sed, awk, regex)
  • ✅ Gestion des erreurs et debugging
  • ✅ Bonnes pratiques et sécurité
  • ✅ Scripts DevOps professionnels

Prochaines étapes

  1. Pratiquez avec des projets réels
  2. Contribuez à des projets open source
  3. Continuez avec Linux 5 - Administration avancée

← Retour à la table des matières du cours