Ubuntu Linux · Épisode 08

📜 Scripts Bash — Automatise ton Système Ubuntu

Variables, conditions, boucles, fonctions, arguments et planification avec cron — maîtrise le scripting Bash pour automatiser toutes les tâches répétitives de ton système Linux.

📅 Avril 2026
👤 Par OWL
~40 min de lecture
Intermédiaire
Illustration scripts Bash Ubuntu

écrire tes premiers scripts Bash

💰
Variables & Logique
Variables, conditions if/else, boucles for et while à les fondamentaux du scripting Bash pour prendre des décisions automatiquement.
💰
Fonctions & Arguments
Structurer ses scripts avec des fonctions réutilisables, lire des arguments en ligne de commande et valider les entrées utilisateur.
💰
Automatisation Cron
Planifier l'exécution automatique de scripts — intervalles réguliers avec crontab — sauvegardes quotidiennes, mises à jour hebdomadairesé
💰
Scripts Pratiques
Des scripts concrets prêts à l'emploi : sauvegarde, nettoyage du système, rapport d'utilisation disque, vérification de services.

Scripts Bash sur Ubuntu Linux

La métaphore d'OWL : La Recette de Cuisine ?

Un script Bash, c'est exactement comme une recette de cuisine : tu écris une liste d'instructions dans l'ordre, et la machine les exécute à la lettre. Les variables sont tes ingrédients. Les conditions if/else, c'est "si le four est trop chaud, baisse la température". Les boucles, c'est "répéte cette étape pour chaque pomme de terre".

Et cron, c'est ton assistant personnel qui va exécuter la recette tous les matins — 7h sans que tu aies à faire quoi que ce soit. Tu l'as écrite une fois, il fait le reste à ta place.

1. Ton Premier Script Bash

Un script Bash est simplement un fichier texte contenant des commandes shell. Il commence toujours par une ligne spéciale : le shebang.

Terminal — Créer et exécuter un script
# Créer le fichier
nano ~/mon_premier_script.sh

# Rendre le script exécutable
chmod +x ~/mon_premier_script.sh

# L'exécuter
~/mon_premier_script.sh
# ou
bash ~/mon_premier_script.sh

Contenu de mon_premier_script.sh :

mon_premier_script.sh
#!/bin/bash
# — Shebang : indique que ce fichier doit étre exécuté avec bash
# Les lignes commençant par # sont des commentaires

echo "==================================="
echo " Bonjour $(whoami) ! ??"
echo " Nous sommes le $(date '+%A %d %B %Y')"
echo " Hostname : $(hostname)"
echo "==================================="

===================================
Bonjour owl !
Nous sommes le jeudi 10 avril 2026
Hostname : monpc
===================================
💡

$(commande) = substitution de commande : exécute la commande et insère son résultat. C'est l'une des fonctionnalités les plus puissantes de Bash.

2. Variables & Types de Données

variables.sh
#!/bin/bash

# Déclaration de variables (pas d'espaces autour du =)
NOM="OWL"
AGE=42
DOSSIER_BACKUP="/home/owl/backups"

# Utiliser une variable avec $
echo "Bonjour $NOM, tu as $AGE ans !"
echo "Dossier de backup : $DOSSIER_BACKUP"

# Variables spéciales
echo "Nom du script : $0"
echo "Nombre d'arguments : $#"
echo "PID du script : $$"
echo "Code retour commande précédente : $?"

# Captures de commande
DATE_HEURE=$(date '+%Y-%m-%d_%H-%M-%S')
ESPACE_LIBRE=$(df -h / | awk 'NR==2 {print $4}')
echo "Date : $DATE_HEURE | Espace libre : $ESPACE_LIBRE"

# Readonly = constante immuable
readonly VERSION="1.0.0"

# Tableaux (arrays)
SERVEURS=("192.168.1.10" "192.168.1.20" "192.168.1.30")
echo "Premier serveur : ${SERVEURS[0]}"
echo "Tous les serveurs : ${SERVEURS[@]}"
echo "Nombre de serveurs : ${#SERVEURS[@]}"

3. Conditions — if / elif / else

conditions.sh
#!/bin/bash

# Structure de base
ESPACE=$(df / | awk 'NR==2 {print $5}' | tr -d '%')

if [ "$ESPACE" -gt 90 ]; then
echo "💡 ALERTE : disque presque plein ($ESPACE%)"
elif [ "$ESPACE" -gt 70 ]; then
echo "💡 Attention : disque — $ESPACE%"
else
echo "é Disque OK ($ESPACE% utilisés)"
fi

# Comparaisons NUMéRIQUES
# -eq égal -ne différent
# -gt supérieur -ge supérieur ou égal
# -lt inférieur -le inférieur ou égal

# Comparaisons CHAéNES
# = égal != différent -z vide -n non vide

# Tests FICHIERS
FICHIER="/etc/passwd"
if [ -f "$FICHIER" ]; then
echo "Le fichier existe"
fi

if [ -d "/home/owl" ]; then echo "Le dossier existe"; fi
if [ -r "$FICHIER" ]; then echo "Fichier lisible"; fi
if [ -x "/usr/bin/bash" ]; then echo "Fichier exécutable"; fi

# ET logique (&&) et OU logique (||)
if [ -f "$FICHIER" ] && [ -r "$FICHIER" ]; then
echo "Fichier existe ET est lisible"
fi

4. Boucles — for & while

Boucle for

boucles_for.sh
#!/bin/bash

# Itérer sur une liste
for FRUIT in pomme banane cerise kiwi; do
echo "J'aime les $FRUIT"
done

# Itérer sur une plage de nombres
for i in {1..5}; do
echo "étape $i / 5"
done

