Bash补全详解
概述
在设计基于Bash的中⽂⽂件拼⾳补全的时候,需要⾼度定制的补全策略,于是特意研究了下Bash的补全机制。
本⽂主要是man bash⾥⾯相关说明,由于英⽂⽔平有限,参考了
补全相关的 Shell 变量(Shell Variables)
COMP_CWORD
${COMP_WORDS} 的索引,指向当前光标位置所在的词。这个变量只有在被可编程补全功能 (参见下⾯的 Programmable Completion 章节)调⽤的 shell 函数中才可⽤。
COMP_LINE
当前命令⾏。这个变量只有在被命令补全功能调⽤的 shell 函数和外部命令中才可⽤。
COMP_POINT
相对于当前命令起始处的当前光标位置。如果当前光标位置是当前命令的末端,它的值就和 ${#COMP_LINE} 相等。这个变量只有在被命令补全功能调⽤的 shell 函数和外部命令中才可⽤。
COMP_WORDS
⼀个数组变量 (参见下⾯的 Arrays(数组)⼀节),由当前命令⾏的各个单词构成。这个变量只有在被命令补全功能调⽤的 shell 函数中才可⽤。
COMPREPLY
⼀个数组变量,bash 从中读取可能的命令补全。它是由命令补全功能调⽤的 shell 函数产⽣的。
HOSTFILE
包含⼀个格式和/etc/hosts相同的⽂件名,当 shell 需要补全主机名时要读取它。shell 运⾏过程中可以改变可能的主机名补全列表;改变之后下⼀次需要主机名补全时 bash 会将新⽂件的内容添加到旧列表中。如果定义了 HOSTFILE 但是没有赋值,bash 将尝试读取 /etc/hosts ⽂件来获得可能的主机名补全列表。当取消 HOSTFILE 的定义时,主机名列表将清空。
FIGNORE
⼀个冒号分隔的后缀名列表,在进⾏⽂件名补全时被忽略 (参见下⾯的READLINE章节)。⼀个后缀满⾜其中之⼀的⽂件名被排除在匹配的⽂件名之外。可以是这样: ".o:~".
GLOBIGNORE
⼀个冒号分隔的模式列表,定义了路径名扩展时要忽略的⽂件名集合。如果⼀个⽂件名与路径扩展模式匹配,同时匹配GLOBIGNORE中的⼀个模式时,它被从匹配列表中删除。
可编程的补全(Programmable Completion)
当试图对⼀个命令的参数进⾏词的补全时,如果已经使⽤内建命令complete定义了这个命令的补全规则(comspec),将启动可编程补全功能。
⾸先,命令名被确认。如果针对这个命令有补全规则的定义,那么将使⽤规则来产⽣可能的词的补全的列表。如果命令词是⼀个路径全名,将⾸先搜索针对这个路径全名的规则。如果针对这个路径全名没有到规则,将尝试查针对最后⼀个斜杠后⾯的部分的规则。
⼀旦到了⼀个规则,它将⽤作产⽣匹配的词。如果没有到,将进⾏上⾯Completing中描述的bash默认的补全。
⾸先,将执⾏规则指定的动作。只有以被补全的词开始的匹配词才会被返回。当在⽂件或⽬录名补全中使⽤ -f 或 -d 选项时,shell 变量FIGNORE将⽤于对匹配进⾏过滤。
接下来,将产⽣所有由-G选项给出的⽂件名扩展模式指定的补全。模式产⽣的词不必匹配要补全的词。shell 变量GLOBIGNORE不会⽤于过滤匹配结果,但是变量FIGNORE会被使⽤。
接下来,将考虑-W选项的参数指定的字符串。这个字符串⾸先被划分,⽤特殊变量IFS中的字符作为分隔符。shell 引⽤被当作⼀个词。接下来,每个词被扩展,使⽤上⾯EXPANSION中描述的brace expansion, tilde expansion, parameter和variable expansion, command substitution, arithmetic expansion,以及pathname expansion规则处理。对于结果,再使⽤上⾯ Word Splitting 中描述的规则划分成词。扩
展的结果与要补全的词进⾏前部⼀致的⽐较,匹配的词成为可能的补全。
在这些匹配被产⽣后,任何由-F和-C选项指定的 shell 函数和命令将被执⾏。当命令或函数被执⾏时,变量COMP_LINE和COMP_POINT被赋值,使⽤上⾯ Shell Variables 中的规则。如果要执⾏ shell 函数,还将设置变量COMP_WORDS和COMP_CWORD。当函数或命令被执⾏时,第⼀个参数是等待参数被补全的命令的名称,第⼆个参数是要补全的词,第三个参数是当前命令⾏中,要补全的词前⾯的词。对要补全的词产⽣的补全不会进⾏任何过滤;函数或命令在产⽣匹配时有完全的⾃由。
任何-F指定的函数将被⾸先执⾏。函数可以使⽤任何 shell 功能,包含内建命令compgen,来产⽣匹配。它必须将可能的补全放到数组变量COMPREPLY中。
接下来,任何 -C 选项指定的命令将被执⾏,其执⾏环境与命令替换的环境相同。它应当向标准输出打印⼀个补全的列表,每⾏⼀个。反斜杠可以⽤来转义⼀个新⾏符,如果需要的话。
所有可能的补全都产⽣之后,将对列表进⾏-X选项指定的任何过滤。过滤器是⼀个模式,和路径名扩展中的⼀样;模式中的&替换为要补全的词。字⾯上的&可以⽤反斜杠转义;反斜杠在进⾏匹配时被删除。任何匹配这个模式的补全将从列表中删除。前导的!将使模式含义相反;这种情况下,任何不匹配这个模式的补全将被删除。
最后,-P和-S指定的任何前缀和后缀被添加到补全列表的每个成员后⾯,结果返回给 readline 补全代码,作为可能的补全列表。
如果先前执⾏的动作没有产⽣任何匹配,并且在定义 compspec 规则时,为 complete 命令提供了 -o dirname 选项,将尝试⽬录名补全。
默认情况下,如果到了⼀个规则,它产⽣的任何东西都被返回给补全代码,作为可能的补全的全集。不再尝试默认的 bash 补
全,readline 默认的⽂件名补全也会禁⽌。如果定义规则时,为 complete 命令提供了-o default选项,在规则没有产⽣匹配时将进⾏ readline 默认的补全处理。
当⼀个规则指出期望⽬录名补全时,可编程补全函数强制 readline 在补全的名称后⾯添加⼀个斜杠,如果它是⼀个到⽬录的符号连接。然后还要经过 readline 变量 mark-directories 的值处理,不管 readline 变量 mark-symlinked-directories 的值是什么。
补全相关的 shell内建命令(SHELL BUILTIN COMMANDS)
compgen
根据option为word产⽣可能的补全。option是内建命令complete接受的任何选项,除了-p和-r,将匹配结果写到标准输出。当使⽤-F或-C选项时,可编程补全功能所设置的多数 shell 变量如果存在,其值将不再有⽤。
产⽣的匹配与可编程补全代码根据补全规则加上相同的标志直接产⽣的结果相同。如果指定了word,只有匹配word的补全结果将被显⽰出来。
返回值为真,除⾮提供了⾮法的选项,或者没有产⽣匹配。
complete
指定每个 name 的参数应当如何被补全。如果给出了 -p 选项,或者没有选项给出,现有的补全规则将被显⽰出来,以⼀种可以重⽤为输⼊的格式显⽰。-r 选项将⼀个针对每个 name 的补全规则删除。或者,如果没有给出 name,将删除所有补全规则。
尝试词的补全时,应⽤这些补全规则的过程在上⾯ Programmable Completion(可编程补全) 中详述。
其他选项,如果给出的话,具有下列意义。-G, -W, 和 -X 选项的参数 (如果需要的话,还包括 -P 和 -S 选项) 应当被引⽤,避免在执⾏内建命令 complete 之前被扩展。
返回值为真,除⾮给出了⾮法的选项,给出除 -p 和 -r 之外的某个选项时没有给出 name 参数,试图删除⼀条 name 的补全规则但是规则不存在,或者添加补全规则时出错。
-o comp-option
comp-option 控制着 compspec 除了简单地产⽣补全之外的多种⾏为。 comp-option 可以是如下之⼀:
action meaning
default使⽤ readline 的默认⽂件名补全,如果 compspec 没有得到匹配
dirnames进⾏⽬录名补全,如果 compspec 没有得到匹配
filenames 告诉 readline,compspec 产⽣了⽂件名,使它可以进⾏任何⽂件名专⽤的处理 (例如,给⽬录名加上斜杠或消除尾部空⽩)。主要⽤于 shell 函数
(博主注)例如:
COMPREPLY=($(compgen -W "${fix_list}" -- "${cur}"))
compgen [option] [word]
complete [-abcdefgjksuv] [-o comp-option] [-A action] [-G globpat] [-W wordlist] [-P prefix] [-S suffix]  [-X filterpat] [-F function] [-C command] name [name ...]
complete -pr [name ...]
nospace告诉 readline 不要向补全的词在⾏的最后添加⼀个空格 (这是默认⾏为)
action meaning
-A action
action 可以是下列之⼀,来产⽣⼀系列可能的补全结果:
action meaning
alias起别名。也可以⽤ -a 指定
arrayvar数组变量名
binding Readline按键关联
builtin shell内建命令的名称。也可以⽤ -b 指定
command命令名。也可以⽤ -c 指定
directory⽬录名。也可以⽤ -d 指定
disabled被禁⽤的内建命令名称
enabled启⽤的内建命令名称
export被导出的 shell 变量名称。也可以⽤ -e 指定
file⽂件名。也可以⽤ -f 指定
function shell 函数的名称
group组名。也可以⽤ -g 指定
helptopic内建命令 help 接受的帮助主题
hostname主机名,从环境变量 HOSTFILE 指定的⽂件中得到
job作业名,如果作业控制被激活的话。也可以⽤ -j 指定
keyword shell 保留字。也可以⽤ -k 指定
running正在运⾏的作业名,如果作业控制被激活的话
service服务名。也可以⽤ -s 指定
setopt内建命令 set 的 -o 选项的有效参数
shopt内建命令 shopt 接受的 shell 选项名
signal信号名
stopped停⽌的作业名,如果作业控制被激活的话
user⽤户名。也可以⽤ -u 指定
variable shell 变量的名称。也可以⽤ -v 指定
-G globpat
⽂件名扩展模式 globpat 被扩展,产⽣可能的补全。
-W wordlist
wordlist 被使⽤ IFS 特殊变量中的字符作为定界符来拆分,每个结果的词被扩展。可能的补全是结果列表中匹配要补全的词的那⼀些。
-C command
command 将在⼀个⼦ shell 环境中执⾏,它的结果⽤作可能的补全。
-F function
shell 函数 function 将在当前 shell 环境中执⾏。当它结束时,可能的补全可以从数组元素 COMPREPLY 中得到。
-X filterpat
filterpat 是⼀个模式,⽤于⽂件名扩展。所有前⾯的选项和参数产⽣的可能的补全都要经过这⼀步处理,每⼀个匹配 filterpat 的补全都被从列表中删除。为 filterpat 加上前导 ! 使模式意义相反;这种情况下,所有不匹配 filterpat 的模式被删除。
-P prefix
在所有其他选项都处理过之后,prefix 被加到每个可能的补全前⾯。
-S suffix
在所有其他选项都处理过之后,suffix 被加到每个可能的补全后⾯。
shopt
shopt [-pqsu] [-o] [optname ...]
对于控制可选的 shell ⾏为的变量,改变它们的值。没有选项或者有-p选项时,将显⽰所有可设置的选项列表,以及它们是否已经设置的指⽰。-p使得输出以⼀种可以被重⽤为输⼊的形式显⽰。
其他选项有如下含义:
-s: 允许(设置) 每个 optname。
-u: 禁⽌(取消) 每个 optname。
-q: 禁⽌通常的输出 (安静模式);返回状态指⽰了 optname 是否被设置。如果对 -q 给出了多个 optname 参数,如果所有 optname 都被允许,返回值就是 0;否则返回⾮零值。
-o: 限制 optname 的值为内建命令 set 的 -o 选项定义的值。
如果使⽤ -s 或 -u 时没有给出 optname 参数,显⽰将分别限于被设置或被取消的选项。除⾮另外说明,shopt 选项默认被禁⽌(取消)。
返回值在列出选项时是 0,如果所有 optname 都被允许的话,否则是⾮零值。当设置或取消选项时,返回值是 0,除⾮ optname 是⾮法的shell 选项。
shopt选项的列表是:
cdable_vars
如果设置的话,内建命令 cd 的参数如果不是⽬录,就假定是⼀个变量,它的值是要切换到的⽬录名。
cdspell
如果设置的话, cd 命令中⽬录的细微拼写错误能够得以纠正。检查的错误包括字符错位,缺字符,重复输⼊同⼀字符。如果到了正确的值,将打印正确的⽂件名,命令将继续。这个选项只能在交互 shell 中使⽤。
hostcomplete
如果设置的话,并且正在使⽤ readline, bash 将试着对正在进⾏补全的包含的词进⾏主机名补全 (参见上⾯的 READLINE 中的Completing 段落)。这是默认允许的。
no_empty_cmd_completion
如果设置的话,并且正在使⽤ readline,试图在空⾏上执⾏补全时, bash 不会搜索 PATH 来查可能的补全。
nocaseglob
如果设置的话, bash 进⾏路径扩展时使⽤⼤⼩写不敏感⽅式匹配⽂件名(参见上⾯的 Pathname Expansion 路径扩展)。
progcomp
如果设置的话,将启⽤可编程补全功能 (参见上⾯的 Programmable Completion)。这个选项是默认启⽤的。
...
篇幅与⽂章主题的原因,不展开更多的shopt列表介绍。
>suv是什么