6月 192016
 

很多命令都会提供一个bash-complete的脚本,在执行该命令时,敲tab可以自动补全参数,会极大提高生产效率。docker亦如此,如:yum install docker后,会有一个文件: /usr/share/bash-completion/completions/docker ; 显然,该脚本是用于bash自动补全的,但是,不幸的是,直接 source 执行该脚本后,docker命令后敲tab,有如下错误:

难道docker的bash自动补全还能有问题?

放狗一搜,解决办法如下:

我这里虽然安装了bash-completion ,但是没有执行其中的一个文件:

该文件中有上面缺少的命令,自然,执行该文件就解决了。

其实 bash_completion 包中已经包含了一堆常用命令的bash自动补全的脚本的:

 

bash补全脚本编写:(实例)

 

complete -F func cmd 其中func的规则:

func可以接受到3个参数:

$0: 就是bash

$1: 命令名

$2: 需要补全的单词的一部分

$3: 上一个完整的单词 , 如果当前要补全的是第一个参数,则上一个完整的单词就是命令名

 

使用命令(任何语言)来实现命令补全(不过还是shell方便,实在不会shell就选择其他语言):

通过命令 mycomplete 给命令phpor来补全:

其中: mycomplete 命令将接到三个参数:

$1: 命令名(就是phpor)

$2: 需要补全的单词

$3: 命令行中出现的最后一个完整的单词

mycomplete要做的事情就是根据最后一个完整的单词来推测下个(要补全的)单词;只是如果命令行中已经包含了超过3个单词,则第二个单词信息将得不到; 其实不是的,只是从命令行参数中得不到,从环境变量是可以得到的,环境变量 COMP_LINE 保存了整个命令行的内容,命令行参数只是有助于我们定位光标的位置。


complete -C  和 -F 的说明

-C 指定一个命令; -F 指定一个函数 。 那么, -C 指定一个函数能行吗?  -F 指定函数一定能行吗?

其实:

  1. -C 也能指定一个函数, 这两个选项的本质不是函数或者二进制程序的命令; 而是传递信息的方式不同(未验证,有时间再验证)
    1. 如果指定-C ,那么会通过参数和export出来的环境变量来传递
    2. 如果指定-F, 那么会通过参数和特定的全局变量来传递

 


可以通过是strace -e file bash 来了解bash自动补全的逻辑,可以通过函数命令complete来设置自动补全函数,如果不存在自动补全函数的话,会自动在补全目录下搜索当前执行的命令为名称的文件,如  ~/.local/share/bash-completion/completions/byssh ,我们可以在这里添加自动补全逻辑

 

complete 的更多用法参考: man bash  搜索: Programmable Completion

如果我们需要补全一些常规得到东西,可以使用 -A ,如:

  1. 补全当前shell中的函数: complete -A function xxx
  2. 补全当前shell中的alias : complete -A alias xxx

参考资料:

 Posted by at 下午 9:38

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

(required)

(required)

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据