linux shell中的命令自动补全(compgen complete)与 命令行参数解析

标签: shell脚本
2013-12-31 21:56 6661人阅读 评论(6) 收藏 举报
分类:
linux shell(1)

版权声明:本文为博主原创文章,未经博主允许不得转载。

很多时候,当我们写一个脚本时,我们总会提供一些可选的命令选项。当可选项比较多的时候,比如git, 如果能够提供命令自动补全,无疑是锦上添花的事。而且个人认为,这种方式,比采用将命令做成选择菜单要更好一些。

假设我们现在这样一个脚本,脚本执行命令时bsu,  类似git,脚本有两个一级主命令pushbaseline, createrepo,然后这两个一级主命令下还有若干选项

pushbaseline  --qcom  --mtk  --name=(NX01, NX02)     #要求  --qcom --mtk不能同时出现,- -name=xxx可以与前面任意一个选项同时出现

createrepo   --git  --repo  --name=xxx  --auth=(W, R, RW) # 同上,这里--git, --repo不能同时出现。 后面两个选项随意

正式行动之前我们做一个简单的需求分析,正所谓不做需求分析就干活,“加班没日夜, 累死也枉然

以pushbaseline为例,这里要求--qcom --mtk不能同时出现,如果直接在脚本中实现,就要判断之前输入中有没有输入--qcom,如果有输入,就不能再把--mtk作为命令自动补全的候选者。这种逻辑很复杂,对shell脚本不熟的人,只能望洋兴叹——“呵呵”。

事实上,从实际情况来看的话,为什么不能同时出现,因为它们都属于某个属相的描述,所以这里简单的改为--platfrom=(qcom, mtk),问题就巧妙解决了。

下面开始写脚本,上面将--qcom --mtk 改编为--platform=(qcom,mtk),缺少了简单选项,为此再额外加一个 --multi

自动补全,linux提供了两个重要命令 compgen, complete

命令:compgen -W "aa ab bb cc" -- “a”

表示从"aa ab bb cc"  匹配出以“a”开头的单词

这条命令的返回结果就是 “aa ab”。

命令:complete -F  __cmd_HUB  bsu

表示当执行bsu命令时,自动补全的候选单词由函数__cmd_HUB计算得到,具体的承载容器是变量COMPREPLY

特别说明一下,像这样的complete -F XXX   ./test.sh  也是合法的。如果XXX的计算后得到COMPREPLY=(aa bb cc), 则输入 ./test.sh 之后, 按tab键,可以自动弹出候选选项aa bb cc。

解释的话说的有点多,下面直奔主题了

[plain] view plaincopy
  1. function __cmd_HUB() {
  2. #$COMP_CWORD是系统自动变量,表示当前命令单词索引。 0表示第一个单词,也就是bsu。
  3. case $COMP_CWORD in
  4. 0)  #仍在完成根命令,这里不需要处理
  5. ;;
  6. 1)  #根命令已经完成,这里开始补充一级主命令
  7. #${COMP_WORDS[0]}是根命令,在这个例子中就是bsu
  8. eval __cmd_${COMP_WORDS[0]}
  9. ;;
  10. 2|*)#一级主命令已经完成,这里开始补充一级主命令的选项
  11. #${COMP_WORDS[1]}是一级主命令,在这个例子中就是pushbaseline或者createrepo
  12. eval __cmd_${COMP_WORDS[1]}
  13. ;;
  14. esac
  15. }
  16. complete -F __cmd_HUB bsu

如果有同学对eval命令不了解,就找度娘吧。

上面我们做了一个约定,要获取命令<command>的选项,则总是调用函数__cmd_<command>获得,因此下面就要实现__cmd_bsu, __cmd_pushbaseline, __cmd_createrepo

[plain] view plaincopy
  1. function __cmd_bsu() {
  2. local cur="${COMP_WORDS[COMP_CWORD]}"
  3. local options="$MAIN_COMMAND"
  4. COMPREPLY=( $(compgen -W "${options}" -- ${cur}) )
  5. }
[plain] view plaincopy
  1. function __cmd_pushbaseline() {
  2. local cur="${COMP_WORDS[COMP_CWORD]}"
  3. COMPREPLY=()
  4. case $cur in
  5. --name=*)
  6. local options="NX01 NX02"
  7. COMPREPLY=( $(compgen -W "${options}" -- ${cur#--name=}) )
  8. ;;
  9. --platform=*)
  10. local options="qcom mtk"
  11. COMPREPLY=( $(compgen -W "${options}" -- ${cur#--platform=}) )
  12. ;;
  13. *)
  14. local options="--platform= --name= --multi"
  15. COMPREPLY=( $(compgen -W "${options}" -- ${cur}) )
  16. ;;
  17. esac
  18. }

命令自动补全都到此为止,篇幅有点长了,下面长话短说,直接处理命令,以命令 bsu  pushbaseline --platform=qcom   --name=NX01 --multi 为例

在bsu函数中完成命令转发,在各个子命令中详细解析参数

[plain] view plaincopy
  1. function bsu() {
  2. case $1 in
  3. pushbaseline)
  4. shift
  5. __parsing_pushbaseline $@
  6. ;;
  7. createrepo)
  8. shift
  9. __parsing_createrepo $@
  10. ;;
  11. *)
  12. echo "unknown command $1"
  13. ;;
  14. esac
  15. }
  16. function __parsing_pushbaseline() {
  17. while [ $# -gt 0 ]; do
  18. case $1 in
  19. --platform=*)
  20. local platform=${1#--platform=}
  21. ;;
  22. --name=*)
  23. local name=${1#--name=}
  24. ;;
  25. --multi)
  26. local multi=1
  27. ;;
  28. esac
  29. shift
  30. done
  31. bsu_pushbaseline $platform $name $multi
  32. }
  33. function bsu_pushbaseline()
  34. {
  35. echo bsu_pushbaseline $@
  36. }

