Bash completions -C vs -F

6

Na configuração de conclusão do bash ( link ) fornecida pelo meu sistema, parece haver uma preferência inequívoca em completar com complete -F em oposição a complete -C .

complete -p | grep -- -C # no match

A diferença entre os dois parece ser que o formulário -F de tomada de contagem espera uma função que leia entrada de variáveis e saídas para variáveis onde o -C formulário de tomada de omissão lê entrada de argumentos posicionais e saídas para stdout .

Eu gosto da segunda abordagem melhor, pois ela é mais funcional e as funções / programas de conclusão são um pouco mais fáceis de depurar (já que não dependem de um contexto particular de variáveis).

No entanto, a preferência do link para com o primeiro me faz pensar: há alguma desvantagem na abordagem -C além do óbvio (insignificante para uma interface do usuário, IMHO) sobrecarga de desempenho de um novo processo?

    
por PSkocik 11.05.2016 / 12:40

1 resposta

2

Não sei por que você consideraria complete -C {command} "mais funcional" do que complete -F {function} , pois o último literalmente recebe uma função; Portanto, a motivação não é clara para a sua preferência declarada. Mas você está certo, quase todos os exemplos e documentação mostram uma preferência por complete ... -F {function} ... , por exemplo, complete -F _foobar foobar , onde a função _foobar é usada para gerar opções de conclusão para um comando hipotético foobar .

Os principais motivos são, presumivelmente,

  • a função " _foobar " pode ser usada para concluir vários comandos, por exemplo, talvez um pacote foobar também tenha um comando foo e bar ; $1 é passado para a função para que você saiba o nome do comando que está sendo concluído.
  • a variante da função parece fornecer muito mais informações para realizar conclusões; a variante " -C " parece mais burra em comparação (mas, na verdade, sempre usei a variante " -F ").
  • é mais fácil definir as opções de conclusão por meio da função (por meio da variável COMPREPLY array) do que depender da saída de um comando; o comando é executado em um subprocesso, por isso é mais difícil transmitir informações para ele e obter informações dele.
  • a variante "Comando -C" gera um subprocesso que, ao pressionar "tab-tab-tab" para completar, cria atrasos adicionais, quando você realmente quer que isso pareça instantâneo.
  • a variante "Comando -C" teria um & comando complicado na instrução complete , ou chamaria um script de shell externo, nesse caso você teria que enviar e rastrear a localização desse script (uma dor).

Além disso, nas minhas "conclusões" pessoais, tenho de fazê-las funcionar em versões mais antigas do bash e em vários Unix (AIX, HP-UX, Solaris, Linux e BSD), e encontrei muita variedade no que é suportado. Como " complete " retorna true quando funciona, uso o idioma a seguir, que parece ser mais portátil em versões bash (incluí isso aqui, pois mostra que o uso de " -F {function} {commmand} " é mais simples / mais limpo que um " -C "command" " correspondente seria:

complete -o bashdefault -o default -o nospace -F _cmd cmd 2>/dev/null \
|| complete             -o default -o nospace -F _cmd cmd 2>/dev/null \
|| complete             -o default            -F _cmd cmd 2>/dev/null \
|| complete                                   -F _cmd cmd

Da mesma forma, se eu tiver cmd1 , cmd2 , cmd3 , todos recebem basicamente as mesmas conclusões (por exemplo, considere um script de conclusão para scp e ssh que recebe uma lista de nomes de host gerados por você ),

for c in cmd1 cmd2 cmd3; do
    # or that long complete statement shown above
    complete -o bashdefault -o default -o nospace -F _cmd $c 2>/dev/null
done

Para referência:

por 03.07.2016 / 12:36