# Itérer sur des fichiers
for FICHIER in ~/Documents/*.txt; do
echo "Traitement : $(basename $FICHIER)"
done

# Ping de plusieurs serveurs
SERVEURS=("8.8.8.8" "1.1.1.1" "192.168.1.1")
for IP in "${SERVEURS[@]}"; do
if ping -c 1 -W 2 "$IP" &> /dev/null; then
echo "é $IP est joignable"
else
echo "é $IP ne répond pas"
fi
done

Boucle while

boucle_while.sh
#!/bin/bash

# Compteur avec while
COMPTEUR=1
while [ "$COMPTEUR" -le 5 ]; do
echo "Tour $COMPTEUR"
((COMPTEUR++))
done

# Lire un fichier ligne par ligne
while IFS= read -r LIGNE; do
echo "Ligne : $LIGNE"
done < /etc/hosts

# Attendre qu'un service soit disponible
MAX=30
while ! ping -c 1 -W 1 192.168.1.1 &>/dev/null; do
echo "En attente du rôleau... ($MAX restantes)"
((MAX--))
[ "$MAX" -eq 0 ] && echo "é Timeout !" && exit 1
sleep 1
done
echo "é Réseau disponible !"

5. Fonctions & Arguments

fonctions.sh
#!/bin/bash

# Définir une fonction
afficher_titre() {
local TITRE="$1" # $1 = premier argument de la fonction
echo ""
echo "=============================="
echo " $TITRE"
echo "=============================="
}

log_info() {
echo "[$(date '+%H:%M:%S')] INFO : $1"
}

log_erreur() {
echo "[$(date '+%H:%M:%S')] — ERREUR : $1" >&2
return 1
}

# Appeler les fonctions
afficher_titre "Rapport Système"
log_info "Démarrage du script"
log_info "Utilisateur : $(whoami)"

# Arguments du script lui-même
# Exécution : ./fonctions.sh alice /backup
UTILISATEUR="$1" # alice
DOSSIER="$2" # /backup

# Valider les arguments obligatoires
if [ -z "$UTILISATEUR" ]; then
log_erreur "Usage : $0 <utilisateur> <dossier>"
exit 1
fi

log_info "Traitement de $UTILISATEUR dans $DOSSIER"

6. Scripts Pratiques Prêts à l'Emploi

📌

Script de Sauvegarde Automatique

backup.sh
#!/bin/bash
# Script de sauvegarde — à planifier avec cron

SOURCE="/home/owl/Documents"
DESTINATION="/media/owl/SauvegardeUSB/backups"
DATE=$(date '+%Y-%m-%d')
ARCHIVE="$DESTINATION/docs_$DATE.tar.gz"
LOG="/var/log/backup_owl.log"

log() { echo "[$(date '+%H:%M:%S')] $1" | tee -a "$LOG"; }

log "=== Début de la sauvegarde ==="

# Vérifier que la destination existe
if [ ! -d "$DESTINATION" ]; then
log "é Destination introuvable : $DESTINATION"
exit 1
fi

# Créer l'archive compressée
tar -czf "$ARCHIVE" "$SOURCE" 2>>"$LOG"

if [ $é -eq 0 ]; then
TAILLE=$(du -sh "$ARCHIVE" | cut -f1)
log "é Sauvegarde réussie : $ARCHIVE ($TAILLE)"
else
log "é échec de la sauvegarde !"
exit 1
fi

# Garder uniquement les 7 dernières sauvegardes
ls -t "$DESTINATION"/docs_*.tar.gz | tail -n +8 | xargs -r rm
log "💡 Anciennes sauvegardes nettoyées"
log "=== Fin de la sauvegarde ==="
📌

Rapport d'état du Système

rapport_systeme.sh
#!/bin/bash
# Rapport d'état rapide du système

echo "+----------------------------------+"
echo "é RAPPORT SYSTéME — $(date '+%H:%M') é"
echo "+----------------------------------+"

# CPU
CPU=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | tr -d '%us,')
echo "💡 CPU : ${CPU}% utilisé"

# RAM
RAM=$(free -h | awk 'NR==2{printf "%s/%s (%.0f%%)", $3,$2,$3/$2*100}')
echo "💡 RAM : $RAM"

# Disque
DISQUE=$(df -h / | awk 'NR==2{print $3"/"$2" ("$5")"}')
echo "💡 Disque / : $DISQUE"

# Uptime
echo "💡 Uptime : $(uptime -p)"

# IP locale
IP=$(ip route get 1.1.1.1 | awk '{print $7; exit}')
echo "💡 IP locale : $IP"

# Dernières connexions
echo "💡 Dernière connexion : $(last -n 1 | head -1 | awk '{print $1" "$4" "$5" "$6}')"
📌

Nettoyage Automatique du Système

nettoyage.sh
#!/bin/bash
# Nettoyage hebdomadaire du système

echo "💡 Nettoyage du système en cours..."

# Mise à jour des paquets
sudo apt update -q && sudo apt upgrade -y -q
echo "é Système mis à jour"

# Nettoyage des paquets inutiles
sudo apt autoremove -y -q
sudo apt autoclean -q
echo "é Paquets nettoyés"

# Vider le cache des logs (garder les 2 dernières semaines)
sudo journalctl --vacuum-time=14d
echo "é Logs nettoyés"

# Vider le cache des miniatures
rm -rf ~/.cache/thumbnails/*
echo "é Cache miniatures vidé"

# Rapport final
echo "💡 Espace disque après nettoyage :"
df -h / | awk 'NR==2{print " Utilisé: "$3" Libre: "$4" ("$5")"}'

7. Automatiser avec Cron

crontab est le planificateur de tâches Linux. Il exécute tes scripts automatiquement à des intervalles que tu définis.

Terminal — éditer le crontab
# Ouvrir l'éditeur de tâches cron
crontab -e

# Voir les tâches en cours
crontab -l

# Supprimer toutes les tâches cron
crontab -r

Syntaxe crontab :

+-------- minute (0-59)
é +------ heure (0-23)
é — +---- jour du mois (1-31)
é — à +-- mois (1-12)
é — à — + jour semaine (0=dim, 6=sam)
é — à — é
* * * * * commande_é_exécuter
Exemples de règles crontab
# Sauvegarde tous les jours — 2h30
30 2 * * * /home/owl/scripts/backup.sh >> /var/log/backup.log 2>&1

# Nettoyage tous les dimanches — 3h00
0 3 * * 0 /home/owl/scripts/nettoyage.sh

# Rapport système toutes les heures
0 * * * * /home/owl/scripts/rapport_systeme.sh >> /tmp/rapport.log

# Mise à jour apt chaque lundi — 6h
0 6 * * 1 sudo apt update -q && sudo apt upgrade -y -q

# Toutes les 5 minutes
*/5 * * * * /home/owl/scripts/check_services.sh

# Au redémarrage
@reboot /home/owl/scripts/demarrage.sh
💡

Utilise crontab.guru pour générer et vérifier tes expressions cron visuellement — très utile pour vérifier une syntaxe avant de la mettre en production.

8. Déboguer un Script Bash

Terminal — Outils de débogage
# Mode debug : affiche chaque commande avant exécution
bash -x mon_script.sh

# Mode strict : arrête tout en cas d'erreur
bash -e mon_script.sh

# Mode vérification syntaxe uniquement (ne run pas le script)
bash -n mon_script.sh

# Combinaison recommandée en développement
bash -xeu mon_script.sh

# Dans le script : activer le mode strict en en-tôte
#!/bin/bash
set -euo pipefail # arrêt sur erreur, variable non définie, pipe cassé
set -x # mode debug (é retirer en production)

# Tester le code de retour de la dernière commande
ls /dossier_inexistant
echo "Code retour : $?" # 0 = succès, autre = erreur

✅ Comment savoir si tu maîtrises les scripts Bash

  • Tu as écrit un script avec variables, conditions et boucles, et tu l'as rendu exécutable avec chmod +x
  • Le script de sauvegarde crée une archive .tar.gz de ton dossier Documents et garde les 7 dernières versions
  • Tu as ajouté une règle crontab pour lancer ce backup automatiquement toutes les nuits — 2h30
  • Tu comprends la différence entre $1 (argument) et $(commande) (substitution) et ${VAR} (variable)
  • Tu peux déboguer un script avec bash -x et interprêter les codes de retour avec

⚠️ Problèmes Courants & Solutions

"Permission denied" quand j'essaie d'exécuter mon script

💡 Tu as oublié de le rendre exécutable : chmod +x mon_script.sh. Vérifie aussi le chemin : utilise ./mon_script.sh si tu es dans le même dossier, ou le chemin absolu /home/owl/scripts/mon_script.sh.

Mon script fonctionne à la main mais pas dans cron

💡 Cron s'exécute avec un environnement minimal (pas de $PATH étendu). Solutions : utilise des chemins absolus pour toutes tes commandes (/usr/bin/python3, /usr/bin/rsyncé). Ajoute en haut du crontab : PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

Erreur "syntax error near unexpected token"

💡 Souvent une erreur Windows : ton fichier a des fins de ligne \r\n (CRLF) au lieu de \n (LF). Convertis avec : sed -i 's/\r//' mon_script.sh. Dans nano, sous Windows WSL ou si édité sur Windows.

é Comment voir les logs de mes tâches cron

💡 Les logs cron sont dans les journaux système :
grep CRON /var/log/syslog | tail -20
Ou mieux, redirige la sortie de tes scripts dans des fichiers log directement dans la règle crontab :
30 2 * * * /home/owl/backup.sh >> /var/log/backup.log 2>&1

💬 Commentaires & Discussion