首页 > 解决方案 > 如何为文件搜索和自定义搜索配置 bash 自动完成功能?

问题描述

我想要一个命令自动完成上传的脚本,可以远程运行,但用户也可以选择一个本地脚本来上传。这是一个小例子来说明我在使用 bash 完整逻辑时遇到的问题。

_test_complete()
{
    local cur prev opts uploaded_scripts
    uploaded_scripts='proc1.sh proc2.sh'
    
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    if [[ ${prev} == '-s' ]] ; then
        COMPREPLY=( $(compgen -W "${uploaded_scripts}" -- ${cur}) )
        return 0
    fi
}

complete -F _test_complete remote

该示例几乎可以工作,但它不再自动完成本地文件搜索。

$ remote -s proc<TAB><TAB>
proc1.sh  proc2.sh

$ remote -s proc1.sh ./<TAB><TAB>

./当您执行应该列出当前目录中的文件的常规文件搜索时,什么也不会发生。关于如何启用两者的任何想法?


编辑:上面的例子有一个问题,你只能选择一个文件完整的文件。我破解了一个可行的解决方案,但如果有人有更好的解决方案,请发表评论。也-o default来自接受的答案。

_test_complete()
{
    local cur prev opts uploaded_scripts
    uploaded_scripts='proc1.sh proc2.sh'

    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    
    [[ $COMP_CWORD == '1' ]] && LAST_OPT=''
    [[ ${prev:0:1} == '-' ]] && LAST_OPT=${prev}
    
    if [[ ${LAST_OPT} == '-s' ]]; then
        COMPREPLY=( $(compgen -o default -W "${uploaded_scripts}" -- ${cur}) )
        return 0
    fi
}

complete -F _test_complete remote

标签: bashbash-completion

解决方案


您只需要将本地目录中的所有文件也添加到COMPREPLYcomplete -f -- abc生成以 . 开头的文件列表abc

顺便说一句:你也可以使用bash 提供给任何补全函数的and来代替"${COMP_WORDS[COMP_CWORD]}"and 。 但是在这里我完全放弃了,因为你似乎想在. 由于您不建议自己,因此始终建议文件:COMP_CWORD-1$2$3
if-s-s

_test_complete() { 
  local cur="$2" prev="$3" uploaded_scripts='proc1.sh proc2.sh'
  COMPREPLY=( $(
    compgen -W "${uploaded_scripts}" -- "$cur"
    compgen -f -- "$cur"
  ) )
}

complete -F _test_complete remote

注意:COMPREPLY=( $(...) )写起来很容易,但有一些缺陷。带有空格的文件将被拆分为多个建议,特殊符号(例如)*将扩展并生成更多建议。为避免这种情况,请设置IFS=$'\n'; set -o noglob或使用mapfile -t COMPREPLY < <(...).
完成此操作后,您可以使用complete -o filenames -F ...这样的方式,以便在插入时也正确引用那些有问题的建议。


推荐阅读