【问题标题】:Accessing bash completions for specific commands programmatically以编程方式访问特定命令的 bash 完成
【发布时间】:2010-08-19 10:41:10
【问题描述】:

我正在尝试编写一个小型命令启动器应用程序,并希望在我自己的补全系统中使用 bash 的制表符补全。我已经能够使用compgen -abck 获得一般命令的完成列表。
但是,我还想获得特定命令的完成:例如,输入 git p 应该显示 git 命令的完成。

有什么方法可以使用compgen 来做到这一点?如果没有,还有其他方法可以让我以编程方式获取完成列表吗?

[编辑:澄清一下,我并不是要提供完成 bash - 我的应用程序是一个 GUI 命令启动器。我只是想在我自己的应用程序中使用 bash 的现有完成。]

【问题讨论】:

  • 我不久前修改了这个脚本,它给了你相当准确的Man-page Bash Completion 我知道其他人在解析--help 选项输出时也做过类似的事情。
  • 很棒的脚本,但不是我想要实现的。不过还是感谢您链接到它。

标签: bash shell tab-completion bash-completion


【解决方案1】:

我真的不知道它是如何工作的,但是awesome window manager 使用以下 Lua 代码来访问 bash 完成的结果:

https://github.com/awesomeWM/awesome/blob/master/lib/awful/completion.lua#L119

  1. 通过complete -p,我们找到complete -o bashdefault -o default -o nospace -F _git git。我们稍后会记住“_git”。
  2. “git l”的长度是5,所以我们设置COMP_COUNT=6。我们正在完成“git”的第一个参数,所以 COMP_CWORD=1。

我们一起使用以下脚本:

__print_completions() {
    printf '%s\n' "${COMPREPLY[@]}"
}

# load bash-completion functions
source /etc/bash_completion

# load git's completion function
_completion_loader git

COMP_WORDS=(git l)
COMP_LINE='git l'
COMP_POINT=6
COMP_CWORD=1
_git
__print_completions

输出:“日志”

【讨论】:

  • 代码似乎完全符合我想要对我的应用程序执行的操作。我需要将它移植到常规 Bash,但它仍然很有帮助。非常感谢!
  • 我做了一些测试,这是为了完成“git l”而运行的:/usr/bin/env bash -c 'source /etc/bash_completion; __print_completions() { for ((i=0;i
  • "_git" 是通过 "complete -p" 找到的,它打印 "complete -o bashdefault -o default -o nospace -F _git git"。因此,如果第一个单词是“git”,则调用“_git”。 COMP_COUNT 是到目前为止字符串的长度加一。 COMP_CWORD 是要完成的单词(第一个是索引 0)。
  • 嘿太棒了!感谢您解决这个问题。请注意,为了可读性/方便,您可以将 for ((..;..;..)) 语句替换为 for reply in "${COMP_REPLY[@]}"(然后在循环中使用 echo "$reply")。另外:您的示例中的 i 或我的建议中的 reply 应声明为 local 以避免破坏同名的全局变量。
  • FYI Bash 现在使用动态完成加载,这需要使用_completion_loader git 来加载git 的完成函数_git。我也找不到对COMP_COUNT 的任何引用。正确的变量是COMP_POINT。注意,COMP_POINT 不直接用于完成脚本,而是通过 /usr/share/bash-completion/bash_completion 中常用的辅助函数间接使用。
【解决方案2】:

签入/etc/bash_completion.d/ 目录。这是不同的命令完成脚本所在的位置。

【讨论】:

  • 我在/etc/bash_completion.d/ 中进行了一次探索,但还没有找到一种简单的方法来轻松获取其中包含的补全。 (我使用 Python 来访问补全,这让事情稍微复杂了一点。)我希望可能有一种更简单的方法来访问特定于命令的补全。
【解决方案3】:

这是一个很老的问题,但与此同时,我有 implemented a script 来处理这个问题,以便通过 ZSH 重用完成

【讨论】:

    【解决方案4】:

    这是一个简单但有效的 bash 示例:

    function foo_completion()
    {
        local currentWord=${COMP_WORDS[COMP_CWORD]}
        local completionList=""
    
        case "${COMP_CWORD}" in
            "1")
                completionList="command1 command2 command3";
                ;;
            "2")
                completionList="param1 param2 param3";
                ;;
        esac
    
        COMPREPLY=( $( compgen -W "${completionList}" -- ${currentWord} ) )
    }
    
    complete -F foo_completion foo
    

    使用这种代码,当你输入“foo c”+tab时commandN完成,当你输入“foo command1 p”+tab时paramN完成

    您可以从命令帮助中计算完成列表。

    my2c

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-19
      • 2018-09-01
      • 2022-08-22
      • 1970-01-01
      • 1970-01-01
      • 2016-10-06
      相关资源
      最近更新 更多