Que fait Fonctionnalités et améliorations de Bash 5.1 ?
Publiée en décembre 2020, Bash 5.1 a introduit plusieurs fonctionnalités et améliorations notables pour les scripts shell modernes.
Nouvelles variables shell
EPOCHSECONDS et EPOCHREALTIME
Deux nouvelles variables spéciales pour accéder à l'heure actuelle :
# Obtenir l'horodatage Unix actuel en secondes
echo "Horodatage actuel : ${EPOCHSECONDS}"
# Obtenir l'horodatage Unix actuel avec une précision microseconde
echo "Horodatage haute précision : ${EPOCHREALTIME}"
# Exemple pratique : Benchmarking simple
debut="${EPOCHREALTIME}"
# ... une opération ...
sleep 0.5
fin="${EPOCHREALTIME}"
duree=$(awk "BEGIN {print ${fin} - ${debut}}")
echo "L'opération a pris ${duree} secondes"
# Exemple : Journalisation avec horodatages précis
log_message() {
printf '[%s.%06d] %s\n' \
"$(date -d "@${EPOCHSECONDS}" '+%Y-%m-%d %H:%M:%S')" \
"${EPOCHREALTIME#*.}" \
"$*"
}
log_message "Démarrage du processus"
Cas d'utilisation :
- Mesure précise des performances
- Horodatages haute résolution pour la journalisation
- Éviter les appels externes à la commande
date - Chronométrage à précision microseconde dans les scripts
Variable SRANDOM
Nombres aléatoires cryptographiquement forts :
# Générer un nombre aléatoire sécurisé (si disponible)
if [[ -n "${SRANDOM}" ]]; then
alea_securise="${SRANDOM}"
echo "Aléatoire sécurisé : ${alea_securise}"
else
echo "SRANDOM non disponible (nécessite getrandom/getentropy)"
fi
# Exemple pratique : Générer un fichier temporaire avec un nom aléatoire sécurisé
fichier_temp="/tmp/secure_${SRANDOM}_${EPOCHSECONDS}.tmp"
Remarque : SRANDOM nécessite le support système des appels système getrandom() ou getentropy().
Syntaxe de redirection améliorée
Redirection {varname}
Assigner un descripteur de fichier à une variable pour une meilleure gestion des handles de fichiers :
# Ouvrir un descripteur de fichier et le stocker dans une variable
exec {fd}< input.txt
tandis que IFS= read -r -u "${fd}" ligne; faire
echo "Lu : ${ligne}"
fait
exec {fd}<&- # Fermer le descripteur de fichier
# Exemple pratique : Gestion de multiples descripteurs
exec {entree_fd}< data.txt
exec {sortie_fd}> results.txt
exec {erreur_fd}> errors.txt
process_data() {
tandis que IFS= read -r -u "${entree_fd}" ligne; faire
if validate_ligne "${ligne}"; then
echo "Traitée : ${ligne}" >&"${sortie_fd}"
else
echo "Erreur : ${ligne}" >&"${erreur_fd}"
fi
fait
}
process_data
exec {entree_fd}<&-
exec {sortie_fd}>&-
exec {erreur_fd}>&-
Avantages :
- Descripteurs de fichier nommés plutôt que des nombres magiques
- Allocation automatique des FD évitant les conflits
- Code plus lisible et maintenable
- Suivi plus facile des descripteurs de fichier ouverts
Améliorations des tableaux
Gestion améliorée des tableaux associatifs
Meilleur support pour les opérations complexes sur les tableaux :
# Déclarer un tableau associatif avec typeset
declare -A config=(
[hote]="localhost"
[port]="8080"
[debug]="true"
)
# Expansion de tableau améliorée
for cle in "${!config[@]}"; do
printf '%s=%s\n' "${cle}" "${config[${cle}]}"
fait
# Exemple pratique : Analyseur de configuration
analyser_config() {
declare -gA app_config
local ligne cle valeur
tandis que IFS='=' read -r cle valeur; faire
[[ "${cle}" =~ ^[[:space:]]*# ]] && continuer # Ignorer les commentaires
[[ -z "${cle}" ]] && continuer # Ignorer les lignes vides
# Supprimer les espaces blancs
cle="${cle#"${cle%%[![:space:]]*}"}"
cle="${cle%"${cle##*[![:space:]]}"}"
valeur="${valeur#"${valeur%%[![:space:]]*}"}"
valeur="${valeur%"${valeur##*[![:space:]]}"}"
app_config["${cle}"]="${valeur}"
fait < config.ini
}
Support des tableaux multidimensionnels
Gestion améliorée des structures de tableau imbriquées.
Intégration de Readline 8.1
Interaction améliorée avec le texte et la ligne de commande :
Liaisons de touches et historique
# Configurer readline dans ~/.inputrc
# Activer la complétion insensible à la casse
set completion-ignore-case on
# Activer les statistiques visibles pour les complétions
set visible-stats on
# Afficher toutes les complétions immédiatement
set show-all-if-ambiguous on
# Utiliser les couleurs pour le préfixe de complétion
set colored-completion-prefix on
Recherche d'historique améliorée
# Dans votre script ou .bashrc
# Lier Ctrl+R pour la recherche incrémentielle inversée (par défaut, mais améliorée dans 5.1)
bind '"\C-r": reverse-search-history'
# Lier Ctrl+S pour la recherche incrémentielle avant
bind '"\C-s": forward-search-history'
# Gestion améliorée de l'historique
shopt -s histappend # Ajouter à l'historique
shopt -s cmdhist # Commandes multi-lignes comme une seule entrée
HISTCONTROL=ignoreboth # Ignorer les doublons et les espaces de début
HISTSIZE=10000
HISTFILESIZE=20000
Améliorations de la gestion des signaux
Meilleure propagation des signaux dans les sous-shells et les substitutions de processus :
# Gestion améliorée des traps dans les sous-shells
nettoyage() {
echo "Nettoyage en cours..." >&2
rm -f "${fichier_temp}"
exit 130 # 128 + SIGINT
}
trap nettoyage SIGINT SIGTERM
fichier_temp=$(mktemp)
# Le signal se propage correctement à travers les pipelines
tache_longue | traiter_sortie &
pid=$!
# Attendre le job en arrière-plan avec une gestion appropriée des signaux
wait "${pid}" 2>/dev/null
code_sortie=$?
if [[ ${code_sortie} -gt 128 ]]; then
signal=$((code_sortie - 128))
echo "Processus terminé par le signal ${signal}" >&2
fi
Corrections de bogues et cas limites
Gestion des sous-shells
Comportement amélioré lors de la création de sous-shells :
# Héritage plus fiable des variables du sous-shell
variable_externe="parent"
(
# Le sous-shell hérite désormais plus fiablement des variables parentes
echo "Dans le sous-shell : ${variable_externe}"
variable_interne="enfant"
)
# variable_externe est toujours accessible, variable_interne ne l'est pas
echo "Après le sous-shell : ${variable_externe}"
Cas limites de correspondance de motifs
Correction des cas limites dans la correspondance de motifs glob :
# Correspondance glob plus fiable avec caractères spéciaux
shopt -s nullglob # Expansion vide pour les globs sans correspondance
shopt -s extglob # Correspondance de motifs étendue
# Exemple : Correspondre aux fichiers mais gérer gracieusement l'absence de correspondance
fichiers=(*.txt)
if [[ ${#fichiers[@]} -eq 0 ]]; then
echo "Aucun fichier .txt trouvé"
else
printf 'Trouvé : %s\n' "${fichiers[@]}"
fi
Améliorations des performances
- Expansion de variables plus rapide dans les boucles
- Opérations sur les tableaux optimisées
- Utilisation réduite de la mémoire pour les grands tableaux
- Efficacité améliorée dans la correspondance de motifs
Notes de compatibilité
Mise à niveau depuis Bash 5.0
La plupart des scripts sont compatibles, mais notez :
EPOCHSECONDSetEPOCHREALTIMEsont nouveaux - vérifiez leur existence si vous ciblez des versions plus anciennesSRANDOMpeut ne pas être disponible sur tous les systèmes- Certains cas limites obscurs dans le comportement d'expansion ont été corrigés
Vérification de version
# Vérifier la version de Bash avant d'utiliser les fonctionnalités de 5.1
if [[ "${BASH_VERSINFO[0]}" -ge 5 ]] && [[ "${BASH_VERSINFO[1]}" -ge 1 ]]; then
# Utilisation sécurisée des fonctionnalités de Bash 5.1
horodatage="${EPOCHSECONDS}"
else
# Solution de repli pour les versions plus anciennes
horodatage=$(date +%s)
fi
Références
- Fichier NEWS de Bash - Notes de version officielles
- Publication GNU Bash 5.1 - Distribution source
- Page de manuel de Bash :
man bash(section sur les fonctionnalités spécifiques à la version)
Ressources supplémentaires
Pour des modèles et bonnes pratiques plus larges de développement Bash, voir :
- ../bash-development/SKILL.md - Modèles de développement Bash de base
- ../bash-portability/SKILL.md - Compatibilité entre versions