如何在其他目录中扩展bash完成?

时间:2016-07-09 20:02:04

标签: bash autocomplete bash-completion

我正在学习bash完成。我能够列出当前目录的内容。这是我的代码:

   _foo()
   {
       local cur prev opts
       COMPREPLY=()
       cur="${COMP_WORDS[COMP_CWORD]}"
       prev="${COMP_WORDS[COMP_CWORD-1]}"

       opts="push pull"
       OUTPUT=" $(ls) "

      case "${prev}" in
          push)
              COMPREPLY=( $(compgen -W "--in --out" -- ${cur}) )
              return 0
              ;;
          --in)
              COMPREPLY=( $(compgen -W "$OUTPUT" -- ${cur}) )
              return 0
              ;;
      esac

        COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
        return 0
  }
  complete -F _foo foo

它的输出是:

$ foo push --in[TAB]
file1.txt file2.txt foo  ;; content of pwd

但是当我这样做时:

$ foo push --in ~[TAB]

它不起作用。 所以我想知道如何在不同的目录中完成bash完成(不仅仅是在 pwd 中)?感谢。

1 个答案:

答案 0 :(得分:2)

您可以使用-f来匹配文件名:

#!/bin/bash
_foo()    {
       local cur prev opts
       COMPREPLY=()
       cur="${COMP_WORDS[COMP_CWORD]}"
       prev="${COMP_WORDS[COMP_CWORD-1]}"
       opts="push pull"

       case "${prev}" in
          push)
              COMPREPLY=( $(compgen -W "--in --out" -- ${cur}) )
              return 0
              ;;
          --in)
              COMPREPLY=( $(compgen -f ${cur}) )
              return 0
              ;;
      esac

      COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
      return 0   
}

complete -F _foo foo

然而,它似乎并不适用于~,但$ foo push --in ~/[TAB]可以正常工作,所有其他目录 此解决方案不包括斜杠以在目录中查找文件:$ foo push --in /etc[TAB]将提供foo push --in /etc而不是foo push --in /etc/

以下帖子使用默认模式解决了这个问题:
Getting compgen to include slashes on directories when looking for files

  

默认

     

如果compspec没有生成匹配项,请使用Readline的默认文件名完成。

所以你可以使用:

#!/bin/bash
_foo()
   {
       local cur prev opts
       COMPREPLY=()
       cur="${COMP_WORDS[COMP_CWORD]}"
       prev="${COMP_WORDS[COMP_CWORD-1]}"

       opts="push pull"
       OUTPUT=" $(ls) "

      case "${prev}" in
          push)
              COMPREPLY=( $(compgen -W "--in --out" -- ${cur}) )
              return 0
              ;;
          --in)
              COMPREPLY=()
              return 0
              ;;
          --port)
              COMPREPLY=("")
              return 0
              ;;
      esac

        COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
        return 0
  }
  complete -o default -F _foo foo

或者当您需要喜欢这篇文章时设置为默认模式:https://unix.stackexchange.com/a/149398/146783