下面的bash完成将一个可能的单词数组(即完成)传递给compgen。
basenames=("foo" "fu bar" "baz");
COMPREPLY=($(compgen -W "${basenames[*]}" -- "${COMP_WORDS[COMP_CWORD]}"))问题是数组元素中的空白没有被保留,也就是说,"foo bar“由于分词而被视为元素。是否有办法保留空白,以便显示3个元素,而不是4个元素?
编辑
basenames包含文件名,即几乎每个字符(除了/和\0)都是允许的。
编辑2
-W标志需要一个单词,即类似于foo bar foobar的单词。将多个元素传递给它(这就是${basenames[@]}所要做的)是行不通的。
编辑3
更改了示例基名数组(因此foo和来自foo bar的foo不会被折叠)。
用换行符分隔单词有效:
local IFS=$'\n'
COMPREPLY=($(compgen -W "$(printf "%s\n" "${basenames[@]}")" -- ${COMP_WORDS[COMP_CWORD]}"))使用\0并不是:
local IFS=$'\0'
COMPREPLY=($(compgen -W "$(printf "%s\0" "${basenames[@]}")" -- ${COMP_WORDS[COMP_CWORD]}"))发布于 2012-07-14 09:26:27
为什么要麻烦compgen呢?只需手动将它们添加到COMPREPLY。下面将完成来自/some/path的匹配文件名,安全地处理文件名。
some_completion_function() {
local files=("/some/path/$2"*)
[[ -e ${files[0]} ]] && COMPREPLY=( "${files[@]##*/}" )
}不可能安全地使用compgen句柄文件名。
发布于 2012-05-18 18:47:28
也许这样做可以:
COMPREPLY=($(compgen -W "$(printf "%q " "${basenames[*]}")" -- "${COMP_WORDS[COMP_CWORD]}"))发布于 2020-09-06 03:16:04
阅读更好的解决方案那里
使用readarray和printf
readarray -t words < /etc/passwd
compgen -W "$(printf "'%s' " "${words[@]}")" -- "man"
# OUTPUTS: man:x:6:12:man:/var/cache/man:/usr/sbin/nologin@Q参数转换(20170 man bash search parameter@operator )https://stackoverflow.com/questions/10652492
复制相似问题