Linux Shell 命令自动补全(各方资料汇总补全版)
在下所在的公司定义了一种路径,配合自定义的 loader 命令;遂命令在下完成自定义路径的自动补全需求。关于Linux Shell命令自动补全已有的一些优秀 blog没有开花的树的《详解Linux Shell命令自动补全》这篇文章讲得比较系统,最后给的 demo 也特别优秀。Linux中10个关于命令行自动补全的技巧注意这篇文章中的第10条:如果定义的补全规则没有生...
·
在下所在的公司定义了一种路径,配合自定义的 loader 命令;遂命令在下完成自定义路径的自动补全需求。
关于Linux Shell命令自动补全已有的一些优秀 blog
- 没有开花的树的《详解Linux Shell命令自动补全》
- 这篇文章讲得比较系统,最后给的 demo 也特别优秀。
- Linux中10个关于命令行自动补全的技巧
- 注意这篇文章中的第10条:如果定义的补全规则没有生成匹配时,可以使用 -o 选项生成补全。强烈建议使用
-o default
,这样在没有补全项的情况下可以走系统默认的。
- 注意这篇文章中的第10条:如果定义的补全规则没有生成匹配时,可以使用 -o 选项生成补全。强烈建议使用
- 【Bash百宝箱】shell命令行自动补全(compgen、complete、compopt)
- 这篇文章的参数详解非常值得参考。
本人遇到的一些需求及解决方案:
需求一:从多个路径下获取补全候选项,并做去重
- 解决方案写一个循环获取所有候选项,并且去重。这里记录一下 shell数组去重 ,和数组的使用。
array=()
array[0]="hello"
array[1]="hello"
# 数组去重(从一个贴吧里找到的,非原创)
array=($(awk -vRS=' ' '!a[$1]++' <<< ${array[@]}))
# 数组的使用(同样非原创,找不到链接了)
COMPREPLY=($(compgen -W "${array[*]}" -- "he"))
需求二:自定义路径 转化成 系统路径
- 比如:我需要把
test:hello.world
转成/.../hello/world
- 这里需要注意的:COMP_WORDS 切割方式是按 COMP_WORDBREAKS 进行切割的。所以
test:hello.world
会被当成三个单词test
、:
、hello.world
;所以 COMP_CWORD 会增加得比较快。(都是坑=_=)
[root@localhost ~]# echo $COMP_WORDBREAKS
"'@><=;|&(:
- 所以就有人有这样的需求:删除或者添加 COMP_WORDBREAKS,比如,我希望
.
当成分隔符,或者我希望:
不是分割符。注意:千万别去改COMP_WORDBREAKS。这里首推 StackOverflow 的帖子,好久远的帖子了。
- 对于删除分隔符,使用
_get_comp_words_by_ref -n : xxxxx
就可以把因:
分割的单词拼起来。大家可以百度一下 _get_comp_words_by_ref 这个关键字,印象中有人详解过。 - 对于添加分隔符,我参考了LinuxQuestions的帖子。思路是,自己把
.
作为分隔符切分,然后作为前缀在单词补全后补上,同时对于其他特殊字符,也可以作为后缀补上。
- 对于删除分隔符,使用
local pro=($(pwd))
local prefix=${cur%%.*}
cd $dict_path"/"$prefix
compopt -o nospace
COMPREPLY=( $(compgen -S "#" -P $prefix"." -d -f -- ${cur#*"."}) )
cd $pro
- 将 cur 从右边数最后一个
.
的左边的内容作为前缀,利用compgen
的-P
参数,这是增加前缀的参数。如果不加前缀,就会出现test.f
,你希望f
补全为father
,整体变成test.father
,这是你希望得到的。请注意,补全是整个单词补全,所以没有前缀的情况下,test.
是会被删掉的,你只能得到father
,所以test.
必须首先抽出来当做前缀,然后补全得到father
后拼到前面得到test.father
。(在下语文水平不好,希望描述清楚了这个巨坑)。同理,补全是补全单词,不会带像cd
命令一样的/
,所以如果想自动补全/
,使用-S
参数,增加后缀(代码中我增加了#
后缀)。 compopt -o nospace
是将补全后自动加的空格删掉。
补充:/etc/bash_completion.d 目录下的补全脚本不生效
- 有可能遇到将脚本放到
/etc/bash_completion.d
目录下不生效的情况,原因可能是:缺少/etc/profile.d/bash_completion.sh
(根据为什么/etc/bash_completion.d 下面的bash自动补全脚本不生效)
结束语
折腾了两天,全程 tab 起飞,放飞自我。当然其中还学习了一些 shell 命令的基本写法,假装自己是运维。路漫漫其修远兮,加油加油!
更多推荐
已为社区贡献1条内容
所有评论(0)