Créer des modèles de scripts Bash réutilisables pour plus d'efficacité
Construisez des modèles de scripts Bash réutilisables avec mode strict, texte d'utilisation, journalisation, nettoyage et analyse sécurisée des arguments avec getopts.
Créer des modèles de scripts Bash réutilisables pour plus d'efficacité
Les modèles de scripts Bash réutilisables vous aident à ne pas réécrire les mêmes vérifications de sécurité à chaque fois que vous automatisez une tâche. Un bon modèle offre à votre script une gestion stricte des erreurs, une journalisation prévisible, une aide à l'utilisation, une analyse des arguments et des hooks de nettoyage avant d'ajouter la logique spécifique au projet.
L'objectif n'est pas un framework énorme. C'est un petit point de départ qui rend les scripts courants cohérents et plus faciles à déboguer.
Pourquoi utiliser des modèles de scripts ?
Les modèles sont utiles lorsque votre équipe écrit de nombreux petits scripts pour les sauvegardes, les déploiements, les rapports, le nettoyage des journaux ou le déplacement de données. Sans modèle, chaque script a tendance à gérer les erreurs, les options et la journalisation un peu différemment.
Un modèle réutilisable vous offre :
- Un mode strict cohérent et des habitudes de citation.
- Une fonction
usagestandard. - Un endroit pour les aides à la journalisation.
- Un hook de nettoyage pour les fichiers temporaires et les verrous.
- Une analyse prévisible de la ligne de commande avec
getopts.
Les éléments de base du modèle
Commencez par Bash lui-même, puis activez le comportement strict :
#!/usr/bin/env bash
set -euo pipefail
set -e quitte en cas d'échec de nombreuses commandes non gérées, set -u traite les variables non définies comme des erreurs, et set -o pipefail capture les échecs à l'intérieur des pipelines. Vous avez toujours besoin de vérifications explicites pour les échecs que vous attendez, mais le mode strict attrape de nombreuses erreurs accidentelles.
Ajoutez un nom de script et un court bloc d'utilisation :
readonly SCRIPT_NAME="$(basename "$0")"
usage() {
cat <<USAGE
Usage : $SCRIPT_NAME [-v] [-o output_dir] input_file
Options :
-v Activer la journalisation verbeuse
-o output_dir Écrire la sortie dans ce répertoire
-h Afficher ce message d'aide
USAGE
}
Utilisez de petites aides à la journalisation au lieu d'appels echo dispersés :
log_info() {
[[ "$VERBOSE" -eq 1 ]] && printf '[INFO] %s\n' "$1"
}
die() {
printf '[ERREUR] %s\n' "$1" >&2
exit 1
}
Si le script crée des fichiers temporaires ou des fichiers de verrouillage, ajoutez une fonction de nettoyage tôt :
cleanup() {
# Supprimer les fichiers temporaires ou libérer les verrous ici.
:
}
trap cleanup EXIT
Analyse sécurisée des arguments avec getopts
La plupart des modèles réutilisables ont besoin de drapeaux. Le getopts intégré de Bash est suffisant pour les options courtes comme -v et -o output_dir.
VERBOSE=0
OUTPUT_DIR="."
while getopts ":vo:h" opt; do
case "$opt" in
v) VERBOSE=1 ;;
o) OUTPUT_DIR=$OPTARG ;;
h) usage; exit 0 ;;
:) die "L'option -$OPTARG nécessite un argument" ;;
\?) die "Option inconnue : -$OPTARG" ;;
esac
done
shift "$((OPTIND - 1))"
INPUT_FILE=${1:-}
[[ -n "$INPUT_FILE" ]] || { usage >&2; exit 1; }
[[ -f "$INPUT_FILE" ]] || die "Fichier d'entrée introuvable : $INPUT_FILE"
Le : au début de ":vo:h" permet à votre script de gérer lui-même les arguments d'option manquants. Après l'analyse, shift "$((OPTIND - 1))" supprime les options analysées afin que les arguments positionnels soient plus faciles à lire.
Un modèle compact que vous pouvez réutiliser
Voici un point de départ pratique pour les petits scripts d'opérations :
#!/usr/bin/env bash
set -euo pipefail
readonly SCRIPT_NAME="$(basename "$0")"
VERBOSE=0
OUTPUT_DIR="."
usage() {
cat <<USAGE
Usage : $SCRIPT_NAME [-v] [-o output_dir] input_file
USAGE
}
log_info() {
[[ "$VERBOSE" -eq 1 ]] && printf '[INFO] %s\n' "$1"
}
die() {
printf '[ERREUR] %s\n' "$1" >&2
exit 1
}
cleanup() {
:
}
trap cleanup EXIT
while getopts ":vo:h" opt; do
case "$opt" in
v) VERBOSE=1 ;;
o) OUTPUT_DIR=$OPTARG ;;
h) usage; exit 0 ;;
:) die "L'option -$OPTARG nécessite un argument" ;;
\?) die "Option inconnue : -$OPTARG" ;;
esac
done
shift "$((OPTIND - 1))"
INPUT_FILE=${1:-}
[[ -n "$INPUT_FILE" ]] || { usage >&2; exit 1; }
[[ -f "$INPUT_FILE" ]] || die "Fichier d'entrée introuvable : $INPUT_FILE"
mkdir -p "$OUTPUT_DIR"
log_info "Traitement de $INPUT_FILE"
# Ajoutez votre logique de script ici.
Gardez le modèle court. N'ajoutez des fonctions partagées que lorsque plusieurs scripts en ont vraiment besoin. Un modèle doit supprimer le travail de configuration répété, pas donner l'impression que chaque script est un framework.