4 votes

bash-completion - fonction de complétion définie la première fois qu'une commande est invoquée

J'ai ajouté un nouvel alias scp_using_rsync qui utilise rsync pour copier des fichiers via SSH avec certaines options. Je voulais lier la complétion bash de scp à cet alias.

Il fonctionne lorsque j'ajoute cette ligne :

complete -o bashdefault -o default -o nospace -F _scp scp_using_rsync 2>/dev/null || complete -o default -o nospace -F _scp scp_using_rsync

Le seul problème, c'est que je le remarque, _scp est défini dans mon environnement bash, seulement après avoir essayé la complétion de tabulation avec ssh/scp au moins une fois dans ce shell. Ainsi, si je lance directement scp_using_rsync dans un nouveau shell, j'obtiendrais le _scp erreur non trouvée.

La sortie de typeset -F dans un nouveau shell avant et après avoir essayé la complétion par tabulation pour les commandes ssh ou scp indiquent clairement que les fonctions suivantes sont définies après avoir essayé la complétion par tabulation pour la première fois :

$ diff ~/.scratch/file1 ~/.scratch/file2
224a225,227
> declare -f _scp
> declare -f _scp_local_files
> declare -f _scp_remote_files
226a230
> declare -f _sftp
230a235,240
> declare -f _ssh
> declare -f _ssh_ciphers
> declare -f _ssh_macs
> declare -f _ssh_options
> declare -f _ssh_suboption
> declare -f _ssh_suboption_check

Ces fonctions semblent être définies dans /usr/share/bash-completion/completions/ssh dans mon système.

Ce sont mes deux questions interdépendantes :

  • Comment bash trouve-t-il où récupérer les définitions automatiquement et les définir lorsque la complétion est essayée pour la première fois ?
  • Comment dois-je lier la complétion bash pour scp_using_rsync à la complétion bash de scp d'une manière similaire ?

6voto

whjm Points 1199

Bash 4.1 a ajouté un nouveau -D option pour complete , compgen y compopt :

Nouvelle option complete/compgen/compopt -D pour définir une complétion `par défaut' : une complétion à invoquer sur une commande pour laquelle aucune complétion n'a été demandée. définie . Si cette fonction renvoie 124 l'achèvement programmable est tentée à nouveau, permettre à un utilisateur de construire dynamiquement un ensemble de complétions comme l'achèvement est tenté en ayant la fonction d'achèvement par défaut installe des fonctions d'achèvement individuelles à chaque fois qu'elle est invoquée.

Il y a un exemple tiré de l'application bash manuel :

_completion_loader()
{
     . "/etc/bash_completion.d/$1.sh" >/dev/null 2>&1 && return 124
}
complete -D -F _completion_loader

3voto

slevin Points 306

J'ai eu un problème pour appliquer la réponse de whjm. Comme Tuxdude l'a remarqué, il existait déjà une fonction _completion_loader définie dans ma distribution (Ubuntu 14.04). La fonction a été définie comme suit :

_completion_loader () 
{ 
    local compfile=./completions;
    [[ $BASH_SOURCE == */* ]] && compfile="${BASH_SOURCE%/*}/completions";
    compfile+="/${1##*/}";
    [[ -f "$compfile" ]] && . "$compfile" &> /dev/null && return 124;
    complete -F _minimal "$1" && return 124
}

Je voulais faire en sorte que la maintenance des achèvements soit conservée en un seul endroit, j'ai donc ajouté un fichier à /usr/share/bash-completion/completions/ avec le nom de la commande pour laquelle je veux ajouter la complétion. Dans votre cas, vous pourriez ajouter un fichier appelé scp_using_rsync contenant ceci :

cfile="${compfile%/*}/scp"
cmd="${1##*/}"
. "$cfile" 
complete -F _scp $cmd

Cela créera le fichier source qui définit les compléments de l'application scp y compris le _scp puis ajoutez la complétion pour votre commande. J'ai pensé que c'était une manière plus directe et plus cohérente (mais bien sûr, pour faire cela, vous devez être d'accord pour changer ce comportement pour tous les utilisateurs).

0voto

wisbucky Points 829

Certaines fonctions d'achèvement sont chargées dynamiquement. Vous pouvez les charger manuellement afin qu'elles fonctionnent avec les alias. Par exemple, vous pouvez ajouter ceci à votre ~/.bashrc afin que l'achèvement fonctionne avec votre alias.

_completion_loader docker

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X