如何编写 bash completion script

ImportNew2018-03-17 19:57:09

(点击上方公众号,可快速关注)


来源:暗无天日,

lujun9972.github.io/blog/2018/03/13/如何编写bash-completion-script/


静态补全


创建静态补全很简单,只 complete 的 -W (wordlist) 选项为脚本注册补全的单词列表就行了。


比如,假设有一个 myscript 脚本,接参数 him,her,me,you, 那么我们可以执行:


complete -W "him her me you" myscript


这样输入 myscript 后按两下TAB,就会所有可能的参数了:


[lujun9972@T520 .spacemacs.d]$ myscript 

her  him  me   you


甚至,当你输入首字母后再按 TAB,bash会自动筛选出以首字母开头的参数


[lujun9972@T520 .spacemacs.d]$ myscript h

her  him


除了 -W 之外, complete 还有很多其他选项,比如可以使用


-A alias / -a

列出别名

-A directory / -d

列出目录

-A command / -c

列出

-A file / -f

列出文件

-A service / -s

列出服务名称

-A signal

列出信号名称

-A user / -u

列出用户名

-A group / -g

列出组名

-A variable / -v

列出shell变量

详细的说明可以看这里


https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion-Builtins.html#Programmable-Completion-Builtins


动态补全


动态补全能够根据用户的环境动态的生成补全的内容。 当出发动态补全时,bash会在当前shell中执行一个补全函数,然后从变量 COMPREPLY 中读取补全的内容。


在这个补全函数中,我们可以通过几个变量来获取当前用户输入命令的环境:


COMP_WORDS

一个数组,包含了程序名称和已经输入的参数


COMP_CWORD

这是一个指向COMP_WORDS数组的索引,指明了当前光标所在的位置(从0开始)


COMP_LINE

当前命令行的内容


compgen命令


compgen是一款内置命令,它与 complete 命令类似,但可以根据已经输入的内容对补全内容进行过滤,比如


compgen -W "him her me you" h


会输出结果:


him

her


该命令常在动态补全的补全函数中使用


注册动态补全函数


要为命令注册动态补全函数,则需要使用 completion 的 -F 函数 参数:


completion -F 补全函数 程序名称


举个例子


比如,我想为 myscript 增加一个补全,这个补全的逻辑是:


  • 第一个参数可以是 -f 或 -d

  • 第二个参数补全的内容由第一个参数的值来决定,如果第一个参数为 -f 则补全文件名,如果第一个参数为 -d 则补全目录名。


那么我们可以这么做:


# 首先,定义一个补全函数

function _myscript_completion()

{

    if [[ "${COMP_CWORD}" == "1" ]];then

        # 若补全的是第一个参数,则可以是 -f 或 -d

        COMPREPLY=($(compgen -W "-f -d" ${COMP_WORDS[${COMP_CWORD}]}))

    elif [[ "${COMP_WORDS[1]}" == "-f" ]];then

        COMPREPLY=($(compgen -f ${COMP_WORDS[${COMP_CWORD}]}))

    elif [[ "${COMP_WORDS[1]}" == "-d" ]];then

        COMPREPLY=($(compgen -d ${COMP_WORDS[${COMP_CWORD}]}))

    fi

}

 

# 注册补全函数

complete -F _myscript_completion myscript


看完本文有收获?请转发分享给更多人

关注「ImportNew」,提升Java技能

阅读原文

TAGS: