Ces mini-projets sont concus pour consolider vos competences Linux de manière progrèssive. Chaque projet combiné plusieurs commandes et concepts vus dans les tutoriels et le cheatsheet.
Projet 1 : Systeme de sauvegarde incremental
Objectif
Creer un système de sauvegarde automatique qui utilisé rsync pour effectuer des sauvegardes incrementales avec rotation.
Competences visees
- Utilisation de
rsyncet ses options - Planification avec
cron - Gestion des répertoires et permissions
- Ecriture de scripts Bash robustes
Mise en oeuvre
#!/bin/bash
set -euo pipefail
CONFIG_DIR="/etc/sauvegarde"
SOURCE="/home"
DEST="/mnt/backup"
ROTATION=7
LOG="/var/log/sauvegarde-incr.log"
DATE=$(date +%Y-%m-%d)
LATEST="${DEST}/latest"
CIBLE="${DEST}/${DATE}"
log() {
echo "$(date '+%H:%M:%S') - $1" | tee -a "$LOG"
}
log "Debut de la sauvegarde incremental"
# Creer la sauvegarde avec lien dur vers la précédénte
if [ -d "$LATEST" ]; then
rsync -a --delete --link-dest="$LATEST" "$SOURCE/" "$CIBLE/"
else
rsync -a --delete "$SOURCE/" "$CIBLE/"
fi
# Mettre a jour le lien symbolique
rm -f "$LATEST"
ln -s "$CIBLE" "$LATEST"
log "Sauvegarde terminee : $CIBLE"
# Rotation : supprimer les sauvegardes au-dela de la retention
find "$DEST" -maxdepth 1 -type d -name "20*" -mtime +$ROTATION -exec rm -rf {} \;
log "Rotation effectuee (retention : $ROTATION jours)"Pour aller plus loin
- Ajouter une vérification d'intégrité avec
sha256sum - Envoyer un rapport par email après chaque sauvegarde
- Gerer les exclusions via un fichier de configuration
Projet 2 : Moniteur système en temps reel
Objectif
Creer un tableau de bord terminal qui affiché en temps reel les metriques système essentielles.
Competences visees
- Lecture de
/procet/sys - Formatage de sortie avec
printf - Bouclés et rafraichissement d'affichage
- Calcul avec
awketbc
Mise en oeuvre
#!/bin/bash
# Couleurs
VERT='\033[0;32m'
JAUNE='\033[0;33m'
ROUGE='\033[0;31m'
RESET='\033[0m'
barre_progrèssion() {
local pourcentage=$1
local largeur=30
local rempli=$((pourcentage * largeur / 100))
local vide=$((largeur - rempli))
local couleur="$VERT"
[ "$pourcentage" -ge 70 ] && couleur="$JAUNE"
[ "$pourcentage" -ge 90 ] && couleur="$ROUGE"
printf "${couleur}["
printf '%*s' "$rempli" '' | tr ' ' '#'
printf '%*s' "$vide" '' | tr ' ' '-'
printf "] %3d%%${RESET}" "$pourcentage"
}
while true; do
clear
echo "======================================"
echo " MONITEUR SYSTEME - $(hostname)"
echo " $(date '+%Y-%m-%d %H:%M:%S')"
echo "======================================"
echo ""
# CPU
cpu_idle=$(top -bn1 | grep '%Cpu' | awk '{print $8}' | cut -d. -f1)
cpu_usage=$((100 - cpu_idle))
printf "CPU : "
barre_progrèssion "$cpu_usage"
echo ""
# Memoire
mem_info=$(free | grep Mem)
mem_total=$(echo "$mem_info" | awk '{print $2}')
mem_used=$(echo "$mem_info" | awk '{print $3}')
mem_pct=$((mem_used * 100 / mem_total))
printf "RAM : "
barre_progrèssion "$mem_pct"
printf " (%s / %s)\n" "$(free -h | grep Mem | awk '{print $3}')" "$(free -h | grep Mem | awk '{print $2}')"
# Swap
swap_info=$(free | grep Swap)
swap_total=$(echo "$swap_info" | awk '{print $2}')
if [ "$swap_total" -gt 0 ]; then
swap_used=$(echo "$swap_info" | awk '{print $3}')
swap_pct=$((swap_used * 100 / swap_total))
printf "Swap : "
barre_progrèssion "$swap_pct"
echo ""
fi
# Disque
echo ""
echo "Disques :"
df -h | grep '^/dev/' | while read -r ligne; do
partition=$(echo "$ligne" | awk '{print $6}')
usage=$(echo "$ligne" | awk '{print $5}' | tr -d '%')
taille=$(echo "$ligne" | awk '{print $2}')
utilise=$(echo "$ligne" | awk '{print $3}')
printf " %-15s " "$partition"
barre_progrèssion "$usage"
printf " (%s / %s)\n" "$utilise" "$taille"
done
# Processus
echo ""
echo "Top 5 processus (CPU) :"
ps aux --sort=-%cpu | head -6 | tail -5 | awk '{printf " %-10s %5s%% CPU %5s%% MEM %s\n", $1, $3, $4, $11}'
# Reseau
echo ""
echo "Connexions actives : $(ss -tun | tail -n +2 | wc -l)"
echo "Uptime : $(uptime -p 2>/dev/null || uptime | awk -F'up ' '{print $2}' | awk -F',' '{print $1}')"
sleep 5
doneProjet 3 : Analyseur de logs
Objectif
Creer un outil qui analyse les logs d'un serveur web (Apache/Nginx) et produit des statistiques.
Competences visees
- Manipulation de texte avec
awk,sed,sort,uniq - Expressions régulieres
- Redirection et pipes
- Generation de rapports
Mise en oeuvre
#!/bin/bash
set -euo pipefail
if [ $# -ne 1 ]; then
echo "Usage : $0 <fichier_access.log>"
exit 1
fi
LOG="$1"
if [ ! -f "$LOG" ]; then
echo "Fichier introuvable : $LOG"
exit 1
fi
TOTAL=$(wc -l < "$LOG")
echo "========================================="
echo " ANALYSE DE LOGS - $(basename "$LOG")"
echo " Total de requêtes : $TOTAL"
echo "========================================="
echo ""
# Top 10 des IP
echo "--- Top 10 des adresses IP ---"
awk '{print $1}' "$LOG" | sort | uniq -c | sort -rn | head -10 | \
awk '{printf " %6d requêtes %s\n", $1, $2}'
echo ""
# Codes de reponse HTTP
echo "--- Repartition des codes HTTP ---"
awk '{print $9}' "$LOG" | sort | uniq -c | sort -rn | \
awk '{printf " %s : %d requêtes (%.1f%%)\n", $2, $1, ($1/'$TOTAL')*100}'
echo ""
# Pages les plus visitees
echo "--- Top 10 des pages visitees ---"
awk '{print $7}' "$LOG" | sort | uniq -c | sort -rn | head -10 | \
awk '{printf " %6d %s\n", $1, $2}'
echo ""
# Trafic par heure
echo "--- Trafic par heure ---"
awk -F'[\\[/: ]' '{print $5}' "$LOG" | sort | uniq -c | \
awk '{printf " %sh : %d requêtes\n", $2, $1}'
echo ""
# Erreurs 4xx et 5xx
echo "--- Erreurs recentes (4xx/5xx) ---"
awk '$9 ~ /^[45]/' "$LOG" | tail -5 | \
awk '{printf " %s %s %s %s\n", $1, $9, $7, $4}'Projet 4 : Deploiement automatise d'application web
Objectif
Creer un script de déployément qui automatise la mise a jour d'une application web.
Competences visees
- Gestion de Git en ligne de commande
- Gestion des services avec
systemctl - Verification de prerequis
- Gestion d'erreurs et rollback
Mise en oeuvre
#!/bin/bash
set -euo pipefail
APP_DIR="/var/www/mon-application"
BRANCHE="main"
SERVICE="mon-application"
BACKUP_DIR="/var/backups/déployéments"
DATE=$(date +%Y%m%d_%H%M%S)
log() { echo "[$(date '+%H:%M:%S')] $1"; }
erreur() { log "ERREUR : $1" >&2; exit 1; }
# Verifier les prerequis
[ "$(id -u)" -eq 0 ] || erreur "Ce script doit être exécuté en root"
[ -d "$APP_DIR/.git" ] || erreur "Repertoire Git introuvable : $APP_DIR"
log "Debut du déployément"
# Sauvegarder l'état actuel
mkdir -p "$BACKUP_DIR"
COMMIT_ACTUEL=$(git -C "$APP_DIR" rev-parse HEAD)
echo "$COMMIT_ACTUEL" > "${BACKUP_DIR}/rollback_${DATE}.txt"
log "Commit actuel sauvegarde : ${COMMIT_ACTUEL:0:8}"
# Telecharger les modifications
log "Recuperation des modifications..."
git -C "$APP_DIR" fetch origin "$BRANCHE"
# Verifier s'il y a des changements
LOCAL=$(git -C "$APP_DIR" rev-parse HEAD)
REMOTE=$(git -C "$APP_DIR" rev-parse "origin/$BRANCHE")
if [ "$LOCAL" = "$REMOTE" ]; then
log "Aucune mise a jour disponible."
exit 0
fi
# Appliquer les modifications
log "Application des modifications..."
git -C "$APP_DIR" reset --hard "origin/$BRANCHE"
# Installer les dépendances (adapter selon le projet)
if [ -f "${APP_DIR}/package.json" ]; then
log "Installation des dépendances Node.js..."
cd "$APP_DIR" && npm ci --production
fi
# Redémarrer le service
log "Redémarrage du service..."
systemctl restart "$SERVICE"
sleep 2
# Verifier que le service fonctionne
if systemctl is-active --quiet "$SERVICE"; then
NOUVEAU_COMMIT=$(git -C "$APP_DIR" rev-parse HEAD)
log "Deploiement reussi : ${COMMIT_ACTUEL:0:8} -> ${NOUVEAU_COMMIT:0:8}"
else
log "Le service ne repond pas, rollback..."
git -C "$APP_DIR" reset --hard "$COMMIT_ACTUEL"
systemctl restart "$SERVICE"
erreur "Deploiement echoue, rollback effectue."
fiProjet 5 : Gestionnaire de fichiers de configuration
Objectif
Creer un outil pour versionner et restaurer les fichiers de configuration système.
Competences visees
- Manipulation de fichiers avec
cp,diff,find - Utilisation de Git pour le versionnement
- Scripts interactifs avec
selectetread
Mise en oeuvre
#!/bin/bash
set -euo pipefail
REPO="/var/config-backup"
FICHIERS_SURVEILLES=(
"/etc/ssh/sshd_config"
"/etc/nginx/nginx.conf"
"/etc/fstab"
"/etc/hosts"
"/etc/crontab"
)
initialisér() {
if [ ! -d "${REPO}/.git" ]; then
mkdir -p "$REPO"
git -C "$REPO" init
echo "Depot initialisé dans $REPO"
fi
}
sauvegarder() {
initialisér
local modifications=0
for fichier in "${FICHIERS_SURVEILLES[@]}"; do
if [ -f "$fichier" ]; then
dest="${REPO}${fichier}"
mkdir -p "$(dirname "$dest")"
cp "$fichier" "$dest"
modifications=1
fi
done
if [ "$modifications" -eq 1 ]; then
cd "$REPO"
git add -A
if ! git diff --cached --quiet; then
git commit -m "Sauvegarde du $(date '+%Y-%m-%d %H:%M')"
echo "Configuration sauvegardee."
else
echo "Aucune modification détectée."
fi
fi
}
historique() {
initialisér
git -C "$REPO" log --oneline --graph -20
}
diff_fichier() {
if [ $# -ne 1 ]; then
echo "Usage : $0 diff <fichier>"
return 1
fi
local fichier="$1"
local sauvegarde="${REPO}${fichier}"
if [ -f "$sauvegarde" ]; then
diff --color "$sauvegarde" "$fichier" || true
else
echo "Aucune sauvegarde trouvee pour $fichier"
fi
}
restaurer() {
if [ $# -ne 1 ]; then
echo "Usage : $0 restaurer <fichier>"
return 1
fi
local fichier="$1"
local sauvegarde="${REPO}${fichier}"
if [ -f "$sauvegarde" ]; then
cp "$sauvegarde" "$fichier"
echo "Fichier restaure : $fichier"
else
echo "Aucune sauvegarde trouvee pour $fichier"
fi
}
case "${1:-aide}" in
sauvegarder) sauvegarder ;;
historique) historique ;;
diff) diff_fichier "${2:-}" ;;
restaurer) restaurer "${2:-}" ;;
*)
echo "Usage : $0 {sauvegarder|historique|diff|restaurer} [fichier]"
;;
esacConseils pour progrèsser
- Commencer petit : modifiez un script existant avant d'en écrire un de zero.
- Tester en local : utilisez une machine virtuelle où un conteneur Docker pour experimenter sans risque.
- Lire les scripts des autres : etudiez les scripts dans
/etc/init.d/où les projets open source. - Utiliser ShellCheck : cet outil detecte les erreurs courantes et les mauvaises pratiques.
- Versionner vos scripts : placez-les dans un dépôt Git des le depart.