Linux shell 脚本自动补全

sh/bash/dash/ksh/zsh等Shell脚本
回复
头像
Crazier
帖子: 1051
注册时间: 2007-09-23 17:06
联系:

Linux shell 脚本自动补全

#1

帖子 Crazier » 2014-05-06 11:28

经常用Linux都会用到Shell的自动补全功能:输入部分命令,按两个Tab键就可以把完整的命令或路径调出来了。这个功能功能减少了用户的记忆和操作步骤,可以提高工作效率。但是Shell的强大不仅在于把命令、文件名补全,它还可以自动补全变量、用户名、路径、文件名、路径、服务、job,更方便的是你可以为自己的命令量身定作一套自己的补全方式。

比如经常使用的tar命令,按tab默认是打印出来所在文件夹下所有的文件,如果可以只打印出来.tar后缀的岂不是更好。那你可以这么做:

complete -f -X '!*.tar*' tar

效果如下:
bash_tar.gif
complete比较常用的参数为:

代码: 全选

-c: 补全的对象是Linux下的命令

-f:补全的对象是文件

-d:补全的对象是目录

-X:对补全的对象进行正则过滤

-F:如果上面这些还满足不了你的要求,就可以使用该参数了,它主要是通过使用自定义函数来为你的脚本制定补全规则。
我有一个脚本viewlog,它的参数是

代码: 全选

viewlog -s servicename -t logtype
其中servicename为 /data/applog目录下的文件名,logtype为debug error key perform run中的一种。

想实现的效果是:输入viewlog时可以自动补全出-t -s , 输入-s时可以自动补全出/data/applog下的文件,-t时则可以自动补全出debug error key perform run中的一种

这就要用到complete中的-F参数了。

其实Bash_complete的工作依赖两个内置函数,complete和compgen,

Complete指定每个参数依赖什么样的规则来补全;

Compgen则根据complete的规则来生成符合规则的补全对象。

Compgen的使用方法是:

代码: 全选

compgen -W "${opts}" -- ${cur}
上面的opts是所有可能的要补全的参考对象。Cur则是目前已经提供给compgen的字符串,我们来看一个例子。

代码: 全选

pengzhanwu@ISD_223_122_sles10_64:~/complete> compgen -W "debug   error error2 key     perform run" -- "err"

error

error2
可以看到compgen就是把opts中与cur匹配的字符串列出来。

Complete的-F参数需要自己按照你对脚本补全的要求来写一个函数,该函数中默认使用的变量有:

代码: 全选

COMPREPLY: 是一个数组,里面包含的是补全匹配的结果

COMP_WORDS:一个包含在命令行中输入的字符串的数组

COMP_CWORD:COMP_WORDS数组中的下标。
以下为脚本_viewlog的内容:

代码: 全选

_viewlog()
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    opts="-s -t"

    #参数-s需要补全/data/applog目录下的服务
    if [[ ${prev} == "-s" ]]
    then
      
        local servicename=$(ls -l /data/applog | grep ^d | awk '{print $9}')
        COMPREPLY=( $(compgen -W "${servicename}" -- ${cur}) )
        return 0
    fi
    #-t的补全对象为"debug error key perform run"
    if [[ ${prev} == "-t" ]]
    then
    local logtypes="debug error key perform run"
        COMPREPLY=( $(compgen -W "debug error key perform run" -- ${cur}) )
	return 0
    fi

    #只输入viewlog时,补全该命令可选的参数
    COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )

}

complete -F _viewlog viewlog
需要把脚本文件复制到/etc/bash_completion.d目录上,理论上放到该目录下即可自动加载,但是我这边好像不行。所以仍然需要在

代码: 全选

sudo echo ". /etc/bash_completion.d/viewlog_complete" >>/etc/profile.d/complete.bash
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

Re: Linux shell 脚本自动补全

#2

帖子 eexpress » 2014-05-06 11:56

# source compat completion directory definitions
if [[ -d $BASH_COMPLETION_COMPAT_DIR && -r $BASH_COMPLETION_COMPAT_DIR && \
-x $BASH_COMPLETION_COMPAT_DIR ]]; then
for i in $(LC_ALL=C command ls "$BASH_COMPLETION_COMPAT_DIR"); do
i=$BASH_COMPLETION_COMPAT_DIR/$i
[[ ${i##*/} != @($_backup_glob|Makefile*|$_blacklist_glob) \
&& -f $i && -r $i ]] && . "$i"

done
fi

看-r

就是source 这里面的。/etc/bash_completion.d/
● 鸣学
头像
tracyone
帖子: 866
注册时间: 2010-11-19 14:25
系统: 乌班图
来自: onetracy.com
联系:

Re: Linux shell 脚本自动补全

#3

帖子 tracyone » 2014-05-06 13:19

oh-my-zsh
回复