自定义设置 linux tab 自动补全 compgen complete
在Linux命令行下,输入字符后,按两次Tab键,shell 就会列出以这些字符打头的所有可用命令。如果只有一个命令匹配到,按一次 Tab 键就自动将这个命令补全。默认情况下,会自动列出当前目录的文件作为自动补全。
自动补全是Bash自带的一个强大的功能,允许通过编码指定命令参数如何补全。通常,补全脚本会放在 /etc/bash_completion.d/ 目录下,方便统一启用所有补全脚本。
它涉及到的命令有:
自动补全名 complete
筛选命令 compgen
一,小 demo
在 /usr/share/bash-completion/completions 或者 /etc/bash_completion.d/下 新建文件 laojia
内容为:
_laojia_completion_() { local curr_arg=${COMP_WORDS[COMP_CWORD]} #当前输入的字符串 COMPREPLY=( $(compgen -W "xx jj bb cc" -- $curr_arg ) ); } complete -F _laojia_completion_ laojia lj # 会对 laojia 和 lj 进行补全 即使这个命令根本不存在
新建一个可执行命令 laojia (这步其实可以省略)
cd /usr/local/bin/ touch laojia chmod +x laojia
尝试补全
[root@localhost bin]# exec bash [root@localhost bin]# laojia bb cc jj xx [root@localhost bin]# laojia
二、补全命令 complete
[root@localhost bash_completion.d]# help complete complete: complete [-abcdefgjksuv] [-pr] [-DE] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...] Specify how arguments are to be completed by Readline. For each NAME, specify how arguments are to be completed. If no options are supplied, existing completion specifications are printed in a way that allows them to be reused as input. Options: -p print existing completion specifications in a reusable format -r remove a completion specification for each NAME, or, if no NAMEs are supplied, all completion specifications -D apply the completions and actions as the default for commands without any specific completion defined -E apply the completions and actions to "empty" commands -- completion attempted on a blank line When completion is attempted, the actions are applied in the order the uppercase-letter options are listed above. The -D option takes precedence over -E. Exit Status: Returns success unless an invalid option is supplied or an error occurs.
-W wordlist: 自动补全使用的 wordlist, 使用 IFS 分割,会和当前用户输入的Word做前缀比较,提示那些匹配的 word list.
-S suffix: 向每个自动补全 word 后添加 suffix 后缀.
-P prefix: 向每个自动补全 word 后添加 prefix 前缀.
-X filterpat: 对于文件名,将匹配 pattern 的文件名从 completion list 中移除(exclude), pattern中使用 ! 表示否定
-G globpat: 对于文件名,将匹配 pattern 的文件名作为可能的 completion. 与 -X 刚好相反,-X “!*.foo” 与 -G “*.foo”作用相同
-C command: 将 command 命令的执行结果作为可能的 completion.
-F function: 执行 shell function,在 function 中对 COMPREPLY 这个数组复制,作为可能的 completion
-p [name]: 打印当前自定义的 complete
-r [name]: 删除当前自定义的 complete
-A action : 表示生成可能的 completion 的方式,包括 alias, file, directory 等,具体请参看文后的参看资料
使用 -C -G -X 参数样例
# ls的自动补全为当前目录 complete -C "pwd" ls # ls的自动补全为.py文件 complete -G "*.py" ls # ls的自动补全为非.py文件 complete -X "*.py" ls
使用 -F 参数自定义补全函数
function _mycomplete_() { local cmd="${1##*/}" # 当前命令 local word=${COMP_WORDS[COMP_CWORD]} #当前输入的字符串 local line=${COMP_LINE} #整行字符串 local xpat='*.py' # pattern # 根据word的值来补全当前非.py的文件file. COMPREPLY=($(compgen -f -X "$xpat" -- "${word}")) } # _mycomplete_函数可定义在.bash_profile中,然后执行 source ~/.bash_profile # 当然也可多个命令共用一个function, 只要_myfunction_作区分即可,比如对cmd执行case语句 # 生成不同的xpat complete -F _mycomplete_ myfoo #使用 _mycomplete 作为 myfoo 的自动补全
三、筛选命令 compgen
[root@localhost bash_completion.d]# help compgen compgen: compgen [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word] Display possible completions depending on the options. Intended to be used from within a shell function generating possible completions. If the optional WORD argument is supplied, matches against WORD are generated. Exit Status: Returns success unless an invalid option is supplied or an error occurs. [root@localhost bash_completion.d]#
参数虽然多,但是用的最多的只有 -W 参数啦
命令:compgen -W "aa ab bb cc" -- “a” 表示从"aa ab bb cc" 匹配出以“a”开头的单词 这条命令的返回结果就是 “aa ab”。
四、compopt(修改补全命令设置)了解即可
这个命令可以修改补全命令设置,注意了,这个命令必须在补全函数中使用,否则会报错。
# help compopt compopt: compopt [-o|+o option] [-DE] [name ...]
+o option:启用 option 配置
-o option:弃用 option 配置
例如,设置命令补全后不要多加空格,方法如下:
compopt -o nospace
五、例子讲解
# cat /etc/bash_completion.d/foo.bash _foo() { COMPREPLY=() local cur=${COMP_WORDS[COMP_CWORD]}; local cmd=${COMP_WORDS[COMP_CWORD-1]}; case $cmd in 'foo') # foo有3个参数,分别是 help, read, test COMPREPLY=( $(compgen -W 'help test read' -- $cur) ) ;; 'test') # test 从文件中提取2级参数 local pro=( $(awk '{print $1}' /data/a.txt) ) COMPREPLY=( $(compgen -W '${pro[@]}' -- $cur) ) ;; '*') ;; esac if [[ "${COMP_WORDS[1]}" == "read" && ${COMP_CWORD} -eq 2 ]]; then local pro=($(pwd)) cd /data compopt -o nospace COMPREPLY=($(compgen -d -f -- $cur)) cd $pro fi return 0 } complete -F _foo foo
例子中, foo有3个参数,分别是 help, read, test
read 测试遍历 /data 目录下所有文件
test 测试从文件中提取2级参数
help 只是演示,没有特殊作用
共 0 条评论