自定义Bash自动完成

Bash的自动完成功能很爽,它不知道免掉我多少记忆的负担,节约了多少键盘操作。 但是对于我们自己写的脚本也能够利用它的自动完成功能吗?回答是肯定的。下面以几个例子来说明。

程序员需要记忆很多东西,bash, vi, screen, svn都有很多命令和快捷键,偏偏我的记忆力不行,不时查看cheatsheet,每次都cd到某个目录,从一大堆文件中找到那个文件,然后再打开,这个过程显然很烦琐。所以我写了一个脚本,叫做quickref,它接收一个参数,例如bash, vi,然后就会打开对应的cheatsheet。
quickref:

#!/bin/bash

case $1 in
bash)
exo-open ~/dropbox/cheatsheets/bash/bash_cheat_sheet.pdf
;;
vi)
exo-open ~/dropbox/cheatsheets/vi_cheat_sheet.pdf
;;
# more...
esac

exo-open是xubuntu下的命令,它自动用文件关联的应用程序打开, 例如, pdf文件就会用evince打开。ubuntu下对应的命令是gnome-open。

如果只有bash, vi的cheatsheet,一切不成问题,但是当列表越来越长,问题就来,你不知道你的命令能够接受哪些参数,输入命令时你得考虑,我该输入什么呢?可能还得来回折腾几次,最坏的情况,你可能需要查看源代码才能确定你到底能输入什么。你可以将它们显示在出错消息中,这样可以节省一些功夫,但总不太好。我们可以利用Bash的自动完成功能,我不再担心会输入错误。

我们直接来看怎么做,建立一个文件quickref_completion, 输入以下内容:

_quickref_completion()
{
local cur
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
COMPREPLY=($( compgen -W 'bash vi' -- $cur ))

return 0
}
complete -F _quickref_completion quickref

然后执行命令". quickref_complection",然后再在bash下输入"quickref ",然后再按Tab(或许得按两次Tab),你会发现bash自动列出所有匹配的結果,下面是我的机器上的显示結果:

$ quickref
bash vi
$ quickref

怎么实现的呢?其实很简单,_quickref_completion函数用来完成主要的功能,前三行用来得到用户当前的输入,全部补全的結果放在COMPREPLY数组中。这里补全的功能由compgen命令来完成,它完成的功能就是从单词列表中选出匹配给定前缀的所有单词,你最后在命令行下测试一下:

$ compgen -W "find fine hello"
find
fine
hello
$ compgen -W "find fine hello" fi
find
fine

最后complete命令用来注册自动补全函数,第一个参数就是自动补全的函数,后面的参数是应用这个补全函数的所有命令。执行quickref_completion的操作最好放在bashrc中去。

再一个例子,我经常用到命令"sudo apt-get install"命令,所以我给它定义了一个别名:"alias pkginstall='sudo apt-get install'",但这样不好的是,你不能再利用apt-get install的自动完成功能。另外我也定义了别名"alias pkgremove='sudo apt-get remove", 我为它们写了自动补全的函数:

_pkginstall_completion()
{
local cur

COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
COMPREPLY=( $( apt-cache pkgnames -- $cur ) )
}
complete -F _pkginstall_completion pkginstall

_pkgremove_completion()
{
local cur

COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
COMPREPLY=( $( dpkg -l | awk '{ print $2 }' | grep "^${cur}" ) )
}
complete -F _pkgremove_completion pkgremove

代码就不再解释了,很简单,至于用到的命令,不熟悉的在命令行下试试就知道了。

当然这里所介绍的只是十分简单,但于我已经够用了,至少到目前为止是这样。但要完成更加复杂的功能,例如对于不同的选项,使用不同的命令完成,例如apt-get install和apt-get remove的自动补全就不一样,你可能需要参考其它文章。/etc/complete.d/目录下有很多补全函数的实现,你可以拿来看一下。也可能参考官方文章[url=http://www.gnu.org/software/bash/manual/bashref.html#Programmable-Completion]Programmable-Completion[/url].
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值