📜 Scripting Bash — Automatisation système
| Formation | BTS SIO option SISR — IRIS Mediaschool |
|---|---|
| Bloc | B2 — Administration Systèmes & Réseaux |
| Module | M2.2 — Administration Linux |
| Prérequis | Maîtrise du shell Linux (C2.2.1) |
🎯 Objectifs
- Écrire et exécuter des scripts Bash
- Maîtriser les variables, les conditions et les boucles
- Créer des fonctions réutilisables
- Manipuler du texte avec grep, sed, awk et les expressions régulières
- Appliquer les bonnes pratiques de scripting
- Automatiser des tâches d'administration courantes
📖 Shebang et exécution de scripts
Un script Bash est un fichier texte contenant une suite de commandes. La première ligne, le shebang, indique l'interpréteur à utiliser :
#!/bin/bash
# Mon premier script
echo "Bonjour, monde !"
Pour rendre un script exécutable et le lancer :
# Rendre exécutable
chmod +x mon_script.sh
# Exécuter
./mon_script.sh
# Ou explicitement avec bash
bash mon_script.sh
Utilisez #!/usr/bin/env bash plutôt que #!/bin/bash pour une meilleure portabilité entre systèmes, car le chemin de bash peut varier.
📖 Variables, types et expansion
En Bash, les variables ne sont pas typées — tout est traité comme une chaîne de caractères :
#!/bin/bash
# Affectation (pas d'espace autour du =)
nom="Alice"
age=25
repertoire="/var/log"
# Utilisation avec $
echo "Bonjour $nom, vous avez $age ans"
# Expansion avec accolades (recommandé)
echo "Fichier : ${nom}_backup.tar.gz"
# Substitution de commande
date_actuelle=$(date +%Y-%m-%d)
nb_fichiers=$(ls /tmp | wc -l)
echo "Date : $date_actuelle — Fichiers dans /tmp : $nb_fichiers"
# Variables en lecture seule
readonly VERSION="1.0"
# Variables de calcul
resultat=$((10 + 5))
echo "Résultat : $resultat"
Pas d'espace autour du = lors de l'affectation ! nom = "Alice" provoquera une erreur (Bash interprète nom comme une commande).
📖 Entrée utilisateur et arguments
#!/bin/bash
# Lire une entrée utilisateur
read -p "Entrez votre nom : " nom
echo "Bonjour, $nom !"
# Lire un mot de passe (sans affichage)
read -sp "Mot de passe : " mdp
echo ""
# Arguments du script
echo "Nom du script : $0"
echo "Premier argument : $1"
echo "Deuxième argument : $2"
echo "Tous les arguments : $@"
echo "Nombre d'arguments : $#"
echo "Code retour dernière commande : $?"
| Variable | Description |
|---|---|
$0 | Nom du script |
$1, $2, … | Arguments positionnels |
$@ | Tous les arguments (chacun entre guillemets) |
$* | Tous les arguments (comme une seule chaîne) |
$# | Nombre d'arguments |
$? | Code retour de la dernière commande (0 = succès) |
$$ | PID du script en cours |
📖 Structures conditionnelles
#!/bin/bash
# Structure if/elif/else
if [[ $# -eq 0 ]]; then
echo "Aucun argument fourni"
exit 1
elif [[ $1 == "start" ]]; then
echo "Démarrage du service..."
elif [[ $1 == "stop" ]]; then
echo "Arrêt du service..."
else
echo "Usage : $0 {start|stop}"
exit 1
fi
# Opérateur ternaire avec && et ||
[[ -f "/etc/hosts" ]] && echo "Le fichier existe" || echo "Le fichier n'existe pas"
Comparaisons
| Type | Opérateur | Description |
|---|---|---|
| Numérique | -eq | Égal |
-ne | Différent | |
-lt, -le | Inférieur (strict / ou égal) | |
-gt, -ge | Supérieur (strict / ou égal) | |
| Chaîne | == | Égale |
!= | Différente | |
-z, -n | Vide / Non vide | |
| Fichier | -f | Est un fichier régulier |
-d | Est un répertoire | |
-e | Existe | |
-r | Est lisible | |
-w | Est modifiable | |
-x | Est exécutable |
Préférez [[ ]] à [ ] (test). La syntaxe double crochet est spécifique à Bash et offre des fonctionnalités supplémentaires : pas de word splitting, support des expressions régulières avec =~, et opérateurs && / || à l'intérieur.
📖 Boucles
#!/bin/bash
# Boucle for classique
for fichier in /var/log/*.log; do
echo "Traitement de $fichier"
wc -l "$fichier"
done
# Boucle for avec séquence
for i in {1..10}; do
echo "Itération $i"
done
# Boucle for de style C
for ((i = 0; i < 5; i++)); do
echo "Index : $i"
done
# Boucle while
compteur=0
while [[ $compteur -lt 5 ]]; do
echo "Compteur : $compteur"
((compteur++))
done
# Boucle while pour lire un fichier ligne par ligne
while IFS= read -r ligne; do
echo "Ligne : $ligne"
done < /etc/hostname
# Boucle until (s'exécute tant que la condition est fausse)
until ping -c 1 -W 1 8.8.8.8 &>/dev/null; do
echo "En attente de connexion réseau..."
sleep 2
done
echo "Connexion établie !"
📖 Fonctions et portée des variables
#!/bin/bash
# Déclaration d'une fonction
verifier_service() {
local service_name="$1" # Variable locale
if systemctl is-active --quiet "$service_name"; then
echo "[OK] $service_name est actif"
return 0
else
echo "[ERREUR] $service_name est inactif"
return 1
fi
}
# Appel de la fonction
verifier_service "nginx"
verifier_service "ssh"
# Récupérer le code retour
if verifier_service "apache2"; then
echo "Apache fonctionne correctement"
fi
Utilisez local pour déclarer des variables locales dans les fonctions. Sans local, les variables sont globales et peuvent interférer avec le reste du script.
📖 Manipulation de texte
| Outil | Usage | Exemple |
|---|---|---|
grep | Rechercher un motif | grep -i "error" /var/log/syslog |
sed | Remplacer du texte | sed 's/ancien/nouveau/g' fichier |
awk | Traiter des colonnes | awk '{print $1, $3}' fichier |
cut | Extraire des champs | cut -d: -f1 /etc/passwd |
sort | Trier | sort -rn fichier |
uniq | Dédoublonner (après tri) | sort fichier | uniq -c |
wc | Compter lignes/mots/octets | wc -l fichier |
# Exemple combiné : top 5 des utilisateurs avec le plus de processus
ps aux | awk '{print $1}' | sort | uniq -c | sort -rn | head -5
# Remplacer une IP dans un fichier de configuration
sed -i 's/192\.168\.1\.10/10.0.0.50/g' /etc/myapp/config.conf
# Extraire les noms d'utilisateurs depuis /etc/passwd
awk -F: '{print $1, $3, $7}' /etc/passwd | column -t
📖 Expressions régulières
Les expressions régulières (regex) permettent de définir des motifs de recherche complexes :
| Motif | Signification | Exemple |
|---|---|---|
. | N'importe quel caractère | a.c → abc, aXc |
* | 0 ou plusieurs fois l'élément précédent | ab*c → ac, abc, abbc |
+ | 1 ou plusieurs fois (regex étendue) | ab+c → abc, abbc |
? | 0 ou 1 fois (regex étendue) | ab?c → ac, abc |
^ | Début de ligne | ^root |
$ | Fin de ligne | bash$ |
[abc] | Un caractère parmi a, b ou c | [0-9]+ |
\d | Un chiffre (équivalent [0-9]) | — |
# grep avec regex basique
grep '^root' /etc/passwd
# grep avec regex étendue (-E)
grep -E '^[a-z]+:[x*]:0:' /etc/passwd
# Valider un format d'adresse IP
if [[ "$ip" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
echo "Format IP valide"
fi
📖 Exemples de scripts utiles
Backup automatisé
#!/bin/bash
set -euo pipefail
BACKUP_DIR="/backup"
SOURCE="/var/www"
DATE=$(date +%Y-%m-%d_%H-%M)
ARCHIVE="${BACKUP_DIR}/www_${DATE}.tar.gz"
mkdir -p "$BACKUP_DIR"
tar -czf "$ARCHIVE" "$SOURCE"
# Supprimer les backups de plus de 30 jours
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +30 -delete
echo "[$(date)] Backup terminé : $ARCHIVE"
Surveillance de disque
#!/bin/bash
set -euo pipefail
SEUIL=80
df -h --output=pcent,target | tail -n +2 | while read -r usage mount; do
pourcent=${usage%\%}
if [[ $pourcent -ge $SEUIL ]]; then
echo "ALERTE : $mount utilise ${pourcent}% de l'espace disque"
# Envoyer un mail ou une notification
fi
done
Gestion d'utilisateurs en masse
#!/bin/bash
set -euo pipefail
# Fichier CSV : prenom,nom,groupe
FICHIER_USERS="utilisateurs.csv"
while IFS=',' read -r prenom nom groupe; do
login="${prenom,,}.${nom,,}" # Minuscules
if ! id "$login" &>/dev/null; then
useradd -m -s /bin/bash -G "$groupe" "$login"
echo "${login}:ChangeMe123!" | chpasswd
echo "[CRÉÉ] $login (groupe: $groupe)"
else
echo "[EXISTE] $login"
fi
done < "$FICHIER_USERS"
📖 Bonnes pratiques
- Toujours commencer par
set -euo pipefail:
#!/bin/bash
set -euo pipefail
# -e : arrêter le script à la première erreur
# -u : erreur si une variable non définie est utilisée
# -o pipefail : considérer les erreurs dans les pipes
- Commenter le code : expliquer le « pourquoi », pas le « quoi »
- Utiliser des guillemets autour des variables :
"$var"pour éviter le word splitting - Logging : enregistrer les actions dans un fichier de log
- Vérifier les prérequis : tester l'existence des commandes et fichiers nécessaires
- Utiliser des fonctions pour structurer et réutiliser le code
- Tester avec
shellcheck: outil d'analyse statique pour détecter les erreurs
# Installer et utiliser shellcheck
sudo apt install shellcheck
shellcheck mon_script.sh
📝 QCM — Testez vos connaissances
- Quelle ligne commence un script Bash ?
- Comment rendre un script exécutable ?
- Quelle syntaxe utilise-t-on pour une condition en Bash ?
- Comment parcourir une liste d'éléments en Bash ?
- Que représente $1 dans un script Bash ?
- Comment capturer la sortie d'une commande dans une variable ?
📝 Afficher les corrections
- #!/bin/bash (shebang) — Le shebang #!/bin/bash indique au système d'utiliser Bash pour interpréter le script.
- chmod +x script.sh — La commande chmod +x ajoute le droit d'exécution au fichier script.
- if [ condition ]; then ... fi — La structure if/then/elif/else/fi permet les tests conditionnels en Bash.
- for item in liste; do ... done — La boucle for itère sur une liste de valeurs, un fichier ou le résultat d'une commande.
- Le premier argument passé au script — Les variables $1, $2, $3... sont les arguments positionnels, $0 est le nom du script, $# le nombre d'arguments.
- variable=$(commande) — La substitution de commande $() exécute la commande et stocke sa sortie dans la variable.
Le scripting Bash est la clé de l'automatisation sous Linux. Maîtrisez les variables, conditions, boucles et fonctions. Utilisez grep, sed et awk pour manipuler du texte. Appliquez toujours set -euo pipefail et vérifiez vos scripts avec shellcheck.
