标签完成时如何防止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}) ) 但是,面对完整的解决方案,这有点多余. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |