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

如何在其他目录中扩展bash完成?,bash,autocomplete,bash-completion,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

我正在学习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中)?谢谢。

您可以使用
-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/

下面的帖子使用默认模式解决了这个问题:

违约

如果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

或者当你需要喜欢这篇文章时,设置为默认模式:

哦,它们实际上不在脚本中。这些都是因为Vim编辑器。我从那里复制了这个脚本,所以行号也被复制了。这很好。但如果我不想在特殊情况下做任何事情呢。假设有一个参数--port,我想从键盘上获取它。它应该是这样的
$foo push--port[TAB]
;;自动完成应该停止,没有结果。它指示用户从键盘传递--端口值。但根据您的回答,它将是
$foo push--port[TAB]
;;pwd的内容那么有没有办法指定,在这些情况下,我们不会默认结果?但这不起作用<代码>$foo push--in[TAB]bash:compopt:command not found这是我收到的错误消息。您是否在bash\u completion.d中找到了该文件的源代码?尝试添加
#/bin/bash
位于顶部,以确保它使用了正确的bash。如果您的bash不在
/bin/bash
中,请替换为正确的bash位置(
哪个bash
),这将不包括用斜杠查找子目录,如果您这样做了,请让我们。