BASH命令自动补全

BASH命令自动补全是一个提供命令参数制表符补全的功能。您熟悉它的默认行为,即完成文件名和路径。

~ ls enctypt<TAB>
encrypt              encrypt-only-sym.rb  encrypt-time.rb
encrypt-decrypt.rb   encrypt-sym.rb       encrypt.rb
~  ls encrypt

您可以通过为BASH提供可能完成的列表来覆盖此行为。该列表可以是单词的文字列表,也可以是查看当前环境, 并生成上下文感知列表的函数。

因此,我们想要的是一种生成我们知道的主机列表的方法。您知道第一次通过SSH连接到新服务器时如何提示您确认其身份吗?好吧,确认信息和主机名一起存储在中~/.ssh/known_hosts。从该文件中,我们可以提取一个列表,该列表应涵盖我们关心的大多数服务器。

简单的方法是在登录时建立一个列表。如果您百度一下,您会发现很多示例脚本,这些脚本可用于从known_hosts中提取主机名,但最常见的外观如下:

echo `cat ~/.ssh/known_hosts | cut -f 1 -d ' ' | sed -e s/,.*//g | uniq | grep -v "\["`

设置自动完成的命令是complete。在给它一个列表时,将它们作为-W选项传递给:

complete -W "$(echo `cat ~/.ssh/known_hosts | cut -f 1 -d ' ' | sed -e s/,.*//g | uniq | grep -v "\["`;)" wait-for-host

我正在捕获命令的输出,$()并将其包装在双引号中。最后一个参数是将使用此自动补全功能的命令名称(也可以是函数或别名)。现在我们得到这个:

~ wait-for-host www<TAB>
www.example.com            www1.example.com
~ wait-for-host www

效果很好,但它是静态的,仅适用于一个命令。相反,您可以创建一个可重用的函数。

_known_hosts() {
    local know_hosts cur
    known_hosts=$(cat ~/.ssh/known_hosts | cut -f 1 -d ' ' | sed -e s/,.*//g | uniq | grep -v "\[")

    cur="${COMP_WORDS[COMP_CWORD]}"

    COMPREPLY=( $(compgen -W "$known_hosts" -- ${cur}) )
    return 0
}

BASH自动完成功能是功能强大的功能,但今天,我们将其保持简单。首先,我们像以前一样构建一个选项列表,并将其存储在中$known_hosts。其次,我们得到当前单词,即命令参数,它是制表符补全。最后,我们传递该列表和compgenBASH内部匹配器所对应的单词。compgen具有一些强大的功能,但在这种情况下,它将仅返回以$known_hosts我们在tab上单击的单词开头的主机列表。

然后,通过给它提供-f选项以及函数名称(而不是:)来告诉完成操作,我们正在使用函数-W:

complete -F _known_hosts wait-for-host

您还可以将该_known_hosts函数用于其他命令:

complete -F _known_hosts ssh

这是理解自动补全的很好的练习,但这是非常基本的。幸运的是,人们已经完成了bash完成 项目中的所有艰苦工作。默认情况下,许多Linux发行版都附带了该版本。在Mac上:

brew install bash-completion
if [ -f $(brew --prefix)/etc/bash_completion ]; then
    . $(brew --prefix)/etc/bash_completion
fi

这将为从SSH到rsync的所有内容添加上下文相关的完成_known_hosts功能,并为您提供更聪明的功能,可与您自己的命令一起使用。

如果您想了解更多信息,建议阅读bash补全 代码。它执行的功能远比我在这里介绍的功能强大,对于您自己的完成功能而言,这是一个很好的起点。

Bash printf命令
bash命令: trap
Tags:,