目录
自编写的Shell脚本/命令,很多时候都需要输入一定的参数。当参数较多而且较复制的时候,如果能使用Tab键补全就显得非常的便利。
例如,我们自定义一个命令 footest
function? footest() { echo "function footest called $@"; }
现在想给footest这个命令添加自动补全功能,按下tab按键会自动列出word1 word2 word3 test 这些候选,执行:
complete -W 'word1 word2? wpord1 wpord2? aord3 test '? footest
试试:
footest? 按tab 列出所有可以用参数
footest? w按tab 列出所有w开头的参数
footest? wp按tab 列出所有wp开头的参数
?
我想让服务器启动就给我的函数自动添加补齐功能,不用我手工执行complete 命令:
将complete -W 'word1 word2 word3 test' ?footest 写入自动加载文件
# vim?/etc/bash_completion.d/footest .bash
_footest ()
{
local cur=${COMP_WORDS[COMP_CWORD]}
COMPREPLY=( $(compgen -W "word1 word2 wpord1 wpord2 aord3 test" -- $cur) )
}
complete -F _footest footest #执行function函数,把函数中生成COMPREPLY作为候选的备选的补齐参数
重启后里面生效,想要立刻加载生效,执行下面的命令:
chmod +x /etc/bash_completion.d/footest.bash
source/etc/bash_completion.d/footest.bash
实现自动补全的功能,涉及到两个两个命令complete和compgen,下面分别介绍这两个命令
complete (补全命令)
这是命令补全最核心的命令了,来看下这个命令的参数说明。
omplete [-abcdefgjksuv] [-pr] [-DE] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...]
?
重点说明:
-F function | 执行function函数,把函数中生成COMPREPLY作为候选的补全结果 |
-C command | 将 command 命令的执行结果作为候选的补全 结果 |
-Gpattern | 将匹配 pattern的文件名作为候选的补全结果 |
-W wordlist | 分割 wordlist 中的单词,作为候选的补全结果 |
-p [name] | 列出当前所有的补全命令 |
-r [name] | 删除某个补全命令 |
?
compgen(筛选命令)
这个命令,用来筛选生成 匹配单词的 候选补全结果
compgen: compgen [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word]
重点说明:
-W wordlist | 分割 wordlist 中的单词,生成候选补全列表 |
?
compopt(修改补全命令设置)
这个命令可以修改补全命令设置,注意了,这个命令必须在补全函数中使用,否则会报错。
重点说明:
+o option | 启用 option 配置 |
-o option | 弃用 option 配置 |
例如,设置命令补全后不要多加空格,方法如下:
compopt -o nospace
内置辅助变量
除了上面三个命令外,Bash还有几个内置变量来辅助补全功能,如下:
COMP_WORDS | 类型为数组,存放当前命令行中输入的所有单词 |
COMP_CWORD | 类型为整数,当前输入的单词在COMP_WORDS中的索引 |
COMPREPLY | 类型为数组,候选的补全结果 |
COMP_WORDBREAKS | 类型为字符串,表示单词之间的分隔符 |
COMP_LINE | 类型为字符串,表示当前的命令行输入字符 |
COMP_POINT | 类型为整数,表示光标在当前命令行的哪个位置 |
下面再结合前面三个补全命令(complete/compgen/compopt)和内置变量,写了例子说明下。
# 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')
????????? COMPREPLY=( $(compgen -W 'help test read' -- $cur) ) ;;
??? 'test')
????????? 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 只是演示,没有特殊作用
现在跑下这个例子:
# mkdir /data
# touch /data/a.txt
# touch /data/b.txt
# tree /data
/data
├── a.txt
└── b.txt
0 directories, 2 files
# source /etc/bash_completion.d/foo.bash
# foo [Tab][Tab]
help? read? test?
# echo world1 >> /data/a.txt
# echo world2 >> /data/a.txt
# foo test world[Tab][Tab]
world1? world2?
# foo read[Tab][Tab]
a.txt? b.txt
linux下tab自动补全功能_tab怎么补全-:http://t.csdnimg.cn/4jLjd
?
(摘自:Linux中Bash自动补齐原理_https://blog.csdn.net/youuzi/article/details/128903988)
这里仅介绍最常用的 bash 提供的补全功能。默认的补全脚本保存在 /etc/bash_completion.d 目录下。
但一般会安装bash-completion包来得到更好的补全效果。但bash-completion这个包的安装位置因不同的发行版本会有所区别,但是原理是类似的,一般会有个bash_completion的脚本,这个脚本会在shell初始化时加载,获取脚本的位置可以通过查看“/etc/profile.d/bash_completion.sh文件,同时也是通过这个文件导入的。
而在bash_completion脚本中会加载/etc/bash_completion.d/目录下的补全脚本。
内置补全命令
_footest()? #自定义的补齐函数
{
??????? local cul=${COMP_WORDS[COMP_CWORD]}
??????? COMPREPLY=( $(compgen -W "exec word word2" -- $cul) )
}
complete -F _footest ?footest? # _footest 补齐函数,footest 被自动补齐的命令
Bash内置有两个补全命令,分别为compgen和complete,以及提供内置变量来辅助补全功能。以下用一个示例来演示。
cat /etc/bash_completion.d/footest.bash
#此处footest不是已存在的命令,所以我们自己实现一个
function? footest() { echo "function footest called $@" }
测试footest是否自动补全:
chmod +x /etc/bash_completion.d/footest.bash
source /etc/bash_complietion.d/footest.bash? #加载使其生效
[roo]# footest ?
按tab
exec?? word?? word2
例子2
function autotab() {
??? echo "function autotab called $@"
}
autotab_list=("aa" "bb" "cc" "dd" "123")
function _autotab() {
??? local cur
??? COMPREPLY=()
??? cur="${COMP_WORDS[COMP_CWORD]}"
??? COMPREPLY=( $(compgen -W "${autotab_list[*]}" -- ${cur}) )
??? return 0
}
complete -F _autotab autotab