Guida alle tecnologie

Aggiungere il completamento automatico (Tab) ai tuoi script Bash e zsh

9 min read Scripting Aggiornato 22 Sep 2025
Completamento Tab per script Bash e zsh
Completamento Tab per script Bash e zsh

Finestra del terminale che mostra la pagina di manuale del client di posta Mutt su Linux

Perché aggiungere il completamento automatico

Il completamento tramite Tab è una funzionalità semplice ma potente: riduce gli errori di digitazione, accelera il lavoro, e aiuta a scoprire sottocomandi e opzioni disponibili senza leggere la documentazione. Molti utenti si aspettano che i comandi forniscano completamento; non averlo è una piccola frizione che può abbassare l’adozione del tuo strumento.

Definizione rapida: Il completamento automatico è il meccanismo che suggerisce o completa parole nel terminale mentre digiti, basandosi sul contesto (comando, percorso file, opzioni, ecc.).

Come funziona il completamento nel terminale

I shell come zsh e Bash gestiscono il completamento in modi diversi, ma concettualmente ci sono tre tipi principali:

  • Comandi: completamento del nome del comando cercando nelle directory indicate da PATH.
  • Percorsi/file: completamento di nomi di file e directory.
  • Argomenti e sottocomandi: completamento contestuale di opzioni, sotto-strumenti o valori possibili dopo il nome del comando.

Il completamento contestuale (argomenti) è spesso la parte più utile per script personalizzati: permette di suggerire sottocomandi, file speciali o valori validi per un’opzione.

Suggerimenti di completamento per il comando

Un esempio pratico: il comando todos

Useremo un semplice script fittizio chiamato todos che gestisce una lista di attività. L’esempio è minimale e focalizzato solo sul completamento dei sottocomandi.

#!/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  

Comandi disponibili dopo l’installazione di questo script in PATH e con permessi eseguibili:

  • todos — mostra il contenuto del file dati, ignorando righe che iniziano con ~
  • todos help — mostra l’uso
  • todos edit — apre il file dei todo nell’editor

Questo è tutto ciò che ci serve per dimostrare il completamento degli argomenti.

Completamento personalizzato in zsh

La versione più semplice per zsh sfrutta il modulo compinit e la funzione compadd. Copia e incolla questo frammento nella tua ~/.zshrc o in un file sotto una directory elencata in fpath (nome del file che inizia con underscore):

_complete_todos() {  
    compadd help edit  
}  
  
autoload -Uz compinit  
compinit  
compdef _complete_todos todos  

Spiegazione rapida:

  • _complete_todos è il gestore di completamento: chiama compadd con la lista delle possibili opzioni.
  • compinit attiva il sistema di completamento di zsh.
  • compdef collega la funzione _complete_todos al comando todos.

Importante: puoi mettere lo stesso codice in un file separato e caricarlo dalla tua ~/.zshrc con un semplice source.

Differenze e peculiarità di Bash

Bash funziona in modo più esplicito: il gestore deve popolare la variabile array COMPREPLY. Bash non applica automaticamente filtri di prefisso, quindi il tuo gestore dovrebbe tenere conto del testo parziale già digitato.

Esempio naïf in Bash:

_complete_todos_bash() {  
    COMPREPLY=(help edit)  
}  
  
complete -F _complete_todos_bash todos  

Questo funziona, ma non filtra per il prefisso digitato:

$ todos he  
help edit  

Per produrre suggerimenti contestuali usa le variabili che Bash mette a disposizione:

  • COMP_WORDS: array con ogni parola della riga di comando.
  • COMP_CWORD: indice corrente nella riga di comando (la parola su cui si sta completando).

Il comando compgen semplifica la generazione di completamenti basati su una lista statica. Esempio:

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

Un gestore completo minimale che filtra per prefisso:

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

Script portabile che funziona in zsh e Bash

Per rendere il completamento riutilizzabile su più sistemi, conviene scrivere un singolo file che rilevi la shell in esecuzione e registri il gestore appropriato.

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  

Nota: ZSH_VERSION e BASH_VERSION esistono solo nella shell che invoca il completamento; è la shell dell’utente (dove si preme Tab) che conta, non la shell in cui è stato eseguito lo script originale.

