【问题标题】:Bash Completion: What can we do with it, what lies in the future [closed]Bash Completion:我们能用它做什么,未来会发生什么[关闭]
【发布时间】:2009-12-13 13:10:53
【问题描述】:

Bash 允许您使用 TAB 键完成参数中的命令名称和文件名称。 但是为什么不是命令的常用选项呢?为什么不提供一个更好的完成系统来告诉您选项的作用呢?

我听说过可编程完成..但不明白它适合什么..

所以我的问题是:有没有办法实现我的要求?与 Bash 结合的其他工具可能......或者什么?

【问题讨论】:

  • 我在使用 OSX 10.6 的 mac,我使用 GNUBash 版本 3.2.48

标签: bash tab-completion programmable-completion


【解决方案1】:

如果您想要更出色的完成,请查看zsh。它与 bash 非常相似,并吸收了 ksh、tcsh 等的一些优秀特性。它还修复了一些恼人的 bash 错误。

它可以做一些非常酷的事情,包括完成 scp 的远程文件名(如果您设置了基于密钥的身份验证)和当您完成选项卡时的迷你文档 例如,前几天我在“jar”标签上时感到惊喜:

[steven@sexy:~]% jar <tab>
0  -- store only without using ZIP compression
M  -- do not create manifest file
etc...

【讨论】:

    【解决方案2】:

    这是 bash 的官方手册页:Bash Reference Manual: Programmable Completion

    【讨论】:

      【解决方案3】:

      在 OS X 上,您可以按照说明 here 使用 MacPorts 轻松安装一组预定义的 bash 补全。查看/opt/local/etc/bash_completion.d 中的示例可能会给您一些制作其他示例的想法。

      【讨论】:

        【解决方案4】:

        这是 bash 的标准功能:programmable completion

        【讨论】:

          【解决方案5】:

          【讨论】:

            【解决方案6】:

            Bash 补全非常可定制,可以显示常用命令的选项。配置文件只需要这样指定。在 Debian 中,bash 补全带有一组配置文件,用于完成不同命令的选项。

            例如:

            alanhaggai@neon:~$ tar
            A  c  d  r  t  u  x
            

            【讨论】:

              【解决方案7】:

              我不喜欢这里的任何答案,并想提供几个具体的例子。

              有时我有许多具有共同前缀的目录,并且希望能够通过键入目录名称的唯一部分(位于目录名称的中间或结尾)来完成它们。

              我能够编写一个完成函数来完成这个:

              _cd(){
                  # Backup old nullglob setting
                  local shoptbakup="`shopt -p nullglob`"
                  shopt -s nullglob
              
                  local cur opts i opt
                  local IFS=$'\n'
                  cur="${COMP_WORDS[COMP_CWORD]}"
              
                  # Home directory substitution
                  if [[ "${cur:0:1}" == '~' ]]; then
                      cur="$HOME/${cur:1}"
                  fi
              
                  if [[ $cur == */* ]]; then
                      opts=(${cur}*/)
                  else
                      opts=(*${cur}*/)
                  fi
              
                  # Prevent trailing//
                  i=0
                  for opt in "${opts[@]}"; do
                      #opts[$i]=${opt%${opt##*[!/]}}
                      opts[$i]=${opt%/}
                      i=$((i+1))
                  done
              
                  # Restore nullglob setting
                  eval "$shoptbakup" 2>/dev/null
              
                  COMPREPLY=("${opts[@]}")
              }
              complete -o filenames -o bashdefault -o nospace -F _cd cd
              

              所以现在根据我的提示,我可以这样做:

              $ ls
              test 6/  test 7/  test 8/  test1/  test2/  test3/  test4/  test5/
              $ cd 7[TAB]
              

              它会自动完成到:

              $ cd test\ 7/
              

              您可能想要使用可编程完成的另一个原因是,如果您编写脚本并希望能够为您列出或完成选项。这个页面有一些非常好的例子:

              http://fahdshariff.blogspot.com/2011/04/writing-your-own-bash-completion.html

              这是一个例子:

              假设我有一个名为 listanimals 的脚本。我可以写一个补全函数来帮助填写选项

              # complete sendevent
              _listanimals()
              {
                  local cur=${COMP_WORDS[COMP_CWORD]}
                  local prev=${COMP_WORDS[COMP_CWORD-1]}
              
                  if [[ $prev == "--sort-direction" ]]; then
                      COMPREPLY=( $( compgen -W "horizontal vertical" -- $cur ) )
                      return 0
                  elif [[ $prev == "--type" ]];then
                      COMPREPLY=( $( compgen -W "mammals reptiles birds fish marsupials insects misc" -- $cur ) )
                      return 0
                  elif [[ $prev == "--size" ]]; then
                      COMPREPLY=( $( compgen -W "tiny small medium large huge" -- $cur ) )
                      return 0
                  fi
              
              
                  # completing an option
                  if [[ "$cur" == --* ]] || [[ $cur == "" ]]; then
                      COMPREPLY=( $( compgen -W "--sort-direction --type --size" -- $cur ) )
                  fi
              }
              complete -F _listanimals listanimals
              

              现在我可以这样做了:

              $ listanimals --[TAB][TAB]
              --size            --sort-direction  --type
              $ listanimals --t[TAB]
              

              这会自动填写:

              $ listanimals --type
              

              那么我可以这样做:

              $ listanimals --type [TAB][TAB]
              birds       fish        insects     mammals     marsupials  misc        reptiles
              

              而且我相信你可以弄清楚其余的。这是一个工作示例,因此如果您想尝试一下,只需将其复制/粘贴到文件中(例如 sample.sh)并在 bash source sample.sh 中获取它。您实际上并不需要一个名为 listanimals 的脚本。

              希望有人会觉得这很有用,因为我发现很难弄清楚。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2014-11-09
                • 1970-01-01
                • 1970-01-01
                • 2013-11-05
                • 1970-01-01
                • 2011-04-17
                • 2020-05-05
                相关资源
                最近更新 更多