您的位置:首页 > 运维架构 > Shell

bash的按TAB键自动补全(自动完成)的原理与扩展

2015-12-28 15:34 429 查看
最近在用源码安装ceph,发现命令不能自动补全,然后找到了下面这篇文章,写的很好~转载一下~

源码安装ceph命令没法自动补全的解决方法:把ceph-deploy安装的可以自动补全的系统里/etc/bash_completion.d下ceph的文件scp到源码安装对应的位置,然后“.
/etc/bash_completion”就可以了~(注意点 . 号)

下面是正片环节~

用过bash的人,可能都对TAB自动补全功能有印象吧,按一下“TAB“键就自动帮你把命令或者文件名补全,确实好用。

这个应该是bash解析用户输入的时候,加上这个自动补全的功能的。方便的地方是bash提供的内置命令complete允许你对这个功能进行自定义扩展。 比如

complete -F _my_host my_ssh 就会指定 my_ssh这个名字的自动完成由 _my_host 这个函数去处理

比如我在 .bashrc 后面加上下面这个代码之后

----------------------------------------------

_my_host() {

local HOST cur

COMPREPLY=()

_get_comp_words_by_ref cur

HOST="local test test2 devolop"

COMPREPLY=( $( compgen -W "$HOST" -- "$cur" ) )

}

complete -F _my_host my_ssh

alias egenera_ssh=/home/widebright/桌面/my_ssh.pl

-----------------------------------------------

这样设置之后,在终端再输入自己的自定义命令my_ssh 然后按TAB键,就会自动出来自己预先定义的host主机名字了

---------------

widebright@:~/桌面$ my_ssh

local test test2 devolop

-------------------------

其中COMPREPLY 是Bash的内置变量,一个数组,返回结果到这里去后,bash就是读取这个变量作为自动完成的匹配组合的。

compgen -W "$HOST" -- "$cur" 命令根据当前的输入"$cur" 返回$HOST中匹配的部分。compgen也是内置命令的。_get_comp_words_by_ref 是预定义函数,不过自己从COMP_WORDS
和COMP_CWORD两个预定义变量中去读取当前输入信息。COMP_WORDS表示当前命令输入参数的单词数组,COMP_CWORD表示当前光标的 位置。参考一个例子

------------------------

_xm()

{

local cur prev opts base

COMPREPLY=()

cur="${COMP_WORDS[COMP_CWORD]}"

prev="${COMP_WORDS[COMP_CWORD-1]}"

#

# The basic options we'll complete.

#

opts="console create list"

#

# Complete the arguments to some of the basic commands.

#

case "${prev}" in

console)

local running=$(for x in `xm list --long | grep \(name | grep -v Domain-0 | awk '{ print $2 }' | tr -d
\)`; do echo ${x} ; done )

COMPREPLY=( $(compgen -W "${running}" -- ${cur}) )

return 0

;;

create)

local names=$(for x in `ls -1 /etc/xen/*.cfg`; do echo ${x/\/etc\/xen\//} ; done )

COMPREPLY=( $(compgen -W "${names}" -- ${cur}) )

return 0

;;

*)

;;

esac

COMPREPLY=($(compgen -W "${opts}" -- ${cur}))

return 0

}

complete -F _xm xm

------------------------------------

complete 命令的和预定义的详细说明可以参考bash的文档。

启动complete -p 可以查看bash已经定义的命令的自动完成函数。

现 在有一个叫做“Bash Completion http://bash-completion.alioth.debian.org/ “的包,已经定义了很多名字的自动完成的处理函数了。只要你 “. /etc/bash_completion”
一下这些就全部可以用了。不过这个应该不用自己作了,我转了ubuntu,都自动配置好了吧。不如在这个/etc/bash_completion.d这 个目录下就还有很多命令的例子,比如:

/etc/bash_completion.d/apache2ctl

------------------------------------------------------

# apache2ctl(1) completion

have apache2ctl && {

_apache2ctl() {

local APWORDS cur

COMPREPLY=()

_get_comp_words_by_ref cur

APWORDS=$(apache2ctl 2>&1 >/dev/null | awk 'NR<2 { print $3; exit }' | \

tr "|" " ")

COMPREPLY=( $( compgen -W "$APWORDS" -- "$cur" ) )

}

complete -F _apache2ctl apache2ctl

}

# Local variables:

# mode: shell-script

# sh-basic-offset: 4

# sh-indent-comment: t

# indent-tabs-mode: nil

# End:

# ex: ts=4 sw=4 et filetype=sh

---------------------------------------------------

一个比较ubuntu 14.04可用的例子

root@debian01:/opt/smsc# cat /etc/bash_completion.d/smsc_ctl

# smsc completion

function_exists()
{
declare -F $1 > /dev/null
return $?
}

_smsc_ctl_auto_complete() {
local cur cmds

COMPREPLY=()
local cur prev cmds

COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
prev=${COMP_WORDS[COMP_CWORD-1]}

cmds="compile status start stop restart clean"

if [ $COMP_CWORD -eq 1 ]; then
COMPREPLY=( $( compgen -W "$cmds" -- "$cur" ) )
elif [ $COMP_CWORD -eq 2 ]; then
smsc_ctl=${COMP_WORDS[0]}
sam_files=`$smsc_ctl ls`
case "$prev" in
"start")
COMPREPLY=( $( compgen -W "all $sam_files" -- "$cur" ) )
;;
"stop")
COMPREPLY=( $( compgen -W "all $sam_files" -- "$cur" ) )
;;
*)
COMPREPLY=( $( compgen -W "all $sam_files" -- "$cur" ) )
;;
esac

fi

}

complete -r ./smsc_ctl
complete -r smsc_ctl

complete -F _smsc_ctl_auto_complete smsc_ctl

---------------------------

很多时候,自己往系统里面加了一些命令或者程序之后,自己再定义一个“自动完成”的处理给他,会方便很多的吧。

参考文章

8.6 Programmable Completion
https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion.htmlAn introduction to bash completion:

8.7 Programmable Completion Builtins
https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion-Builtins.html#Programmable-Completion-Builtins An introduction to bash completion: part 1 http://www.debian-administration.org/articles/316 http://www.debian-administration.org/article/An_introduction_to_bash_completion_part_2
More on Using the Bash Complete Command http://www.linuxjournal.com/content/more-using-bash-complete-command
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: