自动补全原理

使用 TAB 键可以根据已输入的字符自动补全路径名文件名可执行程序,自动补全依赖于 bash-completion/etc/bash_completion.d/ 路径下创建的自动补全脚本。

实现简单的参数自动补全

实现自动补全需要使用内置命令 compgencomplete 以及 bash 提供的内置的补全变量,我们先看下面这个例子:

#!/usr/bin/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 为例,我们通过组合使用 compgencomplete 和内置补全变量实现了类似 -W 模式的功能。

results matching ""

    No results matching ""