ti-enxame.com

Como obtenho a conclusão do bash para alias de comando?

Estou procurando obter o preenchimento de guias nos meus aliases de linha de comando, por exemplo, digamos que defini o seguinte alias:

alias apt-inst='Sudo aptitude install'

Existe uma maneira de obter as conclusões fornecidas pelo aptitude quando eu pressiono a tecla tab? ou seja, quando eu escrevo 'Sudo aptitude install gnumer' e clico em tab, o aptitude conclui isso em gnumeric ou, se houver incerteza, lista todos os pacotes disponíveis começando com gnumer. Se eu fizer isso usando meu apelido, nada - nenhuma conclusão.

69
levesque

m ótimo tópico sobre isso nos fóruns do Ubunt . Ole J propõe a seguinte função de definição de conclusão de alias:

function make-completion-wrapper () {
  local function_name="$2"
  local arg_count=$(($#-3))
  local comp_function_name="$1"
  shift 2
  local function="
    function $function_name {
      ((COMP_CWORD+=$arg_count))
      COMP_WORDS=( "[email protected]" \${COMP_WORDS[@]:1} )
      "$comp_function_name"
      return 0
    }"
  eval "$function"
  echo $function_name
  echo "$function"
}

Use-o para definir uma função de conclusão para o seu alias e, em seguida, especifique essa função como um complemento para o alias:

make-completion-wrapper _apt_get _apt_get_install apt-get install
complete -F _apt_get_install apt-inst

Prefiro usar aliases para adicionar argumentos sempre usados ​​aos programas existentes. Por exemplo, com grep, eu sempre quero pular dispositivos e arquivos binários, então faço um alias para grep. Para adicionar novos comandos, como grepbin, eu uso um script Shell no meu ~/bin pasta. Se essa pasta estiver no seu caminho, ela será preenchida automaticamente.

35
Shawn J. Goff

Tente alias completo , que resolve esse problema exatamente. ( Isenção de responsabilidade : sou o autor de complete_alias)

Após a instalação, você pode usar uma função genérica para concluir vários aliases como este:

complete -F _complete_alias <myalias1>
complete -F _complete_alias <myalias2>
complete -F _complete_alias <myalias3>

Você pode originar o arquivo complete_alias Em todas as instâncias do bash através de .bash_profile Ou similar.

installation

mkdir ~/.bash_completion.d
curl https://raw.githubusercontent.com/cykerway/complete-alias/master/complete_alias \
     > ~/.bash_completion.d/complete_alias

inscrição

source ~/.bash_completion.d/complete_alias

alias container=docker\ container
complete -F _complete_alias container

container agora pode ser preenchido automaticamente pelo manipulador de conclusão original _docker();

$ container l<Tab>
logs  ls    

$ container s<Tab>
start  stats  stop   
37
Cyker

resposta em 2018

Você deve adicionar seu alias ao programa 'complete'. Dependendo do tipo de preenchimento automático que você deseja obter, você deve usar -c ou -F.

Para preenchimento automático de pacote:

complete -c name_of_your_alias

Para preenchimento automático de comando:

complete -F name_of_your_alias

Para verificar se o seu alias foi adicionado corretamente:

complete | grep name_of_your_alias

Por fim, para remover um alias de 'complete':

complete -r name_of_your_alias

No seu caso:

complete -c apt-inst
6
Adrian Lopez

Aqui está o código de resposta de Shawn J. Goff com algumas melhorias:

  • Corrigidos erros de sintaxe destacados por Shell-check , por exemplo, o primeiro " do "[email protected]" realmente terminou a string de definição da função.
  • Removeu o return 0 para que o valor de retorno da função subjacente possa ser transmitido de volta ao chamador.

.

# Wraps a completion function, eg for use with an alias.
# Usage:
# make-completion-wrapper <actual completion function> <name of new func.>
#                         <command name> <list supplied arguments>
# eg.
#   alias agi='apt-get install'
#   make-completion-wrapper _apt_get _apt_get_install apt-get install
#     # defines a function called _apt_get_install (that's $2) that will
#     # complete the 'agi' alias. 
#   complete -F _apt_get_install agi
function make-completion-wrapper {
  local function_name="$2"
  local arg_count=$(( $#-3 ))
  local comp_function_name="$1"
  shift 2
  local function="function $function_name {
      (( COMP_CWORD += $arg_count ))
      COMP_WORDS=( \"\[email protected]\" \${COMP_WORDS[@]:1} )
      \"$comp_function_name\"
    }"
  eval "$function"
  # echo "$function"
}
export -f make-completion-wrapper
2
Tom Hale

Ao pesquisar esta questão no Google, acabei aqui, então tentei as abordagens nas outras respostas. Por várias razões que eu realmente não entendo, elas nunca se comportaram corretamente no meu Ubuntu 16.04.

No final, o que funcionou para mim foi muito mais trivial do que o esperado. Eu queria usar o mesmo preenchimento automático que rsync possui para mycommand. Portanto, procurei a função de preenchimento automático e chamei complete de acordo.

# Lookup of name of autocompletion function used for rsync
complete -p rsync
# Returns: complete -o nospace -F _rsync rsync

# Sourcing the rsync functions before, then using the same function for 'mycommand'
. /usr/share/bash-completion/completions/rsync
complete -o nospace -F _rsync mycommand

Isenção de responsabilidade: não sei qual é a desvantagem da minha abordagem em comparação com as outras. Eu escrevi isso principalmente, pois poderia ajudar as pessoas onde essa abordagem trivial pode ser suficiente.

2
M.Ermatinger

Como uma extensão da resposta do @Giles, a seguinte função de conveniência nomeia automaticamente o wrapper gerado por make-completion-wrapper para permitir definir a conclusão em uma linha:

function complete-alias  {
    # uses make-completion-wrapper: https://unix.stackexchange.com/a/4220/50978
    # example usage
    # complete-alias _pass pshow pass show
    # complete-alias _pass pgen pass generate

    EXISTING_COMPLETION_FN=${1} && shift
    ALIAS=${1} && shift
    AUTOGEN_COMPLETION_FN="__autogen_completion_${ALIAS}"
    make-completion-wrapper ${EXISTING_COMPLETION_FN} ${AUTOGEN_COMPLETION_FN} ${*}
    complete -F ${AUTOGEN_COMPLETION_FN} ${ALIAS}
}
1
user84207