我很难让我的bash完成脚本像预期的那样运行。
下面是我正在尝试做的事情的最简化版本,以及问题的截屏视频。
除了一个例外,一切都运行得很好:
当补全中只有一个匹配项时,当我按Tab键两次时,它会打印相同的命令两次,这不是预期的效果。
在我的完成案例中,我只对完成第一个参数(即“子命令”)感兴趣。我认为下面的if [ "$#" -gt "2" ]行应该可以防止这种情况,但它没有-因为在第一个选项卡之后COMP_LINE仍然没有更新。
#!/usr/bin/env bash
send_completions() {
if [[ -z "$COMP_LINE" ]]; then
return
fi
set $COMP_LINE
if [ "$#" -gt "2" ]; then
return
fi
compgen -W "one two test" "$2"
}
send_completions通过运行以下命令启用完成:
$ complete -C './complete.sh' asd然后键入asd o<tab><tab>查看问题。

任何帮助都是非常感谢的。
发布于 2018-07-13 21:40:43
此时检查COMP_LINE的值:
$ asd one <TAB>您会注意到,该值为:
declare -x COMP_LINE="asd one "这将在您发出set之后产生两个位置参数,并且您的条件不会被触发。尝试输入一个额外的字符:$ asd one o<TAB>,您将看到您的条件将被正确触发,并且不会完成任何操作。
我所见过的大多数完成都是使用函数完成的。事实上,现在检查我系统上定义的所有补全(大多数是默认的),其中没有一个是使用脚本完成的。
使用函数有一些好处,例如,支持引号的COMP_WORDS数组。您的脚本可以大致重写如下:
_asd_comp() {
(( COMP_CWORD > 1 )) && return
local cur=${COMP_WORDS[COMP_CWORD]} IFS=$' \t\n'
COMPREPLY=( $(compgen -W "one two three" -- "$cur") )
}
complete -o bashdefault -o default -F _asd_comp asd我添加了-o选项,以便在第一个参数之后执行默认完成。你可以在manual上阅读更多关于这方面的内容。
关于如何更改您的脚本,我想您唯一想到的就是添加相当不干净的条件,例如:
(( $# > 1 )) && [[ ${COMP_LINE: -1} = " " ]] && returnhttps://stackoverflow.com/questions/51324984
复制相似问题