Passer au contenu principal

Automatisation (Linux)

Écrire un script Bash

Bash est le shell par défaut sur Debian et le langage de script le plus répandu en administration système. Avant de se tourner vers des outils d'orchestration, maîtriser Bash permet d'automatiser des procédures fiables sur une machine.

Structure d'un script

#!/bin/bash
# Description : ce que fait le script
# Usage : ./mon-script.sh [arguments]

set -euo pipefail
# -e : quitter au premier code d'erreur
# -u : erreur sur variable non définie
# -o pipefail : propager les erreurs dans les pipes

Le shebang #!/bin/bash spécifie l'interpréteur. set -euo pipefail rend le script robuste par défaut : sans ces options, les erreurs passent silencieusement.

Variables

NOM="romain"                   # assignation (pas d'espace autour du =)
echo "Bonjour $NOM"            # interpolation
echo "Bonjour ${NOM}s"         # délimitation explicite
readonly CONFIG="/etc/app"     # variable en lecture seule

RESULTAT=$(commande)           # capturer la sortie d'une commande
CODE=$?                        # code de retour de la dernière commande

Tests et conditions

if [ -f /etc/nginx/nginx.conf ]; then
    echo "nginx configuré"
elif [ -f /etc/apache2/apache2.conf ]; then
    echo "apache configuré"
else
    echo "aucun serveur web trouvé"
fi

Tests courants

  • -f fichier : le fichier existe
  • -d répertoire : le répertoire existe
  • -z "$var" : la variable est vide
  • -n "$var" : la variable est non vide
  • "$a" = "$b" : égalité de chaînes
  • $a -eq $b : égalité numérique
  • $a -lt $b : inférieur strict (lt : less than)

Boucles

# For sur une liste
for serveur in web1 web2 web3; do
    echo "Ping de $serveur"
    ping -c 1 "$serveur"
done

# For sur des fichiers
for f in /etc/cron.d/*; do
    echo "Fichier : $f"
done

# While
compteur=0
while [ $compteur -lt 5 ]; do
    echo "Itération $compteur"
    ((compteur++))
done

Fonctions

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
}

verifier_service() {
    local service="$1"
    if systemctl is-active --quiet "$service"; then
        log "$service : OK"
        return 0
    else
        log "$service : KO"
        return 1
    fi
}

verifier_service nginx
verifier_service postgresql

Gestion des erreurs

# Nettoyer en cas d'erreur ou d'interruption
cleanup() {
    echo "Nettoyage..."
    rm -f /tmp/mon-script.lock
}
trap cleanup EXIT

# Quitter avec un message d'erreur
die() {
    echo "ERREUR : $*" >&2
    exit 1
}

[ "$(id -u)" -eq 0 ] || die "Ce script requiert les droits root"

En pratique

Trois règles pour des scripts maintenables : toujours set -euo pipefail en tête, toujours citer les variables entre guillemets ("$var" et non $var pour gérer les espaces et les valeurs vides), centraliser les logs via une fonction log(). Un script qui échoue silencieusement est plus dangereux qu'un script qui plante explicitement : l'option -e transforme les erreurs silencieuses en échecs visibles.