使用TAB
键可以根据已输入的字符自动补全路径名、文件名和可执行程序,自动补全依赖于bash-completion
在/etc/bash_completion.d/
路径下创建的自动补全脚本。
实现简单的参数自动补全
自动补全的实现依赖于compgen
和complete
命令以及bash内置的补全变量,我们先看下面这个脚本:
# 脚本1: vtb.bash
_vtb()
{
local cur=${COMP_WORDS[COMP_CWORD]}
COMPREPLY=( $(compgen -W "mea aqua alice" -- $cur) )
}
complete -F _vtb vtb
赋予执行权限并测试:
> chmod +x vtb.bash
> source vtb.bash
> vtb <TAB> <TAB>
alice aqua mea
> vtb a <TAB> <TAB>
alice aqua
现在vtb
这个命令已经具有了参数补全的功能,不难发现其给出的选项来自于_vtb
函数中的COMPREPLY
数组。
自动补全原理
内置补全变量表
变量名 | 功能 |
---|---|
COMP_WORDS | 类型为数组,存放当前命令行中输入的所有单词 |
COMP_CWORD | 类型为整数,当前光标所在位置的单词在COMP_WORDS中的索引 |
COMPREPLY | 类型为数组,候选的补全结果 |
COMP_WORDBREAKS | 类型为字符串,表示单词之间的分隔符 |
COMP_LINE | 类型为字符串,表示当前的命令行输入字符 |
COMP_POINT | 类型为整数,表示光标在当前命令行的哪个位置 |
理解 compgen -W
在脚本1
的_vtb
函数中,我们首先定义了cur
变量用于获取当前光标所在位置的单词,将其作为参数传递给compgen -W
命令。该命令接受两个参数,定义与使用方式如下:
# compgen -W <word_list> <comp_word>
> compgen -W "aqua alice mea" -- a # 省略‘--’则不会输出多行
aqua
alice
compgen
命令的作用是完成候选词的筛选,-W
模式代表从<word_list>
中获得候选词,然后通过<comp_word>
参数对候选词进行筛选,最后我们将筛选得到的结果存入COMPREPLY
数组中。
理解 complete -F
我们在脚本1
中使用了complete
命令的-F
模式让vtb
命令能够获取_vtb
函数中的候选补全结果COMPREPLY
,其本质就是完成候选词的绑定。我们先以简单的-W
模式为例进行讲解,其定义与使用方式如下:
# complete -W <word_list> <comp_cmd>
> complete -W "aa ab cd" test_comp
> test_comp <TAB> <TAB>
aa ab cd
> test_comp a <TAB> <TAB>
aa ab
complete
命令可以给<comp_cmd>
绑定候选词列表,根据不同的命令模式(-F -W -C -G
)会有不同的构建候选词列表的方式。-W
模式通过字符串构建候选词列表,而-F
模式需要使用COMPREPLY
构造候选词列表,其定义与使用方式如下:
complete -F <func_name> <comp_cmd> # 绑定候选词列表
<comp_cmd> <comp_word> <TAB> <TAB> # 筛选候选词列表
该命令可以实现<func_name>
与<comp_cmd>
的绑定,<func_name>
函数中必须通过COMPREPLY
构造候选词列表,而是否使用compgen
或其他方式进行候选词筛选取决于业务逻辑。相比于其他模式,-F
模式能够提供更灵活的自动补全策略,以脚本1
为例,我们通过组合使用compgen
、complete
和内置补全变量实现了类似-W
模式的功能。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。