标签完成时如何防止bash完成替换字符

前端之家收集整理的这篇文章主要介绍了标签完成时如何防止bash完成替换字符前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在为一个共享文件上传语法卷曲的工具构建一个bash完成脚本.

卷曲,你可以做:

curl -F var = @ file

上传文件.

我的应用程序有类似的语义,我希望能够在按下“@”后显示可能的文件.不幸的是,这证明是困难的:

cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
if [[ "$cur" == @* && "$prev" == '=' ]]; then
    COMPREPLY=( $(compgen -f ${cur:1}) )
    return 0
fi

所以如果一个命令(到目前为止)以:

abc=@

当前目录中的文件显示.

var=@/usr/                                                                                                                       
 /usr/bin      /usr/games

问题是如果我真的打标签来完成,’@’消失!

var=/usr/bin

所以看起来像bash用标签的COMPREPLY替换整个当前单词.

避免这种情况的唯一方法是这样做:

COMPREPLY=( $(compgen -f ${cur:1}) )
        for (( i=0; i<${#COMPREPLY[@]}; i++ )); 
        do 
            COMPREPLY[$i]='@'${COMPREPLY[$i]} 
        done

但现在标签完成看起来很奇怪,至少说:

@/usr/bin      @/usr/games

有没有显示正常的文件选项卡完成(没有’@’前缀),但保持“@”当打标签

所以,这让我感兴趣,所以我一直在阅读bash完成源(可在/ etc / bash_completion).

我遇到这个变量:${COMP_WORDBREAKS},这似乎允许控制用于分隔字词的字符.

我也遇到这个函数_get_cword和互补的_get_pword,分别推荐使用${COMP_WORDS [COMP_CWORD]}和${COMP_WORDS [COMP_CWORD-1]}.

所以,把所有这一切放在一起,我做了一些测试,这里是我想出来的:这似乎对我来说,至少,希望它也会为你:

# maintain the old value,so that we only affect ourselves with this
OLD_COMP_WORDBREAKS=${COMP_WORDBREAKS}
COMP_WORDBREAKS="${COMP_WORDBREAKS}@"

cur="$(_get_cword)"
prev="$(_get_pword)"

if [[ "$cur" == '=@' ]]; then
    COMPREPLY=( $(compgen -f ${cur:2}) )

    # restore the old value
    COMP_WORDBREAKS=${OLD_COMP_WORDBREAKS}
    return 0
fi

if [[ "$prev" == '=@' ]]; then
    COMPREPLY=( $(compgen -f ${cur}) )

    # restore the old value
    COMP_WORDBREAKS=${OLD_COMP_WORDBREAKS}
    return 0

fi

现在我承认,如果病例有点脏,那么绝对有更好的办法,但是我需要更多的咖啡因.

此外,无论你是值得的,我还发现了P< prefix> compgen的参数,这将阻止您在调用compgen之后循环使用$COMPREPLY [*]}数组,像这样

COMPREPLY=( $(compgen -P @ -f ${cur:1}) )

但是,面对完整的解决方案,这有点多余.

猜你在找的Bash相关文章