-
Star
(143)
You must be signed in to star a gist -
Fork
(40)
You must be signed in to fork a gist
-
-
Save aliang/1024466 to your computer and use it in GitHub Desktop.
_complete_ssh_hosts () | |
{ | |
COMPREPLY=() | |
cur="${COMP_WORDS[COMP_CWORD]}" | |
comp_ssh_hosts=`cat ~/.ssh/known_hosts | \ | |
cut -f 1 -d ' ' | \ | |
sed -e s/,.*//g | \ | |
grep -v ^# | \ | |
uniq | \ | |
grep -v "\[" ; | |
cat ~/.ssh/config | \ | |
grep "^Host " | \ | |
awk '{print $2}' | |
` | |
COMPREPLY=( $(compgen -W "${comp_ssh_hosts}" -- $cur)) | |
return 0 | |
} | |
complete -F _complete_ssh_hosts ssh |
It doesn't work for me, I get
~/.zprofile: command not found: complete
The same. MacOS Monterey 12.5.1
Thanks for this script.
I removed the known_hosts section because I want only the .ssh/config file to be parsed.
_complete_ssh_hosts ()
{
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
comp_ssh_hosts=`cat ~/.ssh/config | \
grep --color=never "^Host " | \
awk '{print $2}'
`
COMPREPLY=( $(compgen -W "${comp_ssh_hosts}" -- $cur))
return 0
}
complete -F _complete_ssh_hosts ssh
It doesn't work for me, I get
~/.zprofile: command not found: complete
The same. MacOS Monterey 12.5.1
The script is written in bash. zsh has a different way of doing things.
Converted the searches to AWK so there is only 2 commands being called instead of 9 and it is easy to comment out one of the sources if you don't like it.
_complete_ssh_hosts ()
{
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
comp_ssh_hosts=`
awk '{split($1,aliases,","); if (aliases[1] !~ /^\[/) print aliases[1]}' ~/.ssh/known_hosts ;
awk '/^Host/ && $2 !~ /[*]/ {print $2}' ~/.ssh/config ;
`
COMPREPLY=( $(compgen -W "${comp_ssh_hosts}" -- $cur))
return 0
}
complete -F _complete_ssh_hosts ssh
Actually, this can work for zsh as well, we just need to enable bash style autocomplete before using this function.
Here is complete example: put this inside ~/.zshrc
#### initialize completion system ####
# see https://unix.stackexchange.com/questions/593433/bash-like-autocompletion-for-ssh-command-in-zsh-shell-with-etc-hosts-file
# see https://zsh.sourceforge.io/Doc/Release/Completion-System.html
autoload -Uz compinit; compinit
# enable bash style autocomplete (requires compinit to be called before this)
# see https://stackoverflow.com/questions/3249432/can-a-bash-tab-completion-script-be-used-in-zsh
# see https://zsh.sourceforge.io/Doc/Release/Completion-System.html
autoload -Uz bashcompinit; bashcompinit
# replace the default ssh autocomplete that comes from compinit
# with this _complete_ssh_hosts function which looks for hosts in ~/.ssh/config and ~/.ssh/known_hosts
# Note: requires bashcompinit to enable this bash style autocomplete function
# see https://stackoverflow.com/questions/52438964/mac-autocomplete-for-ssh-hosts-in-terminal
# see https://gist.github.com/aliang/1024466
_complete_ssh_hosts ()
{
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
comp_ssh_hosts=`
awk '{split($1,aliases,","); if (aliases[1] !~ /^\[/) print aliases[1]}' ~/.ssh/known_hosts ;
awk '/^Host/ && $2 !~ /[*]/ {print $2}' ~/.ssh/config ;
`
COMPREPLY=( $(compgen -W "${comp_ssh_hosts}" -- $cur))
return 0
}
complete -F _complete_ssh_hosts ssh
Thanks!!!
I tweaked it to work when you have multiple known_hosts files, and multiple config files:
# shellcheck shell=bash
# Add tab completion for SSH hostnames
#
# Based on this gist: https://gist.github.com/aliang/1024466
#
# Search in:
# - ~/.ssh/config
# - ~/.ssh/config.d/*config
# - ~/.ssh/*known_hosts
_complete_ssh_hosts ()
{
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
comp_ssh_hosts=$(
sort -u < <(
awk '{split($1,aliases,","); if (aliases[1] !~ /^\[/) print aliases[1]}' < <(
# list all known_hosts files, ignoring blank lines and comments
# awk code taken from https://stackoverflow.com/a/17396799
awk '!/^ *#/ && NF' < <(cat ~/.ssh/*known_hosts)
)
awk '/^Host/ && $2 !~ /[*]/ {print $2}' <(
cat ~/.ssh/{config,config.d/*config}
)
)
)
COMPREPLY=( $(compgen -W "$comp_ssh_hosts" -- $cur) )
return 0
}
complete -F _complete_ssh_hosts ssh
It doesn't work for me, I get
~/.zprofile: command not found: complete