微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何为文件搜索和自定义搜索配置 bash 自动完成功能?

如何解决如何为文件搜索和自定义搜索配置 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

解决方法

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

顺便说一句:除了 "${COMP_WORDS[COMP_CWORD]}"COMP_CWORD-1,您还可以使用 $2$3,它们由 bash 提供给任何完成函数。
但在这里我完全放弃了 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 ... 以便在插入时正确引用那些有问题的建议。

,

您可以使用 complete-o default 选项 (通常我会同时使用 -o default-o bashdefault

complete -o default -F _test_complete remote

根据man bash

  • bashdefault

    如果 compspec 未生成匹配项,则执行其余的默认 bash 完成

  • 默认

    如果 compspec 未生成匹配项,则使用 readline 的默认文件名补全

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。