【shell】命令行自动补全(compgen、complete、compopt)

目录

用途

小例子

说明

进阶-多级补齐

Bash自动补齐原理


用途

自编写的Shell脚本/命令,很多时候都需要输入一定的参数。当参数较多而且较复制的时候,如果能使用Tab键补全就显得非常的便利。

小例子

例如,我们自定义一个命令 footest

function  footest() { echo "function footest called $@"; }

现在想给footest这个命令添加自动补全功能,按下tab按键会自动列出word1 word2 word3 test 这些候选,执行:

complete -W 'word1 word2  wpord1 wpord2  aord3 test '  footest

试试:

footest  按tab 列出所有可以用参数

footest  w按tab 列出所有w开头的参数

footest  wp按tab 列出所有wp开头的参数

 

我想让服务器启动就给我的函数自动添加补齐功能,不用我手工执行complete 命令:

将complete -W 'word1 word2 word3 test'  footest 写入自动加载文件

# vim /etc/bash_completion.d/footest .bash

 _footest ()
{
 local cur=${COMP_WORDS[COMP_CWORD]}
 COMPREPLY=( $(compgen -W "word1 word2  wpord1 wpord2  aord3 test" -- $cur) )
}
complete -F _footest  footest   #执行function函数,把函数中生成COMPREPLY作为候选的备选的补齐参数

重启后里面生效,想要立刻加载生效,执行下面的命令:

chmod +x /etc/bash_completion.d/footest.bash

source/etc/bash_completion.d/footest.bash

说明

实现自动补全的功能,涉及到两个两个命令complete和compgen,下面分别介绍这两个命令

complete (补全命令)

这是命令补全最核心的命令了,来看下这个命令的参数说明。

omplete [-abcdefgjksuv] [-pr] [-DE] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...]

 

重点说明:

-F function

执行function函数,把函数中生成COMPREPLY作为候选的补全结果

-C command

将 command 命令的执行结果作为候选的补全 结果

-Gpattern

将匹配 pattern的文件名作为候选的补全结果

-W wordlist

分割 wordlist 中的单词,作为候选的补全结果

-p [name]

列出当前所有的补全命令

-r [name]

删除某个补全命令

 

compgen(筛选命令)

这个命令,用来筛选生成 匹配单词的 候选补全结果

compgen: compgen [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word]

重点说明:

-W wordlist

分割 wordlist 中的单词,生成候选补全列表

 

compopt(修改补全命令设置)

这个命令可以修改补全命令设置,注意了,这个命令必须在补全函数中使用,否则会报错。

重点说明:

+o option

启用 option 配置

-o option

弃用 option 配置

例如,设置命令补全后不要多加空格,方法如下:

compopt -o nospace

内置辅助变量

除了上面三个命令外,Bash还有几个内置变量来辅助补全功能,如下:

COMP_WORDS

类型为数组,存放当前命令行中输入的所有单词

COMP_CWORD

类型为整数,当前输入的单词在COMP_WORDS中的索引

COMPREPLY

类型为数组,候选的补全结果

COMP_WORDBREAKS

类型为字符串,表示单词之间的分隔符

COMP_LINE

类型为字符串,表示当前的命令行输入字符

COMP_POINT

类型为整数,表示光标在当前命令行的哪个位置

进阶-多级补齐

下面再结合前面三个补全命令(complete/compgen/compopt)和内置变量,写了例子说明下。

# cat /etc/bash_completion.d/foo.bash

_foo()

{

    COMPREPLY=()

    local cur=${COMP_WORDS[COMP_CWORD]};

    local cmd=${COMP_WORDS[COMP_CWORD-1]};

    case $cmd in

    'foo')

          COMPREPLY=( $(compgen -W 'help test read' -- $cur) ) ;;

    'test')

          local pro=( $(awk '{print $1}' /data/a.txt) )

          COMPREPLY=( $(compgen -W '${pro[@]}' -- $cur) ) ;;

    '*')

          ;;

    esac

    if [[ "${COMP_WORDS[1]}" == "read" && ${COMP_CWORD} -eq 2 ]]; then

          local pro=($(pwd))

          cd /data

          compopt -o nospace

          COMPREPLY=($(compgen -d -f -- $cur))

          cd $pro

    fi

    return 0

}

complete -F _foo foo

例子中, foo有3个参数,分别是 help, read, test

read 测试遍历 /data 目录下所有文件

test 测试从文件中提取2级参数

help 只是演示,没有特殊作用

现在跑下这个例子:

# mkdir /data

# touch /data/a.txt

# touch /data/b.txt

# tree /data

/data

├── a.txt

└── b.txt



0 directories, 2 files

# source /etc/bash_completion.d/foo.bash

# foo [Tab][Tab]

help  read  test 

# echo world1 >> /data/a.txt

# echo world2 >> /data/a.txt

# foo test world[Tab][Tab]

world1  world2 

# foo read[Tab][Tab]

a.txt  b.txt

linux下tab自动补全功能_tab怎么补全-:http://t.csdnimg.cn/4jLjd

 

Bash自动补齐原理

(摘自:Linux中Bash自动补齐原理_https://blog.csdn.net/youuzi/article/details/128903988)

这里仅介绍最常用的 bash 提供的补全功能。默认的补全脚本保存在 /etc/bash_completion.d 目录下。

但一般会安装bash-completion包来得到更好的补全效果。但bash-completion这个包的安装位置因不同的发行版本会有所区别,但是原理是类似的,一般会有个bash_completion的脚本,这个脚本会在shell初始化时加载,获取脚本的位置可以通过查看“/etc/profile.d/bash_completion.sh文件,同时也是通过这个文件导入的。

而在bash_completion脚本中会加载/etc/bash_completion.d/目录下的补全脚本。

内置补全命令

_footest()  #自定义的补齐函数

{

        local cul=${COMP_WORDS[COMP_CWORD]}

        COMPREPLY=( $(compgen -W "exec word word2" -- $cul) )

}

complete -F _footest  footest  # _footest 补齐函数,footest 被自动补齐的命令

Bash内置有两个补全命令,分别为compgen和complete,以及提供内置变量来辅助补全功能。以下用一个示例来演示。

cat /etc/bash_completion.d/footest.bash

#此处footest不是已存在的命令,所以我们自己实现一个

function  footest() { echo "function footest called $@" }

测试footest是否自动补全:

chmod +x /etc/bash_completion.d/footest.bash

source /etc/bash_complietion.d/footest.bash  #加载使其生效

[roo]# footest  

按tab

exec   word   word2

例子2

function autotab() {

    echo "function autotab called $@"

}

autotab_list=("aa" "bb" "cc" "dd" "123")

function _autotab() {

    local cur

    COMPREPLY=()

    cur="${COMP_WORDS[COMP_CWORD]}"

    COMPREPLY=( $(compgen -W "${autotab_list[*]}" -- ${cur}) )

    return 0

}

complete -F _autotab autotab

  • compopt: compopt[-o|+o option][-DE][name ...]
  • chmod +x /etc/bash_completion.d/footest.bash
  • source/etc/bash_completion.d/footest.bash
  • # cat /etc/bash_completion.d/footest .bash
  • _footest ()
  • {
  • local cur=${COMP_WORDS[COMP_CWORD]}
  • COMPREPLY=( $(compgen -W "word1 word2  wpord1 wpord2  aord3 test" -- $cur) )
  • }
  • complete -F _footest  footest   #执行function函数,把函数中生成COMPREPLY作为候选的备选的补齐参数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/280930.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用flutter开发windows桌面软件读取ACR22U设备的nfc卡片id,5分钟搞定demo

最近有个需求,要使用acr122u读卡器插入电脑usb口,然后读取nfc卡片的id,并和用户账号绑定,调研了很多方式,之前使用rust实现过一次,还有go实现过一次,然后使用electron的时候遇到安装pcsc-lite失…

ORACLE P6 v23.12 最新虚拟机(VM)全套系统环境分享

引言 根据上周的计划,我简单制作了两套基于ORACLE Primavera P6 最新发布的23.12版本预构建了虚拟机环境,里面包含了全套P6 最新版应用服务 此虚拟机仅用于演示、培训和测试目的。如您在生产环境中使用此虚拟机,请先与Oracle Primavera销售代…

python常见报错信息!错误和异常!附带处理方法

作为 Python 初学者,在刚学习 Python 编程时,经常会看到一些报错信息。 Python 有两种错误很容易辨认:语法错误和异常。 Python assert(断言)用于判断一个表达式,在表达式条件为 false 的时候触发异常。 …

【UE5蓝图】读取本地json文件修改窗口大小

效果 插件 蓝图 1.判断文件存在 2.1文件不存在,生成文件 {"ResolutionX":540, "ResolutionY":960} 2.2文件存在,直接读取 3.设置窗口大小 遇到的坑 1.分辨率太大,导致效果不理想,建议先往小填写。 2.选对…

QT 利用开源7z 实现解压各种压缩包,包括进度条和文件名的显示(zip,7z,rar,iso等50多种格式)

想做一个winRAR一样的解压软件吗?很简单,利用开源的7z库就能实现。我看网上其他人说的方法不敢苟同,误人子弟。以前自己在项目中使用过7z,这次又有需要,就想记录下来。如果你研究过如何用7z的话,一定知道7z的每一个GUID都代表了一种格式,50多种GUID也就有50多个格式,最…

Unity坦克大战开发全流程——开始场景——音效数据逻辑

开始场景——音效数据逻辑 从这里开始到后面的三小节我们都将干一件很重要的事——数据存储,只有实现了数据存储才能在再次进入游戏时保持游戏数据不被丢失。 类图分析:数据管理类是一个大类,它其中关联了两个类(这两个类都是数据…

迭代归并:归并排序非递归实现解析

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《数据结构&算法》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 📋 前言 归并排序的思想上我们已经全部介绍完了,但是同时也面临和快速排序一样的问题那就是递…

Go语言中的性能考虑和优化

优化您的Go代码以达到最佳性能 性能优化是软件开发的关键方面,无论您使用哪种编程语言。在这篇文章中,我们将探讨Go语言中的性能考虑和优化,Go是一种以其效率而著称的静态类型和编译语言。我们将深入探讨三个关键领域:分析并发代…

用CSS中的动画效果做一个转动的表

<!DOCTYPE html> <html lang"en"><head><meta charset"utf-8"><title></title><style>*{margin:0;padding:0;} /*制作表的样式*/.clock{width: 500px;height: 500px;margin:0 auto;margin-top:100px;border-rad…

【Electron】webview 实现网页内嵌

实现效果&#xff1a; 当在输入框内输入某个网址后并点击button按钮 , 该网址内容就展示到下面 踩到的坑&#xff1a;之前通过web技术实现 iframe 标签内嵌会出现 同源策略&#xff0c;同时尝试过 vue.config.ts 内配置跨域项 那样确实 是实现啦 但不知道如何动态切换 tagert …

深入浅出Java虚拟机

文章目录 总体图类装载子系统一、类的加载过程一、加载二、链接三、初始化 二、类的加载器 运行时数据区一、程序计数器(ProgramCounter)二、虚拟机栈( Java Stack )三、本地方法栈&#xff08; Native Method Stack &#xff09;四、堆内存&#xff08;Direct Memory&#xff…

51单片机的中断相关知识

51单片机的中断相关知识点 一、中断概念和功能 概念 程序执行过程中CPU会遇到一些特殊情况&#xff0c;是正在执行的程序被“中断”&#xff0c;cpu中止原来正在执行的程序&#xff0c;转到处理异常情况或特殊事件的程序去执行&#xff0c;结束后再返回到原被中止的程序处(断…

【Android12】Android Framework系列---tombstone墓碑生成机制

tombstone墓碑生成机制 Android中程序在运行时会遇到各种各样的问题&#xff0c;相应的就会产生各种异常信号&#xff0c;比如常见的异常信号 Singal 11&#xff1a;Segmentation fault表示无效的地址进行了操作&#xff0c;比如内存越界、空指针调用等。 Android中在进程(主要…

Screenshot-to-code开源项目mac上实践

github上的开源项目&#xff0c;看介绍可以将设计ui图片转换为 HTML 和 CSS 源码地址&#xff1a; GitCode - 开发者的代码家园 我的mac安装了2.7和3.11&#xff0c;就用3吧直接上代码 安装 pip3 install keras tensorflow pillow h5py jupyter 报错 ERROR: Could not in…

TCP服务器的编写(下)

我们现在开始对我们的客户端开始封装 我们的客户端&#xff0c;创建完套接字&#xff0c;需不需要bind呢&#xff1f;&#xff1f; 当然是不需要的&#xff0c;你本身是一个客户端&#xff0c;其他人写的应用也可能是客户端&#xff0c;如果我们bind&#xff0c;一定意味着我们…

Javaweb之Mybatis入门的详细解析

Mybatis入门 前言 在前面我们学习MySQL数据库时&#xff0c;都是利用图形化客户端工具(如&#xff1a;idea、datagrip)&#xff0c;来操作数据库的。 在客户端工具中&#xff0c;编写增删改查的SQL语句&#xff0c;发给MySQL数据库管理系统&#xff0c;由数据库管理系统执行S…

CentOS7安装部署Zookeeper

文章目录 CentOS7安装部署Zookeeper一、前言1.简介2.架构3.集群角色4.特点5.环境 二、正文1.部署服务器2.基础环境1&#xff09;主机名2&#xff09;Hosts文件3&#xff09;关闭防火墙4&#xff09;JDK 安装部署 3.单机部署1&#xff09;下载和解压2&#xff09;配置文件3&…

linux文件夹介绍

在linux内核文件夹下面存在着许多文件夹&#xff0c;那么那些文件夹是什么用处呢&#xff0c;下面将为你介绍。 (1)documentation 这个文件夹下没有内核代码&#xff0c;仅仅有一套实用的文档&#xff0c;但这些文档的质量不一。比如内核文档的文件系统&#xff0c;在该文件夹下…

动态路由传参与查询参数传参详情

动态路由传参 路由规则path :/article/:aid 组件获取参数: this. $route. params.aid 如果想要所有的值&#xff0c;就用this. $route. params 注意&#xff1a;这两个必须匹配 如果是多个参数&#xff0c;path :/article/:aid/:name就写两个参数 接收方式一&#xff1a; 在…

Javaweb-servlet

一、servlet入门 1.Servlet介绍 (1)什么是Servlet Servlet是Server Applet的简称&#xff0c;是用Java编写的是运行在 Web 服务器上的程序&#xff0c;它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。使用 Servlet&#…