bash自动完成:添加可能的完成描述

DDJ*_*DDJ 15 bash tab-completion bash-completion

是否有可能使bash自动完成看起来像Cisco IOS shell?

我的意思是为每个完成添加简短描述,如下所示:

telnet 10.10.10. (TAB Pressed)
 10.10.10.10 - routerA
 10.10.10.11 - routerB
Run Code Online (Sandbox Code Playgroud)

其中10.10.10.10和10.10.10.11是可能的完成,routerA和routerB只是描述(不执行).

我知道bash可以用"完成-W"完成命令,但是它能够为它们打印描述吗?

bon*_*ing 12

我有一个解决方案,不需要按TAB超过两次或回应任何额外的信息.关键是检查是否只有一个完成,然后将完成除去到有效部分,通常是删除"注释"分隔符后面的最大匹配后缀.要完成OP的例子:

_telnet() {
  COMPREPLY=()
  local cur
  cur=$(_get_cword)
  local completions="10.10.10.10 - routerA
10.10.10.11 - routerB
10.20.1.3 - routerC"

  local OLDIFS="$IFS"
  local IFS=$'\n'
  COMPREPLY=( $( compgen -W "$completions" -- "$cur" ) )
  IFS="$OLDIFS"
  if [[ ${#COMPREPLY[*]} -eq 1 ]]; then #Only one completion
    COMPREPLY=( ${COMPREPLY[0]%% - *} ) #Remove ' - ' and everything after
  fi
  return 0
}
complete -F _telnet -A hostnames telnet
Run Code Online (Sandbox Code Playgroud)

这给出了您正在寻找的确切输出,并且当只有一个可能的完成时,在完成之前将从中删除注释.

  • 请注意,这不适用于“zsh”(我知道 OP 要求使用 bash,但有些人可能会使用“zsh + bashcompinit”)。这是因为当使用 zsh 进行“制表符”时,补全将被发送到输入,因此在多个匹配的情况下,描述将放在一起。 (2认同)

sku*_*uro 2

是的,但是你需要一些 bash kung foo 才能构建这样的系统。完成通常的工作方式是将普通函数绑定到您想要完成的命令。您可以找到一些基本示例,以更好地理解补全的工作原理,并开始开发补全功能。另外,如果您碰巧bash-completion安装了该软件包,您可以在系统中搜索当前在 shell 中驱动完成的许多其他示例。

您还可以查看官方 bash 手册的完成部分。


编辑

我尝试了一些实验,我的结论是,你现在不能完全按照你的要求去做:bash 不支持complete结果旁边的帮助文本。您可以做的是为提供的完成词添加图例。_myfoo这可以在用作 的bash 函数中完成complete -F _myfoo,也可以通过命令来完成complete -C myfoo,该命令在完成之前打印出图例。

主要区别在于,使用绑定到 Bash 的函数,而命令可以用您选择的任何语言编写,只要它能够设置所需的环境变量即可。

这是一个小例子:

skuro$ touch ~/bin/myfoo
skuro$ chmod +x ~/bin/myfoo
skuro$ _myfoo(){
> echo "result1 -- number one"
> echo "result2 -- number two"
> local cur prev
> _get_comp_words_by_ref cur prev
> COMPREPLY=( $(compgen -W "result1 result2" "$cur") )
> return 0
> }
skuro$ complete -F _myfoo myfoo
skuro$ myfoo result<TAB>
result1 -- number one
result2 -- number two

result1  result2  
Run Code Online (Sandbox Code Playgroud)