Guide des technologies

Ajouter l'auto‑complétion à vos scripts Bash et zsh

8 min read Scripts Shell Mis à jour 22 Sep 2025
Auto‑complétion pour scripts Bash et zsh
Auto‑complétion pour scripts Bash et zsh

La complétion par tabulation rend vos scripts plus faciles à utiliser et à découvrir. Ce guide explique comment ajouter une auto‑complétion simple pour zsh et Bash, présente une version portable qui détecte le shell et fournit des conseils de test, des modèles et une checklist pour la mise en production.

Fenêtre de terminal affichant la page manuelle du client mail Mutt sur Linux

L’auto‑complétion accélère l’utilisation des outils en réduisant la frappe et en rendant les commandes auto‑documentées. Les shells modernes comme zsh et bash fournissent des mécanismes pour enrichir l’expérience de l’utilisateur avec des suggestions pour des commandes, des noms de fichiers, des options et des sous‑commandes.

Important: la complétion s’exécute dans le shell de l’utilisateur, pas dans le binaire de votre programme. Vous fournissez des règles que le shell utilise quand l’utilisateur presse Tab.

Comment fonctionne la complétion par Tab

L’auto‑complétion existe dans Unix depuis les années 80. Les shells examinent le contexte (ce qui a été tapé, où se trouve le curseur) pour proposer des complétions pertinentes.

  • La complétion de commandes parcourt le PATH pour trouver les exécutables commençant par les lettres tapées.
  • La complétion de chemins propose des fichiers et dossiers (relatifs ou absolus) et résout les ambiguïtés.
  • La complétion d’arguments s’applique à tout ce qui suit le nom de la commande: options, sous‑commandes, identifiants, etc.

Suggestions d'auto‑complétion pour la commande « git check » incluant check-attr, check-ignore et checkout

Définition: auto‑complétion – mécanisme qui propose des termes (commandes, fichiers, options) en fonction du texte déjà saisi.

Exemple pratique: un script « todos » simple

Nous allons montrer la complétion d’arguments pour un script minimaliste qui gère une liste de tâches. Le comportement importe peu; le but est d’illustrer la manière d’ajouter des suggestions.

Code du script (zsh/bourne compatible) :

#!/usr/bin/env zsh

FILE="$HOME/.local/state/todos/data"

if [ "$#" -eq "1" ] && [ "$1" = "edit" ] ; then
    "${EDITOR:-vi}" "$FILE"
elif [ "$#" -eq "1" ] && [ "$1" = "help" ] ; then
    echo "Usage: $(basename $0) [ edit | help ]"
else
    <"$FILE" grep -v ^~
fi

Commandes disponibles après installation du script dans le PATH et rendu exécutable:

  • todos : affiche le contenu du fichier data en ignorant les lignes commençant par ~
  • todos help : affiche l’aide
  • todos edit : ouvre le fichier dans l’éditeur

Vous pouvez créer un script vide et rendre exécutable pour tester la logique de complétion sans implémenter toute la logique métier.

Ajouter une complétion simple pour zsh

Pour zsh, la complétion la plus basique est très simple : définissez une fonction qui appelle compadd avec la liste des suggestions, chargez compinit, puis liez la fonction à la commande.

_complete_todos() {
    compadd help edit
}

autoload -Uz compinit
compinit
compdef _complete_todos todos

Explication rapide:

  • compadd : ajoute des mots proposés à zsh.
  • compinit : initialise le système de complétion de zsh.
  • compdef : associe votre fonction à la commande.

Où placer ce code :

  • Dans ~/.zshrc (pour développement rapide).
  • Dans un fichier sous un répertoire référencé par $fpath, dont le nom commence par un underscore (_todos) pour que zsh puisse l’autoloader.

Note: zsh propose aussi des helpers avancés comme _arguments et _files pour gérer options et chemins.

Comportement et différences dans Bash

Bash adopte une approche moins magique : il vous laisse décider quelles suggestions sont pertinentes. L’équivalent naïf est :

_complete_todos_bash() {
    COMPREPLY=(help edit)
}

complete -F _complete_todos_bash todos

Explication :

  • complete : enregistre une fonction de complétion pour la commande.
  • COMPREPLY : variable tableau que la fonction doit remplir avec les propositions.

Problème courant : bash ne filtre pas automatiquement les propositions en fonction de ce qui est tapé. Par exemple :

$ todos he
help edit

Ici, il faut dire à bash de ne proposer que « help » quand l’utilisateur a tapé “he”. Pour cela, bash fournit des variables utiles :

  • COMP_WORDS : tableau des mots de la ligne de commande actuelle.
  • COMP_CWORD : index du mot en cours de complétion.

