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 pacotefoobar
também tenha um comandofoo
ebar
;$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: