Bash 从另一个完成完成

Bash completion from another completion

我有一个脚本需要命令名称和该命令的参数作为参数。

所以我想编写一个完成函数来完成命令的名称并完成该命令的参数。

所以我可以像这样完成命令的名称

if [[ "$COMP_CWORD" == 1 ]]; then
    COMPREPLY=( $( compgen -c ${COMP_WORDS[COMP_CWORD]} ))
else
    #Don't know what to write here
fi

因此,这将完成 运行 可用的 shell 命令列表的第一个参数。在第二个和其他论点上,我需要完成 ${COMP_WORDS[COMP_CWORD]} 命令。

我考虑从 COMP_WORDS 中删除第一个元素,将 COMP_CWORD 减一个并调用函数 _${COMP_WORDS[0]} 名称在命令前加上“_”前缀,因为在许多示例中,完成命令的函数都有这样的名称,但是当我在 bash 中执行 complete -p 时,我发现许多命令都是用函数完成的有不同的名字。而对于我来说,这样的解决方案看起来真的很糟糕。

我不是 bash 脚本大师,所以我不知道从哪里开始搜索解决方案。

您的要求类似于 exectimexargs 的命令完成。这些命令也将命令和该命令的参数作为完成选项。

正在检查 exec 的 bash_completion 选项:

$ complete -p exec
complete -F _command exec

您可以重新使用相同的函数 _command 作为您的完成函数..

用法:

complete -F _command your-script.sh

我遇到过类似的问题,但我的命令有子命令和全局选项。例如,我需要能够完成以下内容:

mycmd -o foo run ls ./<kbd>Tab</kbd>

要完成这项工作,_command 是不够的。但是 _command_offset 效果很好。这也是例如the sudo completion 使用。这是我的实现中的一个示例,它支持带参数的短选项和长选项:

_mycmd_completion() {
  local cur prev words cword
  _init_completion || return

  local i
  for ((i = 1; i < cword; i++)); do
    case ${words[$i]} in
      -o|--option) ((i++)) ;; # Skip option value
      -o*|--option=*) ;;
      *) break ;; # end of options
    esac
  done

  case ${words[$i]} in
    run)
      _command_offset "$((i + 1))"
      return
      ;;
    …other commands…) … ;;
  esac

  COMPREPLY=($(compgen -W '--option -o run …other commands…' -- "$cur"))
}

complete -F _mycmd_completion mycmd