附录 J. 可编程补全简介

Bash 中的 可编程补全 功能允许您输入部分命令,然后按 [Tab] 键来自动补全命令序列。 [1] 如果有多个补全选项,则 [Tab] 会列出所有选项。 让我们看看它是如何工作的。

bash$ xtra[Tab]
xtraceroute       xtrapin           xtrapproto
 xtraceroute.real  xtrapinfo         xtrapreset
 xtrapchar         xtrapout          xtrapstats


bash$ xtrac[Tab]
xtraceroute       xtraceroute.real


bash$ xtraceroute.r[Tab]
xtraceroute.real
      

Tab 补全也适用于变量和路径名。

bash$ echo $BASH[Tab]
$BASH                 $BASH_COMPLETION      $BASH_SUBSHELL
 $BASH_ARGC            $BASH_COMPLETION_DIR  $BASH_VERSINFO
 $BASH_ARGV            $BASH_LINENO          $BASH_VERSION
 $BASH_COMMAND         $BASH_SOURCE


bash$ echo /usr/local/[Tab]
bin/     etc/     include/ libexec/ sbin/    src/     
 doc/     games/   lib/     man/     share/
      

Bash 的 completecompgen 内建命令 使 tab 补全 能够识别命令的部分 参数选项。 在一个非常简单的例子中,我们可以从命令行使用 complete 来指定一个可接受参数的简短列表。

bash$ touch sample_command
bash$ touch file1.txt file2.txt file2.doc file30.txt file4.zzz
bash$ chmod +x sample_command
bash$ complete -f -X '!*.txt' sample_command


bash$ ./sample[Tab][Tab]
sample_command
file1.txt   file2.txt   file30.txt
  

-f选项用于 complete 指定文件名,以及-X过滤器模式。

对于更复杂的情况,我们可以编写一个脚本来指定可接受的命令行参数列表。 compgen 内建命令扩展 参数 列表以 生成 补全匹配项。

让我们以 UseGetOpt.sh 脚本的 修改版本 作为示例命令。 该脚本接受多个命令行参数,这些参数前面有一个或两个短划线。 这是相应的 补全脚本,按照惯例,文件名与其关联的命令相对应。

示例 J-1. UseGetOpt.sh 的补全脚本

# file: UseGetOpt-2
# UseGetOpt-2.sh parameter-completion

_UseGetOpt-2 ()   #  By convention, the function name
{                 #+ starts with an underscore.
  local cur
  # Pointer to current completion word.
  # By convention, it's named "cur" but this isn't strictly necessary.

  COMPREPLY=()   # Array variable storing the possible completions.
  cur=${COMP_WORDS[COMP_CWORD]}

  case "$cur" in
    -*)
    COMPREPLY=( $( compgen -W '-a -d -f -l -t -h --aoption --debug \
                               --file --log --test --help --' -- $cur ) );;
#   Generate the completion matches and load them into $COMPREPLY array.
#   xx) May add more cases here.
#   yy)
#   zz)
  esac

  return 0
}

complete -F _UseGetOpt-2 -o filenames ./UseGetOpt-2.sh
#        ^^ ^^^^^^^^^^^^  Invokes the function _UseGetOpt-2.

现在,让我们尝试一下。

bash$ source UseGetOpt-2

bash$ ./UseGetOpt-2.sh -[Tab]
--         --aoption  --debug    --file     --help     --log     --test
 -a         -d         -f         -h         -l         -t


bash$ ./UseGetOpt-2.sh --[Tab]
--         --aoption  --debug    --file     --help     --log     --test
  

我们首先 source “补全脚本”。 这会设置命令行参数。 [2]

在第一个例子中,在单个短划线后按 [Tab],输出是以一个或多个短划线开头的所有可能的参数。 在两个短划线后按 [Tab] 会给出以两个或多个短划线开头的可能参数。

现在,为了启用命令行 tab 补全,不得不经历这些繁琐的步骤的意义何在? 它可以节省击键次数。 [3]

--

资源

Bash 可编程补全 项目

Mitch Frazier 在 Linux Journal 上的文章,更多关于使用 Bash Complete 命令

Steve 的精彩两部分文章,“Bash 补全简介”第一部分第二部分

注释

[1]

当然,这仅在 命令行 中有效,而不在脚本中有效。

[2]

通常,默认的参数补全文件位于/etc/profile.d目录或/etc/bash_completion。 这些文件在系统启动时自动加载。 因此,在编写有用的补全脚本后,您可能希望将其(当然,以 root 身份)移动到这些目录之一。

[3]

已经有大量文献记录表明,程序员愿意花费大量时间来节省十分钟的“不必要”的劳动。 这被称为 优化