如何让 bash 命令行完成部分参数并提供更多提示

如何让 bash 命令行完成部分参数并提供更多提示

假设我有一个命令“command”,它接受参数 foo:bar foo:foo bar:bar 或 bar:foo,我可以编写一个命令行完成脚本,可以将其放入我的环境中,给我提供如下所示的完成效果:

function _command_opt()
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    opts="foo:bar foo:foo bar:bar bar:foo"
    if [[ ${prev: -7} == 'command' ]]
    then
        COMPREPLY=( $(compgen -W "${opts}"  -- ${cur}) );
        return 0;
    fi
}
complete -F _command_opt -o bashdefault -o default 'command'

但是如果我输入,command f[tab][tab]我会得到列出的 foo:bar 和 foo:foo,但它们都不会在我的命令行上完成(因为它们尚未区分。我想要实现的是,这会产生command foo:并将我的光标留在当前单词的末尾(而不是添加空格),以便我输入bf然后再次按 Tab 键完成命令。示例问题只是为了说明我的意思……真实情况是前缀:后缀组合很长,因此部分完成将非常有益。例如,25 个不同的命令都以前缀 Translationupdateprocess: 开头,而 Translationupdateprocess 是 25 个不同的等长前缀之一,具有许多选项。

有谁知道如何让 bash 以这种方式完成运行?

答案1

您可以使用以下代码(foo:baz foo:qux bar:eat bar:egg为了澄清起见,我替换了您的选项):

function _command_opt()
{
  local cur cursec command opts
  COMPREPLY=()

  cur="${COMP_WORDS[COMP_CWORD]}"
  cursec=`echo ${cur} | awk -F ':' '{print $1}'`;

  command="${COMP_WORDS[1]}"
  opts="foo bar"

  case "${command}" in
    foo)
      COMPREPLY=( $(compgen -W "baz qux" -- ${cursec}) ); return 0;;
    bar)
      COMPREPLY=( $(compgen -W "eat egg" -- ${cursec}) ); return 0;;
    *) ;;
  esac

  COMPREPLY=( $(compgen -W "${opts}" -S ":" -- ${cur}) ); compopt -o nospace;
}

complete -F _command_opt -o bashdefault -o default 'command'

当你输入时,commandtab你可以获得第一级列表foo: bar:,当你输入时,ftabtab你可以获得第二级的完成列表baz qux。然后,你可以输入qtab以获取完整的命令行command foo:qux

希望能帮助到你。

相关内容