Bash Completion Script Help

2

Estou começando a aprender sobre scripts de conclusão do bash e comecei a trabalhar em um para uma ferramenta que uso o tempo todo. Primeiro construí o script usando uma lista de opções:

_zf_comp() 
{
    local cur prev actions
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"

    actions="change configure create disable enable show"

    COMPREPLY=($(compgen -W "${actions}" -- ${cur}))  
    return 0
}
complete -F _zf_comp zf

Isso funciona bem. Em seguida, decidi criar dinamicamente a lista de ações disponíveis. Eu coloquei o seguinte comando:

zf | grep "Providers and their actions:" -A 100 | grep -P "^\s*3\[36m\s*zf" | awk '{gsub(/[[:space:]]*/, "", $3); print $3}' | sort | uniq | awk '{sub("\-", "\-", $1); print $1}' | tr \n " " | sed 's/^ *\(.*\) *$//'

O que basicamente faz o seguinte:

  • Pega todo o texto no comando "zf" depois de "Provedores e suas ações:"
  • Pega todas as linhas que começam com "zf" (eu tive que fazer algum trabalho interessante aqui porque o comando ZF imprime em cores)
  • Pegue a segunda parte do comando e remova todos os espaços dela (a parte de espaços provavelmente não é mais necessária)
  • Classifique a lista
  • Livrar-se de quaisquer duplicatas
  • Traçar traços (adicionei isso ao tentar depurar o problema - provavelmente não necessário)
  • Apare todas as novas linhas
  • Apare todos os espaços iniciais e finais

O comando acima produz:

$ zf | grep "Providers and their actions:" -A 100 | grep -P "^\s*3\[36m\s*zf" | awk '{gsub(/[[:space:]]*/, "", $3); print $3}' | sort | uniq | awk '{sub("\-", "\-", $1); print $1}' | tr \n " " | sed 's/^ *\(.*\) *$//'
change configure create disable enable show 
$

Então, parece-me que está produzindo exatamente a mesma string que eu tinha no meu roteiro original. Mas quando eu faço:

_zf_comp() 
{
    local cur prev actions
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"

    actions='zf | grep "Providers and their actions:" -A 100 | grep -P "^\s*3\[36m\s*zf" | awk '{gsub(/[[:space:]]*/, "", $3); print $3}' | sort | uniq | awk '{sub("\-", "\-", $1); print $1}' | tr \n " " | sed 's/^ *\(.*\) *$//''

    COMPREPLY=($(compgen -W "${actions}" -- ${cur}))  
    return 0
}
complete -F _zf_comp zf

Meu preenchimento automático começa a funcionar. Primeiro, ele não completará automaticamente qualquer coisa com um "n", e segundo, quando ele fizer autocomplete ("zf create", por exemplo), ele não me permitirá voltar atrás no comando concluído.

O primeiro problema em que estou completamente perplexo. O segundo que estou pensando talvez tenha a ver com os caracteres de escape do texto colorido.

Alguma ideia? Está me deixando louco!

    
por inxilpro 19.03.2010 / 21:57

1 resposta

2

Uma coisa que acho útil é criar uma função de depuração que produza outro terminal:

debug() { echo "$@" >/dev/pts/0; }; export -f de

Depois, você pode chamá-lo de dentro de sua função de conclusão com o conteúdo de variáveis, etc., e isso não interferirá em sua própria saída enquanto você estiver testando.

Você pode tentar alterar seu tr para usar aspas e ver se isso resolve o problema "n":

tr '\n' ' '

Canalize a saída de seu grep a cat -v para ver se você está perdendo alguma sequência de escape.

Além disso, pode acelerar as coisas se você puder evitar chamar tantos comandos externos.

    
por 19.03.2010 / 23:23