SSH AutoComplete on OSX

I am a very heavy user of SSH, like everyday all day type of user. I know a couple cool SSH tricks like port forwarding and mapping remote drives. One thing that always bugged me was the lack of auto complete when I was on my OSX machine. You see with SSH, you can define a bunch of individual host and configurations unique to those host in a file called .ssh/config. It's a great tool to have and when you do have some host define, on a Linux machine, you can type in the command ssh, then the first couple if letters of the host and hit tab. It will act as any tab completion does for commands and fill in as much of the hostname as it can before it requires some other unique identifier. However, this cool autocomplete feature didn't happen naturally of my OSX box.

Through the years, I've had an idea of what I needed to do to create my own script to handle it. There is the complete command, the trick is grepping the config file and pulling out the right information. I decided to be lazy and just manually created several alias for my ssh server. The alias approach worked, but this grew into a very long list of alias and wasn't very efficient. So tonight I decided I was going to write the script to meet my needs and about 2 clicks on Google links later, I found someone who had actually already completely done it. Nem W. Schlecht posted his script on a Macworld hints forum a couple years ago. Here is a link to that original thread http://goo.gl/Wd4Z5 but the piece of magic that did the trick is below. As a added bonus, it also creates auto complete from servers it finds in your known_host file. I will repost his post, not just the code, because he has some wise advice on where to place the code

The macports suggestion is a good one, but IMO, includes too much. If you don't have macports installed, you can add the following to your .bash_profile (I wouldn't add it to my .bashrc, since that gets read in by cron jobs and remote commands).

There are a couple improvements here. First, this will also read in aliases in your ~/.ssh/config file. Secondly, it will ignore commented out entries in your ~/.ssh/known_hosts file. Finally, this is a function and not a static list. Thus, it is immediately aware of any new additions to either file (although on really slow machines it will be slower than a static list).

_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

Don't forget you need to "source" you file to get the new command to load in your terminal or you can close your terminal window and open a new one.

Posted via email from shocm

  • Tomas Gutierrez

    Thanks for posting this! One think I miss after using this for a while is that it breaks the path auto-complete functionality (for example, when going to a particular path for a certificate, etc).

    Thoughts on how to get that back?

  • Pingback: Just another IT guy blog… » Blog Archive » SSH autocomplete on Mac OSX()

  • Ng Dinh Toan

    I think line grep -v “[” ; should be grep -v “[” ;

  • jsmoriss

    _complete_ssh_hosts () {
            COMPREPLY=()
            cur=”${COMP_WORDS[COMP_CWORD]}”
            comp_ssh_hosts=`egrep -v ‘^[#[]’ ~/.ssh/known_hosts|
                    cut -f 1 -d ‘ ‘|sed -e ‘s/[,:].*//g’|uniq;
                    awk ‘/^Host/ { print $2; }’ ~/.ssh/config`
            COMPREPLY=( $(compgen -W “${comp_ssh_hosts}” — $cur))
            return 0
    }
    complete -F _complete_ssh_hosts ssh

  • fgallnii

    Very useful, thanks a lot 🙂
    Any way to make SSH case insensitive?

    Thanks for your support 🙂

    • shocm

      Case sensitivity is more of a OS level issue. There may be a way to trick this script with some regex, I would need to play with it a little.

  • Alfred Nutile

    Thanks!

  • Pingback: Consultor informático tecnologías libres()