Bash自动完成 - 如何将此数组传递给compgen而不会丢失重要的空格?

hel*_*hod 12 arrays bash bash-completion

以下bash完成将一系列可能的单词(即完成)传递给compgen.

basenames=("foo" "fu bar" "baz");

COMPREPLY=($(compgen -W "${basenames[*]}" -- "${COMP_WORDS[COMP_CWORD]}"))
Run Code Online (Sandbox Code Playgroud)

问题是数组元素中的空格不会被保留,即"foo bar"被视为元素,这要归功于单词拆分.有没有办法保留空白,所以显示3个元素,而不是4?

编辑

basenames 包含文件名,几乎每个字符(除了/和\ 0)都是允许的.

编辑2

-W标志需要一个单词,就像这样foo bar foobar.传递多个元素(这是${basenames[@]}可以做的)是行不通的.

编辑3

更改了示例性的basenames数组(因此foofoofrom foo bar不会折叠).

使用换行符分隔单词的工作原理:

local IFS=$'\n'
COMPREPLY=($(compgen -W "$(printf "%s\n" "${basenames[@]}")" --  ${COMP_WORDS[COMP_CWORD]}"))
Run Code Online (Sandbox Code Playgroud)

使用\0不:

local IFS=$'\0'
COMPREPLY=($(compgen -W "$(printf "%s\0" "${basenames[@]}")" --  ${COMP_WORDS[COMP_CWORD]}"))
Run Code Online (Sandbox Code Playgroud)

gei*_*rha 8

为什么要打扰compgen?只需手动将它们添加到COMPREPLY即可.以下将完成匹配的文件名/some/path,安全地处理文件名.

some_completion_function() {
    local files=("/some/path/$2"*)
    [[ -e ${files[0]} ]] && COMPREPLY=( "${files[@]##*/}" )
}
Run Code Online (Sandbox Code Playgroud)

compgen安全地处理文件名是不可能的.