Bash — Scripts et Automatisation
Un script Bash est un fichier texte exécutable contenant une séquence de commandes shell. L’automatisation de tâches répétitives (sauvegardes, déploiements, maintenance) est le principal cas d’usage.
Structure d’un Script§
#!/usr/bin/env bash
# Shebang : indique l'interpréteur à utiliser
set -euo pipefail
# -e : quitter si une commande échoue
# -u : erreur si variable non définie
# -o pipefail : le pipe échoue si une commande du pipe échoue
# Variables
NOM="monde"
echo "Bonjour, $NOM"
Permissions d’exécution :
chmod +x mon_script.sh
./mon_script.sh
Variables et Paramètres§
# Variables
MA_VAR="valeur"
echo "$MA_VAR" # Bonne pratique : toujours entre guillemets
echo "${MA_VAR}_suffixe" # Délimiter le nom avec {}
# Variables spéciales
echo "$0" # Nom du script
echo "$1" # Premier argument
echo "$@" # Tous les arguments (séparés)
echo "$#" # Nombre d'arguments
echo "$?" # Code de retour de la dernière commande
echo "$$" # PID du shell courant
# Substitution de commande
DATE=$(date +%Y-%m-%d)
NB_LIGNES=$(wc -l < fichier.txt)
# Valeur par défaut
NOM="${1:-Martin}" # Si $1 vide, utiliser "Martin"
Conditions§
# if / elif / else
if [[ -f "/etc/passwd" ]]; then
echo "Fichier existe"
elif [[ -d "/etc/passwd" ]]; then
echo "C'est un dossier"
else
echo "N'existe pas"
fi
# Tests courants
[[ -f fichier ]] # Fichier régulier existe
[[ -d dossier ]] # Dossier existe
[[ -z "$var" ]] # Variable vide
[[ -n "$var" ]] # Variable non vide
[[ "$a" == "$b" ]] # Égalité de chaînes
[[ "$a" -eq "$b" ]] # Égalité numérique
[[ "$a" -gt "$b" ]] # a > b (numérique)
# Opérateurs logiques
[[ condition1 && condition2 ]]
[[ condition1 || condition2 ]]
Boucles§
# for sur liste
for fruit in pomme banane cerise; do
echo "$fruit"
done
# for C-style
for ((i=0; i<10; i++)); do
echo "$i"
done
# for sur fichiers
for fichier in /var/log/*.log; do
echo "Traitement : $fichier"
done
# while
compteur=0
while [[ $compteur -lt 5 ]]; do
echo "Compteur : $compteur"
((compteur++))
done
# Lire un fichier ligne par ligne
while IFS= read -r ligne; do
echo "$ligne"
done < fichier.txt
Fonctions§
# Définition
saluer() {
local prenom="$1" # local : variable locale à la fonction
local message="Bonjour, $prenom"
echo "$message"
return 0 # 0 = succès, 1-255 = erreur
}
# Appel
saluer "Martin"
resultat=$(saluer "Alice") # Capturer la sortie
Gestion des Erreurs§
# Quitter avec message d'erreur
erreur() {
echo "ERREUR : $1" >&2 # >&2 : rediriger vers stderr
exit 1
}
# Vérifier code de retour
commande_risquee || erreur "La commande a échoué"
# Trap : exécuter une action sur signal ou erreur
nettoyer() {
rm -f /tmp/fichier_temp_$$
echo "Nettoyage effectué"
}
trap nettoyer EXIT # Exécuter nettoyer à la sortie
trap 'erreur "Ligne $LINENO"' ERR # Afficher la ligne d'erreur
Exemples Pratiques§
Sauvegarde automatique
#!/usr/bin/env bash
set -euo pipefail
SOURCE="/home/user/documents"
DEST="/backup"
DATE=$(date +%Y-%m-%d_%H-%M)
ARCHIVE="$DEST/backup_$DATE.tar.gz"
mkdir -p "$DEST"
tar -czf "$ARCHIVE" "$SOURCE"
echo "Sauvegarde créée : $ARCHIVE"
# Supprimer sauvegardes de plus de 30 jours
find "$DEST" -name "backup_*.tar.gz" -mtime +30 -delete
Surveillance d’un service
#!/usr/bin/env bash
SERVICE="nginx"
if ! systemctl is-active --quiet "$SERVICE"; then
echo "$(date) : $SERVICE arrêté, redémarrage..." >> /var/log/watchdog.log
systemctl restart "$SERVICE"
fi
Traitement de fichiers CSV
#!/usr/bin/env bash
# Traiter chaque ligne d'un CSV (skip header)
tail -n +2 données.csv | while IFS=',' read -r nom age ville; do
echo "Nom: $nom | Age: $age | Ville: $ville"
done
Bonnes Pratiques§
| Pratique | Raison |
|---|---|
#!/usr/bin/env bash | Portable (chemin de bash variable selon OS) |
set -euo pipefail | Fail fast — évite les erreurs silencieuses |
"$var" avec guillemets | Évite le word splitting et la glob expansion |
local dans les fonctions | Évite la pollution des variables globales |
[[ ]] plutôt que [ ] | Plus robuste, supporte &&, ` |
| Noms en MAJUSCULES pour constantes | Convention lisibilité |
mktemp pour fichiers temporaires | Évite les conflits de noms |
| Commentaires au-dessus des blocs | Documenter l’intention, pas l’évidence |
—The Gardener