Consigli pratici per script reali

  1. Mantieni una lista centrale di suggerimenti (es. SUBCOMMANDS) e sfruttala in entrambi i gestori.
  2. Per sottocomandi dinamici, genera la lista al volo (es. leggendo un file, interrogando l’applicazione o chiamando il comando con –list).
  3. Considera l’uso di standard come l’opzione –generate-completion (molti progetti usano questa convenzione) per lasciare che il programma fornisca i suggerimenti più aggiornati.
  4. Evita operazioni lente nel gestore: il completamento è interattivo e deve rispondere rapidamente.

Importante: esegui sempre il completamento in modo idempotente e senza effetti collaterali (non modificare file o stato dell’ambiente).

Quando il completamento fallisce o è poco utile

  • Script che fanno operazioni lente o bloccanti (network, I/O pesante) se vengono chiamati dal gestore di completamento. Evita di eseguire comandi costosi durante la generazione delle liste.
  • Input che dipende da stato remoto non immediatamente disponibile. In questi casi fornisci una cache o un’opzione esplicita per rigenerare l’elenco.
  • Ambiente in cui l’utente non ha caricato il file di completamento (non è stato fatto source o non è stato installato globalmente).
  • Bash senza il corretto uso di COMP_WORDS/COMP_CWORD: suggerimenti che non rispettano il prefisso.

Contromisure:

  • Fornisci un fallback statico.
  • Introduci un timeout o una cache per le operazioni remote.
  • Documenta come installare il completamento.

Approcci alternativi e integrazioni

  • Usare framework di completamento avanzati: per zsh esistono plugin e helper che semplificano la scrittura di completamenti complessi.
  • Delegare al programma: molti progetti espongono un sottocomando per il completamento (es. myprog –completion zsh) in modo che lo script di completamento invochi il programma per ottenere suggerimenti aggiornati.
  • Strumenti esterni come argcomplete (per Python) che si integrano con Bash e offrono mappature automatiche delle opzioni.

Quando usare quale approccio:

  • Script piccoli e personali: gestore statico in ~/.bashrc o ~/.zshrc.
  • Progetti condivisi: un file di completamento installabile (es. /etc/bash_completion.d/) o una funzione che chiede al programma i suggerimenti.

Mini-metodologia per progettare un completamento

  1. Identifica i contesti da completare: sottocomandi, opzioni, file, valori predefiniti.
  2. Definisci la sorgente dei suggerimenti: lista statica, output di un comando, file di configurazione.
  3. Implementa gestori separati per zsh e Bash, riutilizzando la stessa sorgente.
  4. Misura i tempi di risposta e aggiungi caching se necessario.
  5. Scrivi test di accettazione per i casi principali.
  6. Documenta l’installazione e fornisci una procedura per aggiornamenti.

Checklist per ruolo

Sviluppatore:

  • Avere una lista centrale di sottocomandi e opzioni.
  • Garantire che il gestore non modifichi lo stato.
  • Offrire un modo per rigenerare la lista di suggerimenti.

Operazioni / Packager:

  • Installare il file di completamento in /etc/bash_completion.d/ o in una directory compatibile per zsh.
  • Aggiornare la documentazione di installazione.

Utente finale:

  • Eseguire source /path/to/completion.sh oppure riavviare la shell dopo l’installazione.
  • Verificare con il comando compgen (Bash) o compadd (zsh) per debug.

Test di accettazione e casi di prova

Casi minimi che dovresti coprire:

  • Completamento di tutti i sottocomandi dopo “todos ”.
  • Completamento parziale: “todos he” deve suggerire solo “help”.
  • Completamento in presenza di altri argomenti: “todos edit –” non deve accidentalmente suggerire sottocomandi al posto di opzioni.
  • Prestazioni: generazione dei suggerimenti in meno di 200 ms per user experience fluida (criterio qualitativo se non misurabile automaticamente).

Esempio di comando di test rapido per Bash:

# Fornisce l'ultima parola su cui il completamento si applica
echo "COMP_WORDS: ${COMP_WORDS[*]}"  
echo "COMP_CWORD: ${COMP_CWORD}"  

