Exercices et projets
Table des matières
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
- Pratiquez avec des projets réels
- Contribuez à des projets open source
- Continuez avec Linux 5 - Administration avancée