bash completion 指令自动补全详解

简介

  • 什么是补全, 什么是补全规则;

  • 补全规则怎么选;

  • 补全规则怎么生成候选项;

  • compgen, complete, compopt指令;

  • 案例

项目路径

什么是补全

  • shell交互式命令行<tab>键就会触发补全;

  • 补全一般是补全参数; 当然也有补全指令; 补全可以避免使用者记忆, 减少拼写错误;

补全规则

  • 补全规则: compspec: completion specification;

  • 即为某个指令生成参数补全集合的一些脚本指令, bash内部的一些变量, bash可以提供的很多信息;

  • 生成的是一系列的单词组; 供候选补齐;

补全规则选择

  • 空指令: 使用complete -E定义的规则, 用其生成候选集合; 一般可以配置为自己常用的一些指令; 比如编译环境下生成编译指令集合;

  • 相对或绝对路径: 查找和路径完全匹配的规则; 无匹配则用其最后文件名作为指令进行规则搜索;

  • 指令: 普通指令则同样进行匹配搜索;

  • 无指令匹配: 采用complete -D定义的默认规则生成;

  • 无默认规则: 指令是否为alias, 如果是恢复原状, 使用恢复后的指令搜索; (部分版本支持)

  • 无任何匹配规则: 采用Bash的默认补全机制;

补全规则生成候选项

  • -A action 或其简写 -abcdefgjksuv 生成集合;

生成集合: 根据拼写一截的补全; 比如git sta就有补全stage stash status;根据sta过滤; -f -d生成集合会被FIGNORE过滤;

  • -G 根据文件扩张规则生成集合

比如-G "*.sh", 这个就是文件扩张生成当前目录下sh结尾的文件; 不会被sta这种影响, 会全部纳入; 但是受到FIGNORE的影响;

  • -W 字符串被${IFS}分词后的集合

-W "hello world $PATH", 进行bash的扩张后生成的字符串, 再进行bash分词规则生成字符串集合; git sta会从过滤集合中过滤前缀sta的集合; -W某些场景完全可以替代; 差距就是是否需要对集合过滤;

  • -F -C: 会生成变量; COMP_LINE, COMP_POINT, COMP_KEY, COMP_TYPE; -F还会生成COMP_WORDS, COMP_CWORD; 入参:$1指令名, $2补全名, 如sta; $3不全名前一个单词, 比如git sta, sta前一个就是git; 无过滤规则; 即生成的所有都纳入候选, 需指令提供者或函数提供者根据输入参数进行过滤;

-F优先: 是shell函数; 可以通过compgen -A function查看当前环境下的函数定义; 当然一般是局部自定义的; -F指定的function一般结合compgen, comopt使用; 返回集合通过COMREPLY数组, 即一般使用COMPREPLY=( hello world );
-C次之: 基本和-F相同, 除了没有COMP_WORDS, COMP_CWORD; 输出到标准输出的字符集按\n进行分词, 生成结果集; 可以结合\使用;

  • -X: 过滤文件扩张集合, 不会过滤-F, -C生成的集合;

过滤规则:&被替代为sta; 可以用\&保持愿意; !则是取反; shopt nocasematch可以按照不区分大小写匹配; complete -G "*" -X "!&*" todo; 完全匹配的会被删除; 保留不匹配的;

  • -P -S添加前后缀;

补充-o选项;

  • 如果前面没有任何匹配集合, 且规则指定了-o dirnames; 会将当前目录下的文件夹名纳入匹配, 并过滤; 但是如果有匹配集合这个选项就不会生效;
  • 指定了-o plusdirs; 会将目录纳入集合; 和-o dirnames区别在于, -o plusdirs一定会生效; complete -W "hello" -o plusdirs todo;
  • 如果上面的complete指定的规则; bash completion,Readline的补齐规则会被禁用; 可以通过-o bashdefault开启bash complettion,-o default开启Readline completion 作为补充手段, 这个是没有任何生成集合的时候才会生效, 有就不会生效;

  • 如果有compspec是目录, 会补全/; 可以通过一些手段规避; complete -W "hello $(find . -maxdepth 1 -mindepth 1 -type d -printf "%f\n")" todo; compgen -d生成的也没有后缀;

补充: 动态加载规则

  • 一般都是一次性的加载; 但是当我们-F的返回值是124的时候, 会重新加载当前指令的complete; 即返回124表示当前指令的规则发生了变化;
_completion_loader()
{
    
. "/etc/bash_completion.d/$1.sh" >/dev/null 2>&1 && return 124
}
complete -D -F _completion_loader -o bashdefault -o default
  • 默认规则, 用于动态生成某个指令的规则; 即使用了指令并触发才生成;

指令: compgen, complete, compopt

compgen

格式: compgen [option] [word]

  • 这个是手动触发; 即模拟complete;
  • option是可以是complete的所有选项, 除了-r, -p; -F -C在这里也不太好用; 因为相关参数没有设置;
  • word用于过滤; 即git sta案例; 可以理解为sta就是这里的word参与过滤; 没有就不过滤; 返回所有;
  • 具体使用参见后面案例

compopt

格式: compopt [-o option] [-DEI] [+o option] [name], 即控制某个指令的选项开关; 不修改其他规则;

  • -o option: 打开某个选项;
  • +o option: 关闭某个选项;
  • name: 指定具体指令, 未指定表示当前指令;
  • [-DEI]: 指定是name忽略;

complete

  • 指令原型;

complete [-abcdefgjksuv] [-o comp-option] [-DEI] [-A action]
        [-G globpat] [-W wordlist] 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值