Skip to content

Instantly share code, notes, and snippets.

@aliang
Created June 14, 2011 07:14
Show Gist options
  • Save aliang/1024466 to your computer and use it in GitHub Desktop.
Save aliang/1024466 to your computer and use it in GitHub Desktop.
Add auto complete to your ssh, put into your .bash_profile
_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
@anoopengineer
Copy link

👍

@abrambailey
Copy link

Worked like a charm.

@ronaknnathani
Copy link

Very helpful - thanks!

@mconcas
Copy link

mconcas commented May 28, 2016

Great job, Thanks!

@Ayesh
Copy link

Ayesh commented Jun 11, 2016

Thanks a lot. Been searching for this gem all over.

@yourbuddyconner
Copy link

Thanks for the snippet, worked like a charm!

Copy link

ghost commented Aug 18, 2016

This little guy packs a helluva punch!

@lavagetto
Copy link

you could substitute that awkward sequence of cut, sed, grep with a simple awk script:
awk '{split($1,aliases,","); if (aliases[1] !~ /^\[/) print aliases[1]}' ~/.ssh/known_hosts

@nickwilmes
Copy link

Works right out of the box! Awesome job!!

@boxers999
Copy link

Good Job !

@dkaranja
Copy link

Works like a charm!!! 👍

@crmpicco
Copy link

Perfect. It worked for me out of the box on:

ProductName:	Mac OS X
ProductVersion:	10.12.5
BuildVersion:	16F73

@xralphack
Copy link

good job

@tansaku
Copy link

tansaku commented Aug 7, 2017

wonderful!

@lbadger
Copy link

lbadger commented Aug 24, 2017

Whoot! Thanks!

@thrbowl
Copy link

thrbowl commented Sep 21, 2017

cool, thanx

@bees4ever
Copy link

It's absolutely brilliant 🌟 , thank you! 😄

@garrethmcdaid-zd
Copy link

Thanks

@csullivannet
Copy link

Works perfectly, thanks!

@thilinaba
Copy link

This is cool. Thanks.

@crmpicco
Copy link

crmpicco commented Oct 8, 2018

I came back for a reminder when setting up a new machine 👍

@xv1t
Copy link

xv1t commented Oct 17, 2018

Thanx from my MacBook :) 👍

@sparkmuse
Copy link

Hello,
I did not have a ~/.ssh/config file so I got an error. So I modified the script a little to redirect errors from 'cat'.

_complete_ssh_hosts ()
{
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    comp_ssh_hosts=`cat ~/.ssh/known_hosts 2>/dev/null | \
                    cut -f 1 -d ' ' | \
                    sed -e s/,.*//g | \
                    grep -v ^# | \
                    uniq | \
                    grep -v "\[" ;
                    cat ~/.ssh/config 2>/dev/null | \
                    grep "^Host " | \
                    awk '{print $2}'
                    `
    COMPREPLY=( $(compgen -W "${comp_ssh_hosts}" -- $cur))
    return 0
}
complete -F _complete_ssh_hosts ssh

@r-souza
Copy link

r-souza commented Dec 15, 2020

Great!

@mherkazandjian
Copy link

i was getting some color fomatting chars in the output off ssh config. It turns out it was due to the colors emitted by "grep".
Probably to make this more robust the --color=never flag can be added to grep

_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 --color=never "^Host " | \
                         awk '{print $2}'
                   `
        COMPREPLY=( $(compgen -W "${comp_ssh_hosts}" -- $cur))
        return 0
}
complete -F _complete_ssh_hosts ssh

@cossio
Copy link

cossio commented Sep 24, 2022

It doesn't work for me, I get ~/.zprofile: command not found: complete

@baonq-me
Copy link

baonq-me commented Dec 6, 2022

It doesn't work for me, I get ~/.zprofile: command not found: complete

The same. MacOS Monterey 12.5.1

@Lat31320
Copy link

Lat31320 commented Mar 2, 2023

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

@timhughes
Copy link

timhughes commented Aug 1, 2023

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

@michaelleb
Copy link

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


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment