SSH 配置主机自动完成命令不自动完成

SSH 配置主机自动完成命令不自动完成

我编写了一个函数来从 ssh 配置获取主机,而无需获取通配符主机:

sshConfAutoComplete() { 
   cat ~/.ssh/config | \
   grep 'host '      | \
   sed '
     s#.*\*##g; 
     s#host ##g
   '
}

输出:

pi
lynx
iridium
batchelorantor
rasp

输出是正确的,所以我将这个函数添加到: /usr/local/etc/bash_completion.d/ssh

像这样:

sshConfAutoComplete() { 
   cat ~/.ssh/config | \
   grep 'host '      | \
   sed '
     s#.*\*##g; 
     s#host ##g
   '
}
complete -F sshConfAutoComplete ssh

然后我添加了这个来源. /usr/local/etc/bash_completion.d/ssh~/.bash_profile

Sourced ~/bash_profile,然后当我输入ssh <tab>以下内容时会出现:

pi
lynx
iridium
batchelorantor
rasp

如果我输入ssh ly <tab>它不会自动完成 to lynx,它只会输出上面的内容。

我该如何解决?

答案1

man bash标题为可编程完成解释了调用的函数如何-F需要在数组变量中提供匹配结果COMPREPLY。通常,命令提供的完整列表sed 会传递给命令,compgen -W以便它尝试将单词与目标单词(即$2函数的 arg 2 ( ))进行匹配。稍微简化一下我们得到:

sshConfAutoComplete() { 
   COMPREPLY=( $(compgen -W \
    "$(sed -n ' /host /{s#.*\*##g; s#host ##g; p} ' ~/.ssh/config)" -- "$2"))
}
complete -F sshConfAutoComplete ssh

对于 MacOS,标准sed命令不接受;,因此每个命令必须换行:

   COMPREPLY=( $(compgen -W \
    "$(sed -n '/^host /{
     s#.*\*##g
     s#host ##g
     p
    }' ~/.ssh/config)" -- "$2"))

答案2

我做到了这一点并将其添加到我的~/bash_profile

IFS=$'\n'

getSshConfHosts() {                                                                                                                                              
  grep    '^host' ~/.ssh/config  | \                                                                                                                                  
  grep -v '[?*]'                 | \                                                                                                                                      
  cut -d ' ' -f 2-                                                                                                                                       
}

sshConfAutoComplete() {                                                                                                                                          
    local cur prev opts                                                                                                                                                                
    cur=${COMP_WORDS[COMP_CWORD]}                                                                                                                                                                  
    prev=${COMP_WORDS[COMP_CWORD-1]}                                                                                                                                  
    opts=$(getSshConfHosts)                                                                                                                                                       
    COMPREPLY=( $(compgen -W "$opts" -- $cur ) )                                                                                                     
}         
complete -F sshConfAutoComplete ssh

我之前的 sed 命令在删除时留下了一个空行host *

更新

这个答案有效,但我把它给了接受的答案,因为他不知道我在 Mac 上,而且他也没有先写它。他的版本更容易理解。

我在另一个函数中使用正则表达式部分,所以我在我的bash_profile

IFS=$'\n'

getSshConfHosts() {
   sed -n '/^host /{
     s#.*\*##g
     s#host ##g; p
   }' ~/.ssh/config
}

sshConfAutoComplete() {
    local wordList
    wordList=$(getSshConfHosts)
    COMPREPLY=( $(compgen -W "$wordList" -- $2 ) )
}
complete -F sshConfAutoComplete ssh

相关内容