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

发布时间:2023年12月31日

目录

用途

小例子

说明

进阶-多级补齐

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作为候选的备选的补齐参数
文章来源:https://blog.csdn.net/bandaoyu/article/details/135312434
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。