解析命令的关键一点,对于--xxx=YY的选项,可以使用模式匹配运算符快速得到想要的选项。这里简单起见,没有将代码做很多的形式化,有需要的话,只要利用eval函数,相信难不倒各位看官。

over,happy new year to everyone!

linux shell中的命令自动补全(compgen complete)与 命令行参数解析相关推荐

  1. Docker 命令自动补全必须有

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 前言 不知道这个小伙伴有多久没用过 Docker 了, ...

  2. linux的compgen命令,linux shell中的命令自动补全(compgen complete)与 命令行参数解析...

    很多时候,当我们写一个脚本时,我们总会提供一些可选的命令选项.当可选项比较多的时候,比如git, 如果能够提供命令自动补全,无疑是锦上添花的事.而且个人认为,这种方式,比采用将命令做成选择菜单要更好一 ...

  3. shell编程-使用complete实现linux命令自动补全

    一.背景介绍 我们在linux终端操作的时候经常使用tab按键自动补全命令.那么这个是怎么实现的呢?当自己写脚本的时候如何让用户也能自动补全呢?linux提供了两个重要的命令帮助我们实现: compg ...

  4. 实现 npm script 命令自动补全

    实现 npm script 命令自动补全 当 npm script 里面积累的命令越来越多时,重度命令行用户肯定会好奇,能不能实现类似 bash.zsh 里面的命令自动补全?答案是肯定的,下面来逐一介 ...

  5. python tab键自动补全_设置python中TAB键自动补全方法

    设置python中TAB键自动补全方法 一.创建自动补全脚本如下: vi /tmp/python/tab.py #!/usr/bin/python # python tab file import s ...

  6. 笔记:Docker命令自动补全

    笔记:Docker命令自动补全 一 背景 作为一名 Linux 重度用户,每次敲命令总会情不自禁地按下 Tab 键.在键入 Docker 命令时也会出现类似的习惯性动作.那么是否 Docker 相关命 ...

  7. Python命令行自动补全和记录历史命令

    2019独角兽企业重金招聘Python工程师标准>>> ~$ cat .pythonstartup import os import readline import rlcomple ...

  8. mac git 命令自动补全

    2019独角兽企业重金招聘Python工程师标准>>> mac git 命令自动补全 1.检查是否装了brew $ brew list如果没有,拷贝以下命令到终端 回车.可以安装好b ...

  9. 配置 OpenStack 命令 自动 补全

    配置 openstack 命令行 自动补全 The complete command is inherited from the python-cliff library, it can be use ...

最新文章

  1. fpm制作mysql rpm包_fpm制做mysql-5.6.33 rpm包
  2. 快上车!2021次“网易云信号”回顾列车发车啦!
  3. Opencv实现利用滑动条来调整阈值
  4. 设计模式(一)预备知识
  5. 关于Spring 任务调度之task:scheduler与task:executor配置的详解
  6. opencv 叠加两张图_OpenCV基础篇之图片叠加
  7. 画圆角 - HTML5 Canvas 作图
  8. Redis 主从复制的实现及配置
  9. 总结:Oracle 递归查询
  10. 使用Magoshare for Mac无法打开恢复的文件或扫描后找不到丢失的文件怎么办?
  11. 笔记:心理学中的“皮格马利翁效应”
  12. mysql中single是什么意思_single是什么意思
  13. TypeError: set expected at most 1 arguments, got 4
  14. java 九宫格数独_玩转数独之九宫数独进阶技巧
  15. 笔试题??智商题??
  16. 瑞盟MS2358 96KHz、24bit音频ADC芯片--DFN12 封装
  17. fatal: You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists). Please, commit your change
  18. 11.selenium登录126邮箱出现定位问题解决
  19. CVE-2014-6321 schannel堆溢出漏洞分析
  20. 作为一个精神病人是一种怎样的体验?

热门文章

  1. 手动配置mysql_手动配置Mysql,无需安装的方法以及Mysql的一些基本命令
  2. leetcode算法题--栈的压入、弹出序列
  3. 【hiho】38 二分·二分答案【二分答案】
  4. idea没有错误出现红色波浪线怎么去掉?
  5. 从javascript发展说到vue
  6. 教你怎么快速配置 React
  7. MySQL使用INSERT插入多条记录
  8. Android 实现文件上传功能(upload)
  9. 【Mrak】C# 文本文件 ANSI编码格式 转 UTF8
  10. Linux流量监控工具 - iftop用法