2

为了让脚本的命令行开关轻松完成 bash,我一直在探索 /etc/bash_completion(debian sid、bash v4.2-1、bash-completion v1:1.99-3)中的 _parse_help 函数。

我的脚本会生成一条我认为是标准 GNU 格式的帮助消息:

MYSCRIPT [OPTIONS]

Usage:
  -h, --help     Show this help message
  -o, --option   Some option

然后我通过 激活完成complete -F _parse_help ./myscript

不幸的是,这并没有给出预期的结果。在第一个选项卡./myscript <TAB>上(注意,只是一个按键)出现一个未格式化的列表,其中包含 --help 和 --option,而不是缩短的版本。更糟糕的是,任一选项的完成都会失败。事实上,仅仅输入一个破折号就会导致 _parse_help 完全停止生成输出。

整件事情感觉非常破碎,我在网上找不到太多的参考。这个功能可能被认为是过时的吗?是否有另一种基于解析 --help 输出的命令行完成标准方法?

4

1 回答 1

5

根据bash 参考手册-F function期望从变量中读取单词列表COMPREPLY

似乎_parse_help没有设置这个必需的变量,因此不适合作为complete -F. 从执行函数可以看出,输出显然是回显的。

$ _parse_help ./myscript 
-h
--help
-o
--option

@gertjan 您可以使用该-W wordlist选项来完成您的尝试。

$ complete -W "$(_parse_help ./myscript)" ./myscript 
$ ./myscript -
--help    --option  -h        -o
$ ./myscript --
--help    --option
$ ./myscript --help

完成按预期工作--h并将完成--help,或者在有多个参数(如“--”)的情况下,它只会列出适当的选项。

但是,如果我们尝试使用函数,则仅设置是不够的,COMPREPLY正如您将在下一个示例中看到的那样。

注意: 是一个 bash 数组,设置时COMPREPLY需要括号()

$ function _myscript () { 
>     COMPREPLY=($(_parse_help ./myscript))
> }
$ complete -F _myscript ./myscript 
$ ./myscript -
--help    --option  -h        -o
$ ./myscript --
--help    --option  -h        -o
$ ./myscript --help
--help    --option  -h        -o  

如您所见,即使显示了选项,complete现在也希望我们进行过滤。我们可以做到这一点,compgen但首先我们需要确定要过滤的当前参数是什么。根据我们的最后一个示例,该函数_get_comp_words_by_ref可以通过填充变量来帮助解决这个问题。$cur

使用带有_parse_help用于 bash 完成的函数的完整实现。

$ function _myscript () {
>     _get_comp_words_by_ref cur
>     COMPREPLY=($(compgen -W "$(_parse_help ./myscript)" -- "$cur"))
> }
$ complete -F _myscript ./myscript 
$ ./myscript - 
--help    --option  -h        -o
$ ./myscript --
--help    --option
$ ./myscript --help

开心!

于 2012-12-17T07:57:15.870 回答