Et une commande d’aide, compgen, qui peut générer des suggestions filtrées :

$ compgen -W "one two three" o
one
$ compgen -W "one two three" t
two
three

Ainsi, on peut écrire :

_complete_todos_bash() {
    COMPREPLY=( $( compgen -W "edit help" -- "${COMP_WORDS[$COMP_CWORD]}" ) )
}

complete -F _complete_todos_bash todos

Variantes utiles en bash :

  • compgen -f : proposer des noms de fichiers.
  • compgen -d : proposer des répertoires.
  • compopt -o nospace : empêcher l’ajout d’un espace automatique après la complétion (utile pour options qui attendent un =).

Important: vérifiez la compatibilité avec la version de bash cible si vous utilisez compopt, car certaines options sont spécifiques à bash-completion.

Version portable pour zsh et Bash

Voici un exemple complet qui détecte le shell et applique la logique adaptée :

SUBCOMMANDS=(help edit halt)

_complete_todos_zsh() {
    compadd $SUBCOMMANDS
}

_complete_todos_bash() {
    COMPREPLY=( $( compgen -W "${SUBCOMMANDS[*]}" -- "${COMP_WORDS[$COMP_CWORD]}" ) )
}

if [ -n "${ZSH_VERSION:-}" ]; then
    autoload -Uz compinit
    compinit
    compdef _complete_todos_zsh todos
elif [ -n "${BASH_VERSION:-}" ]; then
    complete -F _complete_todos_bash todos
fi

Conseils de déploiement :

  • Stockez ce script dans un fichier (par exemple completion.sh) et sourcez‑le depuis ~/.bashrc ou ~/.zshrc :
. /path/to/completion.sh
  • Pour partager une complétion avec les utilisateurs d’un paquet, placez le fichier pour bash dans /etc/bash_completion.d/ et le fichier zsh dans un dossier fpath approprié, ou fournissez des instructions pour l’ajout au dotfile.

Scénarios plus avancés et limites (quand ça échoue)

Counterexamples / quand cela échoue :

  • Comportement multi‑mot : si la complétion dépend d’autres arguments déjà fournis, un simple compadd/COMPREPLY statique ne suffit.
  • Sous‑commandes dynamiques : si la liste de sous‑commandes provient d’un serveur ou d’une configuration modifiable, il faut générer la liste à la volée.
  • Conflits de complétion : plusieurs fichiers de complétion peuvent entrer en conflit. Le shell charge souvent la dernière définition.
  • Différences de versions : les helpers (compopt, certaines options de compgen) varient selon la version de bash/bash‑completion.

Exemples d’échecs concrets :

  • Vous proposez des fichiers mais oubliez d’utiliser compgen -f; bash proposera des mots non valides.
  • Vous fournissez « help edit » mais oubliez d’exclure la sous‑commande « help » lorsque d’autres drapeaux demandent un fichier.

Approches alternatives

  • argcomplete (Python) : pour les scripts Python, argcomplete peut générer la complétion à partir d’argparse.
  • Click (Python) : framework CLI qui peut générer des complétions shell automatiquement.
  • Cobra (Go) : framework pour CLI qui intègre la génération de scripts de complétion.
  • Utiliser des utilitaires existants : many GNU utilities et outils modernes fournissent déjà des scripts de complétion prêts à l’emploi.

Ces solutions conviennent si vous développez une application distribuée ou un véritable CLI à options complexes.

Mental models et heuristiques

  • Principe KISS : commencez par une liste statique de sous‑commandes, puis complexifiez au besoin.
  • Local first : si la liste vient d’un fichier local, lisez‑la; si elle dépend d’un réseau, mettez en cache pour ne pas bloquer la complétion.
  • Explicitez le contexte : utilisez COMP_WORDS/COMP_CWORD (bash) ou les helpers zsh (_arguments) pour connaître le mot en cours.

Fiche pratique (fact box)

  • Langages visés : shell (bash, zsh)
  • Outils utiles : compadd (zsh), compinit (zsh), compdef (zsh), compgen (bash), complete (bash), COMPREPLY (bash)
  • Déploiement courant : ~/.bashrc, ~/.zshrc, /etc/bash_completion.d/, $fpath pour zsh
  • Risques : conflits de fichiers de complétion, dépendances à la version du shell

Mini‑méthodologie pour développer une complétion fiable

  1. Commencez par un prototype statique (compadd / COMPREPLY avec compgen).
  2. Testez localement en sourçant votre fichier et en essayant plusieurs scénarios.
  3. Traitez les cas contextuels (ex : argument dépend d’un flag précédent).
  4. Ajoutez mise en cache si vous interrogez des sources lentes.
  5. Documentez l’emplacement et la façon d’activer la complétion pour l’utilisateur.
  6. Intégrez des tests automatisés (voir checklist QA ci‑dessous).

Checklist par rôle

Développeur

  • Fournir un script de complétion minimal.
  • Documenter comment sourcer le script.
  • Prévoir une génération dynamique si nécessaire.

Mainteneur de paquet

  • Installer le script dans /etc/bash_completion.d/ (bash).
  • Placer un fichier fpath/_nom pour zsh ou documenter l’installation.
  • Tester l’absence de conflit avec d’autres scripts.

QA / Testeur

  • Vérifier complétions pour mot vide, préfixes partiels, et mots composés.
  • Tester sous bash (au moins 4.x) et zsh (versions courantes).
  • Tester cas d’erreur et latence (complétion asynchrone ou cache si nécessaire).

Tests et critères d’acceptation

Cas de test essentiels :

  • TC1 : « todos » propose la liste complète de sous‑commandes.
  • TC2 : « todos he » ne propose que « help ».
  • TC3 : « todos ed » ne propose que « edit ».
  • TC4 : quand le script fournit des chemins, la complétion montre uniquement des fichiers existants.
  • TC5 : pas d’erreurs visibles dans le shell lors de l’appui sur Tab.

Critères d’acceptation : la complétion propose un ensemble raisonnable d’options pertinentes pour chaque contexte sans provoquer d’erreurs visibles ni ralentir notablement l’utilisation du shell.

Modèles et snippets utiles

Snippet pour compléter des fichiers en bash :

# dans la fonction de complétion bash
local cur
cur=${COMP_WORDS[COMP_CWORD]}
COMPREPLY=( $( compgen -f -- "$cur" ) )

Snippet pour empêcher l’ajout d’espace après complétion (bash) :

# empêche l'ajout d'un espace automatique
compopt -o nospace

Snippet zsh utilisant _arguments (exemple simple) :

# fichier _todos pour fpath
#compdef todos

_arguments \
  '1: :->subcmd' \
  '*: :->args'

case $state in
  subcmd)
    _values 'sous-commande' edit help halt
    ;;
esac

Compatibilité et migration

  • Si vous ciblez plusieurs distributions, testez avec bash 4.x et zsh 5.x au minimum.
  • Pour les scripts partagés dans une équipe hétérogène, fournissez un fichier d’installation simple et documenté.
  • Pour les projets open source, ajoutez la génération des scripts de complétion dans votre pipeline CI si votre CLI est généré (ex : Cobra/Click).

Glossaire (une ligne)

  • compadd : fonction zsh pour ajouter des complétions.
  • compinit : initialise le système de complétion de zsh.
  • compdef : associe une fonction de complétion à une commande en zsh.
  • compgen : utilitaire bash pour générer des propositions.
  • COMPREPLY : tableau bash attendu par complete.
  • complete : commande bash pour enregistrer une fonction de complétion.

Résumé

La complétion par Tab améliore l’ergonomie de vos scripts. Commencez simple avec des listes statiques, puis enrichissez la logique pour gérer des sous‑commandes dynamiques ou des arguments contextuels. Testez sous les shells ciblés et documentez l’installation pour vos utilisateurs.

Notes:

  • Si vous développez en Python ou Go, considérez argcomplete, Click ou Cobra pour générer automatiquement des scripts de complétion.
  • Évitez d’effectuer des appels réseau bloquants pendant la complétion ; utilisez le cache ou une génération asynchrone si nécessaire.
Auteur
Édition

Matériaux similaires

Empêcher les applications Android en arrière-plan
Mobile

Empêcher les applications Android en arrière-plan

Redimensionner un RAID dégradé (/dev/md1)
Administration système

Redimensionner un RAID dégradé (/dev/md1)

Réparer le son des Stories Instagram sur iPhone
Dépannage iPhone

Réparer le son des Stories Instagram sur iPhone

Traquer et se protéger des numéros frauduleux
Sécurité

Traquer et se protéger des numéros frauduleux

Auto‑complétion pour scripts Bash et zsh
Scripts Shell

Auto‑complétion pour scripts Bash et zsh

Formulaires Numbers sur iPad/iPhone — guide pratique
Productivité

Formulaires Numbers sur iPad/iPhone — guide pratique