Local padrão para scripts bash_completion.d definidos pelo usuário?

35

Eu tenho acesso de usuário (sem raiz) em uma máquina Linux (Suse) onde desenvolvi alguns scripts bash e as regras de autocompletar bash correspondentes.

Como os scripts pertencem apenas ao meu usuário e, portanto, eu preciso das regras completas apenas "ativas" para mim (uma parte do fato de não ter acesso de gravação root), colocando meu script bash_completion na pasta /etc/bash_completion.d/ uma opção.

No momento, nomeio meu arquivo .bash_completion.myscript e o nomeio diretamente do meu .bashrc , mas gostaria de saber se existe outra maneira "padrão" de atingir esses resultados, já considerados na implementação do bash.

Por exemplo, criando uma pasta /home/myuser/.bash_completion.d/ ?

    
por Carles Sala 10.05.2013 / 10:25

4 respostas

27

Use um arquivo ~/.bash_completion .

De Perguntas frequentes sobre a conclusão do bash :

Q. How can I insert my own local completions without having to
reinsert them every time you issue a new release?

A. Put them in ~/.bash_completion, which is parsed at the end of the
main completion script. See also the next question.

Q. I author/maintain package X and would like to maintain my own
completion code for this package. Where should I put it to be sure
that interactive bash shells will find it and source it?

A. Install it in one of the directories pointed to by
bash-completion's pkgconfig file variables. There are two
alternatives: the recommended one is 'completionsdir' (get it with
"pkg-config --variable=completionsdir bash-completion") from which
completions are loaded on demand based on invoked commands' names,
so be sure to name your completion file accordingly, and to include
for example symbolic links in case the file provides completions
for more than one command. The other one which is present for
backwards compatibility reasons is 'compatdir' (get it with
"pkg-config --variable=compatdir bash-completion") from which files
are loaded when bash_completion is loaded.

    
por 10.05.2013 / 16:18
36

Veja como um usuário local pode ter um diretório ~/.bash_completion.d/ em funcionamento.

  1. edite o arquivo: nano ~/.bash_completion , adicione o seguinte:

    for bcfile in ~/.bash_completion.d/* ; do
      . $bcfile
    done
    
  2. crie o diretório: mkdir ~/.bash_completion.d

  3. edite o arquivo: ~/.bash_completion.d/myscript , adicione o seguinte:

    _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

Atualizar

Se você espera ter um diretório ~/.bash_completion.d/ vazio e deseja evitar a exibição da mensagem de erro bash: /home/<username>/.bash_completion.d/*: No such file or directory , inclua um teste de tipo de arquivo com [ -f "$bcfile" ] .

for bcfile in ~/.bash_completion.d/* ; do
  [ -f "$bcfile" ] && . $bcfile
done
    
por 07.02.2017 / 21:57
1

A resposta da Russell E Glaue é ótima, mas o ~/.bash_completion está incompleto.

O problema é quando ~/.bash_completion.d/ está vazio e, posteriormente, for f in ~/.bash_completion.d/* imprime a seguinte mensagem de erro:

-bash: /home/user/.bash_completion.d/*: No such file or directory

A solução mais simples e portátil é pular o loop se o diretório estiver vazio:

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
    
por 20.04.2018 / 18:52
0

Uma solução mais simples é usar a opção nullglob. Embora isso não seja portável, nenhuma conclusão é bash. Portabilidade não importa.

Além disso, você desejará usar aspas ao redor da variável ao fazer o sourcing. Isso lida com o caso em que o arquivo possui espaços e outros caracteres especiais.

shopt -s nullglob

for f in ~/.bash_completion.d/*; do
  [ -f "$f" ] && . "$f"
done
    
por 07.06.2018 / 14:32