fangpsh's blog

尝试解决openSUSE下zypper软件包名称自动补全的问题

一年前从debian 换到opensese的时候,很不习惯zypper在安装软件包的时候不能自动补全,添加到todolist里面,后来停用evernote 给忘记了,前几天上去整理笔记发现了,所以尝试性得解决了下,另外顺带修了一个小bug,当本地repo超过10条时,原来脚本生成的自动补全列表不全的问题。

bash自带补全功能,要达到更好的补全效果需要安装bash-completion这个软件包,然后编写对应的补全脚本。关于bash-completion的内容,可以参考以下两个链接:

软件包名词的自动补全问题主要就是怎么快速的获取软件包的名称,然后作为列表供选。 一开始我是用zypper search 来获取,速度不堪忍受,(apt-get,aptitude 等的自动补全脚本是用apt-cache来获取,速度很快)。

zypper se方式的脚本片段:

install | in | info | if | download )
        opts=(${opts[@]}$(echo; LC_ALL=POSIX $ZYPPER se "$curl*" 2> /dev/null | sed '1,5'd | cut -d '|' -f 2 | tr -d ' '))
        ;;
remove | rm)
        opts=(${opts[@]}$(echo; LC_ALL=POSIX $ZYPPER se -i "$curl*" 2> /dev/null | sed '1,5'd | cut -d '|' -f 2 | tr -d ' '))
        ;;
update | up)
        opts=(${opts[@]}$(echo; LC_ALL=POSIX $ZYPPER list-updates | sed '1,4'd | cut -d '|' -f 3 | tr -d ' '))
        ;;

后来看了下libzypp,又看到 zypp-NameReqPrv 这个工具,试了下,速度快了一些,基本可以用了,不过感觉还不是太理想,特别是zypper install 的时候,如果列表生成的数组过大,还是有点卡顿,瓶颈在要对zypp-NameReqPrv的输出结果做过滤。
不知道还有没有更快的方式来获取软件列表,难道只能使用libzypp来编写?
另外如果使用zsh,并且使用了on-my-zsh的话好像是可以自动补全。第一次补全时会有明显的卡顿,后面再使用就很流畅了,可能做了缓存? 不知道是怎么做到的,可以学习学习,然后迁移到bash下。

zypp-NameReqPrv 方式的脚本片段:

install | in | info | if | download )
        if test -n "$cur" ; then
                opts=(${opts[@]}$(echo; LC_ALL=POSIX $ZYPPNameReqPrv $cur | grep -E "^[:blank:]*[0-9]+[:blank:]+$cur[a-Z0-9]*-" | \
                           cut -d ' ' -f 6 | sed -r 's/-[0-9]+\..*//' |sort -u))
        fi
        ;;

remove | rm | update | up )
        if test -n "$cur" ; then
                opts=(${opts[@]}$(echo; LC_ALL=POSIX $ZYPPNameReqPrv --installed $cur | grep -E "^[:blank:]*[0-9]+[:blank:]+$cur[a-Z0-9]*-" | \
                              cut -d ' ' -f 6 | sed -r 's/-[0-9]+\..*//' |sort -u))
        fi
        ;;

使用openSUSE + bash 的同学可以试一试,把这份脚本拷贝至 /etc/bash_completion.d/ 下 。