【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作为候选的备选的补齐参数
以下是一个示例,展示了如何在 Python 中创建自定义的 Linux 自动补全提示: ```python import readline # 自定义自动补全函数 def complete(text, state): commands = ['command1', 'command2', 'command3'] # 自定义命令列表 options = [c for c in commands if c.startswith(text)] # 获取以输入文本开头的命令列表 if state < len(options): return options[state] else: return None # 将自动补全函数注册为补全提示函数 readline.set_completer(complete) readline.parse_and_bind("tab: complete") # 读取用户输入,并提供自动补全提示 while True: user_input = input('>>> ') # 处理用户输入... ``` 在这个示例中,我们使用 `readline` 模块来实现自动补全提示。首先,我们定义了一个名为 `complete` 的函数,它接受两个参数:`text` 表示用户输入的文本,`state` 表示当前补全的状态。 在 `complete` 函数中,你可以根据自己的需求定义命令列表(例如 `commands` 列表),然后根据用户输入的文本来生成匹配的选项列表(例如 `options` 列表)。最后,根据当前的补全状态,返回对应的选项。 然后,我们使用 `readline.set_completer()` 函数将自动补全函数注册为补全提示函数。使用 `readline.parse_and_bind()` 函数将 "tab" 键绑定为自动补全操作。 最后,在一个循环中读取用户输入,并在每次输入之后提供自动补全提示。你可以根据需要,将用户输入传递给相应的处理函数进行处理。 请注意,这只是一个简单的示例,你可以根据实际需求进行扩展和定制。另外,这个示例仅适用于 Linux 环境,因为 `readline` 模块在其他操作系统上可能有不同的行为或不可用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值