Emplacement standard pour les scripts bash_completion.d définis par l'utilisateur?

47

J'ai un accès utilisateur (non root) sur une machine Linux (Suse) sur laquelle j'ai développé des scripts bash et les règles d'auto-complétion correspondantes.

Étant donné que les scripts n'appartiennent qu'à mon utilisateur et que j'ai donc besoin des règles complètes uniquement "actives" pour moi (en partie du fait que je n'ai pas d'accès en écriture root), placer mon script bash_completion dans un /etc/bash_completion.d/dossier n'est pas une option.

Pour le moment, j'ai nommé mon fichier .bash_completion.myscriptet le source directement à partir de mon nom .bashrc, mais je me demande simplement s'il existe un autre moyen "standard" d'obtenir ces résultats, déjà pris en compte dans la mise en œuvre de bash.

Par exemple, créer un dossier /home/myuser/.bash_completion.d/?

Carles Sala
la source

Réponses:

36

Utilisez un ~/.bash_completionfichier.

De la FAQ d'achèvement de Bash :

Q. Comment puis-je insérer mes propres finitions locales sans avoir à les
réinsérer chaque fois que vous publiez une nouvelle version?

A. Mettez-les dans ~ / .bash_completion, qui sera analysé à la fin du
script d'achèvement principal. Voir aussi la question suivante.

Q. Je crée / gère le package X et souhaite conserver mon propre
code d'achèvement pour ce package. Où devrais-je le mettre pour être sûr
que les shells de bash interactifs le trouveront et le rechercheront?

A. Installez-le dans l'un des répertoires
désignés par les variables du fichier pkgconfig de bash-completion. Il existe deux
alternatives: celle recommandée est 'complétionsdir' (obtenez-la avec
"pkg-config --variable = complèteionsdir bash-complétion") à partir de laquelle les
complétions sont chargées à la demande en fonction du nom des commandes invoquées;
assurez-vous donc de nommer votre fichier d’achèvement en conséquence, et d’inclure,
par exemple, des liens symboliques au cas où le fichier fournirait des achèvements
pour plus d’une commande. L'autre qui est présent pour
des raisons de compatibilité ascendante est 'compatdir' (obtenez-le avec
"pkg-config --variable = compatdir bash-complétion"

Dennis Williamson
la source
J'ai googlé et cherché beaucoup dans serverfault avant de demander, mais je n'ai pas pensé à l'étape la plus élémentaire: RTFM! Beacoup de remerciements pour la reponse!
Carles Sala
4
Peut-être vouloir spécifier qu'il .bash_completions'agit d'un fichier et non d'un répertoire. Étant donné que bash_completion.dc’est un répertoire, j’ai supposé que je pouvais seulement scpréinstaller mon répertoire local bash_completion.det le renommer sur le serveur distant, mais lors de la connexion suivante, il m’a indiqué que ce devait être un fichier.
NobleUplift
3
La FAQ de la complétion de Bash de @NobleUplift a changé et contient maintenant des informations sur un moyen de charger les complétions de Bash de l'utilisateur depuis un répertoire à la demande. Cela semble fonctionner avec la version 2.8 de bash-completion au moins, mais pas avec la version 2.1. Les fichiers du répertoire doivent être nommés exactement comme la commande à laquelle ils sont destinés, sinon des liens symboliques pourraient être utilisés à cette fin.
Jarno
@jarno J'ai codé des scripts d'achèvement de bash pour tous les programmes personnalisés et les scripts de notre système, mais mes principaux développeurs les ont abattus :(
NobleUplift le
@NobleUplift pourquoi? Vous pouvez les utiliser pour vous quand même.
Jarno
49

Voici comment un utilisateur local peut avoir un ~/.bash_completion.d/répertoire de travail .

  1. modifier le fichier:, nano ~/.bash_completionajoutez ce qui suit:

    for bcfile in ~/.bash_completion.d/* ; do
      . $bcfile
    done
    
  2. faire un répertoire: mkdir ~/.bash_completion.d

  3. modifier le fichier:, ~/.bash_completion.d/myscriptajoutez ce qui suit:

    _myscript_tab_complete () {
        local cur prev opts
        COMPREPLY=()
        cur="${COMP_WORDS[COMP_CWORD]}"
        prev="${COMP_WORDS[COMP_CWORD-1]}"
        words="-f -h --etc"
    
        COMPREPLY=( $(compgen -W "${words}" -- ${cur}) )
        return 0
    }
    complete -F _myscript_tab_complete myscript
    
  4. source .bash_completion: . ~/.bash_completion

Mise à jour

Si vous prévoyez d'avoir un ~/.bash_completion.d/répertoire vide et que vous souhaitez éviter de voir le message d'erreur bash: /home/<username>/.bash_completion.d/*: No such file or directory, ajoutez un test de type de fichier avec [ -f "$bcfile" ].

for bcfile in ~/.bash_completion.d/* ; do
  [ -f "$bcfile" ] && . $bcfile
done
Russell E Glaue
la source
2

La réponse de Russell E. Glaue est excellente mais ~/.bash_completionincomplète.

Le problème est quand ~/.bash_completion.d/est vide et for f in ~/.bash_completion.d/*imprime ensuite le message d'erreur suivant:

-bash: /home/user/.bash_completion.d/*: aucun fichier ou répertoire de ce type

La solution la plus simple et portable consiste à ignorer la boucle si le répertoire est vide:

if [[ -d ~/.bash_completion.d/ ]] && \
   ! find ~/.bash_completion.d/. ! -name . -prune -exec false {} +
then
    for f in ~/.bash_completion.d/*
    do
        source "$f"
    done
fi
Mateusz Piotrowski
la source
1

Une solution plus simple consiste à utiliser l'option nullglob. Bien que ce ne soit pas portable, ni les achèvements de bash. Donc, la portabilité n'a pas d'importance.

En outre, vous souhaiterez utiliser des guillemets autour de la variable lors de l’approvisionnement. Ceci gère le cas où le fichier contient des espaces avec d'autres caractères spéciaux.

shopt -s nullglob

for f in ~/.bash_completion.d/*; do
  [ -f "$f" ] && . "$f"
done
npmccallum
la source
1
Pour votre information, une explication de (ou un lien vers la documentation) à propos de quelque chose montré (c'est-à-dire nullglob) est utile pour le lecteur.
Cometsong
1

Au moins bash-completion 2.8 et ultérieur permettent à l'option de placer les complétions Bash locales dans le répertoire

${BASH_COMPLETION_USER_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/bash-completion}/completions

Les noms de fichier d'achèvement ou les noms de liens symboliques doivent correspondre aux noms de commande respectifs. Ces finitions ne sont chargées que sur demande. Les finitions stockées dans le fichier ~/.bash_completion sont toujours chargées.

Référence: voir "Q. Où devrais-je installer mes propres finitions locales?" dans https://github.com/scop/bash-completion/blob/master/README.md

Jarno
la source