Snippets e cheat sheet

  • Registrare completamento in zsh: compdef _function comando
  • Registrare completamento in Bash: complete -F _function comando
  • Generare completamenti filtrati in Bash: compgen -W “list” – “${COMP_WORDS[$COMP_CWORD]}”
  • Aggiungere compadd in zsh: compadd item1 item2

Esempio avanzato: completamento dinamico basato su file di configurazione

Questo approccio legge una lista di elementi da un file JSON o da una directory e li serve come suggerimenti senza lanciare comandi pesanti.

Mental model: pensa al completamento come a un query a bassa latenza che legge una sorgente locale già disponibile (file o cache). Se devi fare chiamate di rete, ragiona su un livello di caching o su un processo asincrono che aggiorna una cache locale.

Compatibilità e migrazione

  • Per Bash, assicurati che la distribuzione includa il pacchetto bash-completion o che sia configurata manualmente.
  • Per zsh, verifica che compinit sia presente e che fpath contenga la directory dove metti il file _nome.
  • Se distribuisci il completamento in un pacchetto, aggiungi gli script nei percorsi standard (/usr/share/zsh/site-functions o /etc/bash_completion.d/). Documenta la versione minima di shell supportata.

Sicurezza e privacy

  • Non esporre dati sensibili nei suggerimenti (es. token, password, percorsi con dati privati).
  • Evita di eseguire comandi che potrebbero ritornare informazioni sensibili o modificare lo stato.
  • Quando il completamento legge file utente, assicurati che i permessi siano appropriati e documenta cosa viene letto.

Distribuzione e procedura di rollout

Sempilla SOP per rilasciare il completamento ai tuoi utenti:

  1. Preparare il file completion.sh o _todos (per zsh) con i gestori.
  2. Inserire il file nel pacchetto del progetto sotto /share/completions/.
  3. Aggiornare lo script di installazione per copiare i file in /etc/bash_completion.d/ e /usr/share/zsh/site-functions/.
  4. Aggiornare la documentazione di installazione con i comandi per forzare il reload (source ~/.bashrc o exec zsh).
  5. Comunicare agli utenti la nuova funzionalità e come disabilitarla se necessario.

Edge case e quando preferire l’output statico

  • Utenti con shell minime o container molto ridotti dove non è presente bash-completion o compinit: preferisci un file di completamento statico facilmente installabile a mano.
  • Script che cambiano spesso l’elenco dei sottocomandi: considera la generazione automatica di file di completamento durante la fase di build/release.

Glossario rapido

  • compadd: funzione di zsh che aggiunge suggerimenti al sistema di completamento.
  • compgen: comando di utilità di Bash per generare completamenti da una lista.
  • COMPREPLY: array di Bash che il gestore deve popolare con i suggerimenti.
  • compinit: modulo di zsh che abilita il sistema di completamento.

Riepilogo

  • Il completamento con Tab migliora l’usabilità dei tuoi script e può essere implementato in poche righe per zsh e Bash.
  • zsh fornisce astrazioni più semplici (compadd, compinit), Bash richiede una gestione esplicita tramite COMPREPLY e compgen.
  • Per progetti condivisi crea un file di completamento portabile e documenta l’installazione.
  • Evita operazioni lente e non esporre dati sensibili durante la generazione dei suggerimenti.

Importante: prova sempre il completamento nelle shell e negli ambienti target e includi test e istruzioni per l’installazione.

Breve checklist finale:

  • Funzionalità base implementata per zsh e Bash
  • Documentazione di installazione aggiornata
  • Test di accettazione automatizzati o manuali completati
  • Verificato che non vengono esposti dati sensibili

Grazie per aver letto: ora prova a creare un file completion.sh basato sull’esempio e adattalo al tuo strumento.

Autore
Redazione

Materiali simili

Creare Video Overview con NotebookLM
Strumenti di studio

Creare Video Overview con NotebookLM

Bloccare le app Android in background e risparmiare batteria
Android

Bloccare le app Android in background e risparmiare batteria

Ridimensionare array RAID degradato su Linux
Storage

Ridimensionare array RAID degradato su Linux

Tracciare e difendersi dai numeri falsi
Privacy

Tracciare e difendersi dai numeri falsi

Completamento Tab per script Bash e zsh
Scripting

Completamento Tab per script Bash e zsh

Usare i moduli in Numbers per iOS
Guide.

Usare i moduli in Numbers per iOS