如何在zsh上编辑ssh的命令完成?

我想在zsh上设置命令完成,以在我键入之后显示主机名

ssh [TAB] 

从我的.ssh / config文件(最好从known_hosts和/ etc / hosts以及其他任何有意义的地方)中提取名称,然后显示一个列表。

它目前做了一些,但是

  1. 它根本不使用.ssh / config
  2. 它首先需要用户名,即使使用.ssh / config也不需要input用户名
  3. 它提供了多个列表(可能来自known_hosts,另一个来自/ etc / hosts,但我没有证实)

所以我想在inputssh [TAB]之后在(最好是单个)列表中包含已知的用户名和已知的主机名,

(我在Google之前来到这里,因为1)会导致答案被存储在这里,2)它可能更有效率。 如果没有人回答,我会寻找答案。)

这里是我的.zshrc的相关部分。 它从2002年以来一直没有改变,所以我可能今天的写法不同,但它仍然可以完成~/.ssh/config~/.ssh/known_hosts主机名(如果HashKnownHostsclosures – 它不存在那些天)。

 h=() if [[ -r ~/.ssh/config ]]; then h=($h ${${${(@M)${(f)"$(cat ~/.ssh/config)"}:#Host *}#Host }:#*[*?]*}) fi if [[ -r ~/.ssh/known_hosts ]]; then h=($h ${${${(f)"$(cat ~/.ssh/known_hosts{,2} || true)"}%%\ *}%%,*}) 2>/dev/null fi if [[ $#h -gt 0 ]]; then zstyle ':completion:*:ssh:*' hosts $h zstyle ':completion:*:slogin:*' hosts $h fi 

提供ssh完成的函数位于我的系统上的/usr/share/zsh/functions/Completion/Unix/_ssh

另外请参阅man zshcompsys的文档(特别是在多个地方出现的“host”和在几个地方出现的“ssh”上search)。

在你的~/.zshrc zstyle中添加一个zstyle命令可能会做你想要的,而不必修改完成function。

我使用dig来使用给定域上的所有主机列表来执行此操作。 你可以用下面的函数replace你想要的任何查询系统,包括你的hosts文件或者一个静态列表:

 function complete_host_from_zone () { reply=(`dig axfr ouraynet.com @ns1.ouraynet.com | grep -e '^[az]' | cut -d\. -f1`) } compctl -x 'p[1]' -K complete_host_from_zone -- ssh 

注意:上面的代码可能不能完全替代configuration中的ssh命令的完整系统。 如果你有问题,可以尝试改变“ssh”命令到其他一些随机命令,比如“mycompletetest”,看看这个完成是否适用。

另外请注意,这是每个完成的DNS区域传输! 如果你使用这个或者在一个相当静态的域上,那么查找并保存结果是有意义的,然后在你的查找函数中设置reply = zone_result。

我喜欢保持我的哈希known_hosts文件,而不是closuresHashKnownHosts 。 我发现播种@Gilles已经在我的历史上已经是相当有效的我的需要。

 h=($(echo $(history | awk '{print $4 " " $5 "\n"}' | grep 'ssh ' | awk '{print $2}' | sort -u))) if [[ -r ~/.ssh/config ]]; then h=($h ${${${(@M)${(f)"$(cat ~/.ssh/config)"}:#Host *}#Host }:#*[*?]*}) fi if [[ -r ~/.ssh/known_hosts ]]; then h=($h ${${${(f)"$(cat ~/.ssh/known_hosts{,2} || true)"}%%\ *}%%,*}) 2>/dev/null fi if [[ $#h -gt 0 ]]; then zstyle ':completion:*:ssh:*' hosts $h zstyle ':completion:*:slogin:*' hosts $h fi 

另外,FWIW,这是我用于Bash的:

 # SSH Autocompletion complete -W " $(echo $(grep '^\s*ssh ' ~/.bash_history | sort -u | sed 's/^ssh //' | awk '{print $1}')) $(echo $(history | awk '{print $2 " " $3}' | grep 'ssh ' | awk '{print $2}' | sort -u)) $(sed 's/#.*//;' ~/.ssh/config | awk ' /^Host (.+)$/ {$1 = "";print tolower($0)}') " ssh