RousselTMLEARNING

Artículo · Administración Linux: del descubrimiento a la maestría

Scripts Bash robustos

Este artículo está disponible en francés.

1. Les bases #

Un script, c'est une suite de commandes.

Squelette #

Structure d'un script Bash
Toujours la même organisation : on retrouve vite ce que l'on cherche.
#!/usr/bin/env bash
# backup-etc.sh : archive /etc dans /var/backups
set -euo pipefail

readonly DEST=/var/backups
readonly STAMP=$(date +%F_%H%M)

main() {
    mkdir -p "$DEST"
    tar -czf "$DEST/etc_$STAMP.tar.gz" /etc
    echo "Archive créée : $DEST/etc_$STAMP.tar.gz"
}

main "$@"
chmod +x backup-etc.sh && sudo ./backup-etc.sh
bash -x backup-etc.sh   # exécuter en traçant chaque commande
OptionEffet
set -earrête le script à la première commande en échec
set -uerreur si une variable n'est pas définie
set -o pipefailun pipe échoue si une de ses commandes échoue

Variables et guillemets #

nom="web 01"
echo "$nom"          # guillemets doubles : la variable est développée, les espaces préservés
echo '$nom'          # guillemets simples : texte littéral
fichiers=$(ls /etc)  # substitution de commande
echo "${nom:-defaut}"     # valeur par défaut
echo "${#nom}"            # longueur
echo "${fichier%.log}.gz" # remplacer un suffixe
(( total = 3 * 7 )) ; echo "$total" 
Bonne Pratique : Mettez toujours les variables entre guillemets doubles ("$var") : sans eux, un nom de fichier avec un espace devient deux arguments.

2. Contrôle de flux #

Conditions, boucles, fonctions.

Conditions #

if [[ -f /etc/nginx/nginx.conf ]]; then echo "nginx configuré"; fi
if ! systemctl is-active --quiet nginx; then
    systemctl restart nginx
fi
[[ $EUID -eq 0 ]] || { echo "À lancer en root" >&2; exit 1; }
[[ $usage -gt 90 && $env == prod ]] && alerte
case "$1" in
    start|stop) systemctl "$1" app ;;
    *) echo "Usage : $0 {start|stop}" >&2; exit 2 ;;
esac

Tests utiles #

TestVrai si
-f / -d / -efichier / répertoire / existe
-r -w -xlisible, modifiable, exécutable
-z / -nchaîne vide / non vide
-eq -ne -lt -gtcomparaisons numériques
== !=, =~comparaison de chaînes, expression régulière

Boucles #

for host in web01 web02 db01; do
    ssh "$host" uptime
done
for f in /var/log/app/*.log; do gzip "$f"; done
while read -r user shell; do
    echo "$user utilise $shell"
done < <(awk -F: '$3>=1000 {print $1, $7}' /etc/passwd)
for i in {1..5}; do curl -sf http://localhost:8080/health && break; sleep 2; done

Fonctions et codes de retour #

log() { echo "$(date '+%F %T') [$1] ${*:2}" | tee -a /var/log/monscript.log; }
check_disk() {
    local usage
    usage=$(df --output=pcent / | tail -1 | tr -dc '0-9')
    (( usage < ${1:-90} ))      # code retour 0 si OK
}
if ! check_disk 85; then log WARN "disque racine presque plein"; fi
echo $?   # code de retour de la dernière commande (0 = succès)

Un script doit renvoyer 0 en cas de succès et un code non nul en cas d'erreur : cron, systemd, Ansible et les pipelines CI s'en servent pour détecter l'échec.

Codes de retour
Un script qui renvoie toujours 0 rend ses échecs invisibles.

3. Rendre un script robuste #

Ce qui distingue un script de production.

trap, verrou et arguments #

#!/usr/bin/env bash
set -euo pipefail
TMP=$(mktemp -d)
trap 'rm -rf "$TMP"' EXIT                       # nettoyage, même en cas d'erreur
trap 'echo "Erreur ligne $LINENO" >&2' ERR

exec 9>/run/lock/backup.lock
flock -n 9 || { echo "Déjà en cours" >&2; exit 1; }   # empêcher deux exécutions

DRY_RUN=0 ; RETENTION=7
while getopts "nr:h" opt; do
    case $opt in
        n) DRY_RUN=1 ;;
        r) RETENTION=$OPTARG ;;
        h|*) echo "Usage : $0 [-n] [-r jours]"; exit 0 ;;
    esac
done

Qualité #

ShellCheck
ShellCheck repère les guillemets manquants et les commandes dangereuses.
  • Analysez chaque script avec ShellCheck (aussi en CI).
  • Rendez les scripts idempotents : les relancer ne doit rien casser (mkdir -p, tester avant de créer).
  • Proposez un mode simulation (-n) pour les actions destructrices.
  • Journalisez avec horodatage, sur stderr pour les erreurs.
  • Versionnez les scripts dans Git ; au-delà de ~200 lignes ou de logique complexe, passez à Python ou à Ansible.

Planifier #

Un script de maintenance se lance avec un timer systemd (journalisation, rattrapage, dépendances) ou cron. Testez-le d'abord avec l'environnement minimal : env -i /bin/bash --noprofile --norc ./script.sh.

📄 Scripts Bash pour l'administrateur : écrire des scripts robustes →

Mi seguimiento

  • ⏱ Duración estimada : ≈ 11 min

Inicia sesión para seguir tu progreso y tomar notas. Iniciar sesión

✉️ Hacer una pregunta

Artículos recomendados

Buenas Prácticas de Kubernetes

Mejores prácticas para asegurar y optimizar los despliegues de Kubernetes.