首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >嵌套bash自动完成脚本

嵌套bash自动完成脚本
EN

Stack Overflow用户
提问于 2012-02-18 09:23:23
回答 1查看 1.2K关注 0票数 1

我一直试图在我最近使用的命令行程序中添加bash完成支持,但我似乎遇到了麻烦。

以下是我想要自动完成的命令和子命令

  • 主命令是foo,应该对子命令versionprocesshelp执行自动完成。进一步的自动完成取决于子命令。

代码语言:javascript
运行
复制
- If the user enters `-` after the main command, autocompletion performs completion for these word: `--activate` or  `--deactivate`
- If the user enters `--deactivate`, it should perform autocompletion of a bash command output (let's say `ls`).

  • version:不自动完成performed
  • process:自动完成默认为列出目录(包括当前目录和父目录)

代码语言:javascript
运行
复制
- If the user enters `-`, autocompletion performs completion for these words: `--color`, `--verbose` and then stops afterward

如果用户进入version).,则自动完成将用于其他子命令(processhelp )。

下面是我当前实现的自动完成脚本(它失败了):

代码语言:javascript
运行
复制
_foo() {
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    words=("${COMP_WORDS[@]}")
    cword=$COMP_WORD
    opts="process version help"

    case "$prev" in
    -*)
        local subopts="--activate --deactivate"
            COMPREPLY=( $(compgen -W "${subopts}" -- ${cur}) )
            case "$cur" in
                --deactivate)
                    COMPREPLY=( $(ls) )
                ;;
            esac
         ;;
    version)
        COMPREPLY=()
        ;;
    process)
        case "$cur" in
            -*)
                local subopts="--color --verbose"
                COMPREPLY=( $(compgen -W "${subopts}" -- ${cur}) )
                ;;
            *)
                COMPREPLY=( $(compgen -A directory))
                ;;
        esac
        ;;
    help)
        COMPREPLY=( $(compgen -W "process version" -- ${cur}) )
        ;;
   esac
   } 
 complete -F _foo foo

你可能会发现巴斯也不是我的主要强项。我正在考虑为每个子命令编写单独的bash函数,但目前我不知道如何实现。如果您对如何实现这一点也有建议,我将非常感谢。

谢谢!

EN

回答 1

Stack Overflow用户

发布于 2012-02-21 00:24:16

在第一级可能出现的子命令的情况下,我有点不清楚。是否可以输入foo --activatefoo - --activate?后者看起来有些奇怪,但更适合您给定的代码。第一种方法听起来更合理,但它意味着将--activate等作为一种全局参数,该参数将在与您的子命令相同的级别上处理。

尽管如此,当您还没有输入任何内容时,您错过了默认设置。尝试以下代码:

代码语言:javascript
运行
复制
_foo() {
    local cur prev opts

    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    words=("${COMP_WORDS[@]}")
    cword=$COMP_CWORD
    opts="process version help"

    case "$prev" in
    -*)
        local subopts="--activate --deactivate"
        COMPREPLY=( $(compgen -W "${subopts}" -- ${cur}) )
        case "$cur" in
            --deactivate)
                COMPREPLY=( $(ls) )
            ;;
        esac
        return 0
         ;;
    version)
        COMPREPLY=()
        return 0
        ;;
    process)
        case "$cur" in
            -*)
                local subopts="--color --verbose"
                COMPREPLY=( $(compgen -W "${subopts}" -- ${cur}) )
                ;;
            *)
                COMPREPLY=( $(compgen -A directory))
                ;;
        esac
        return 0
        ;;
    help)
        COMPREPLY=( $(compgen -W "process version" -- ${cur}) )
        return 0
        ;;
   esac
   COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
   return 0
} 
complete -F _foo foo

这基本上与您的相同,但是:在底部,将COMPREPLY设置为您的第一级子命令,以便它们完成。如果输入了子命令,则应返回(0)以不到达最后语句。

给出的示例将适用于foo - --activate,这可能不是您想要的。因此,如果要输入foo --activate,请将相应的行更改为

代码语言:javascript
运行
复制
    case "$prev" in
    --activate)
        COMPREPLY=()
        return 0
        ;;
    --deactivate)
        COMPREPLY=( $(compgen -W "$(ls)" -- ${cur}) )
        return 0
        ;;
    version)
    ...
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9340045

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档