Enable Tab Completion for SSH Aliases

Apr 6, 2011 - 17 Comments

Yesterday we showed you how to setup a basic SSH Config file, and here’s how to make that even more useful: enable tab completion for those SSH aliases.

Throw this into ~/.bash_profile or ~/.bashrc

# Add Tab-completion for SSH host aliases
complete -o default -o nospace -W "$(/usr/bin/env ruby -ne 'puts $_.split(/[,s]+/)[1..-1].reject{|host| host.match(/*|?/)} if $_.match(/^s*Hosts+/);' < $HOME/.ssh/config)" scp sftp ssh

That should be on one line. Save the file, relaunch the Terminal, and now you can use tab completion with SSH aliases.

Thanks to Doug Schmidt for the submission!


Related articles:

Posted by: David Mendez in Command Line


» Comments RSS Feed

  1. Kim says:

    hey there… i’m quite late.. but i also got in some troubles while configuring this on my macbook pro (lion)

    so.. just check if your local .bashrc is even called! (try with echo “hi” or something similar)

    if not, insert this in /etc/profile right after the /etc/bashrc-call:

    [ -r $HOME/.bashrc ] && source $HOME/.bashrc

    (or just write it in the global /etc/bashrc)

  2. none of the above works without errors. tried them all.

  3. Here is the correct command:

    /usr/bin/env ruby -ne ‘puts $_.split(/[,\s]+/)[1..-1].reject{|host| host.match(/\*|\?/)} if $_.match(/\s*Host\s+/);’ < $HOME/.ssh/config

    • I mean:

      complete -o default -o nospace -W “$(/usr/bin/env ruby -ne ‘puts $_.split(/[,\s]+/)[1..-1].reject{|host| host.match(/\*|\?/)} if $_.match(/\s*Host\s+/);’ < $HOME/.ssh/config)" scp sftp ssh

      remember to replace the quotes :)

  4. Nick says:

    Awk variant (combining greps and cut into one system call), accepting multiple hostnames on the Host line in the config:

    complete -o default -o nospace -W “$(awk ‘/^Host / {sub(“^Host “, “”); print $0;}’ < $HOME/.ssh/config)" scp sftp ssh

    (I don't have ruby installed either).

    • MetalRufflez says:

      You can simplify even mor the awk command:
      complete -o default -o nospace -W “$(awk ‘/^Host / {print $2}’ < $HOME/.ssh/config) scp sftp ssh

  5. Mike says:

    You can also set this up easily in your .bash_profile to use the values in your /etc/hosts file:

    complete -A hostname ftp sftp ssh

  6. MetalRufflez says:

    Bro, why use ruby if you can use bash, its WAY easier and works in every *nix

    complete -o default -o nospace -W “$(grep “^Host” $HOME/.ssh/config | cut -d” ” -f2)” scp sftp ssh

    • Justin says:

      Thanks! I added a filter to exclude the wildcard entries i have in my config:

      complete -o default -o nospace -W β€œ$(grep β€œ^Host” $HOME/.ssh/config | grep -v ‘[?*] | cut -d” ” -f2)” scp sftp ssh

      • Justin says:

        sigh. that should be

        complete -o default -o nospace -W β€œ$(grep β€œ^Host” $HOME/.ssh/config | grep -v “[?*]” | cut -d” ” -f2)” scp sftp ssh

    • Cliff says:

      I’d prefer to use bash but this does not work for me

  7. luca says:

    reopening Terminal, this is the error message I’ve been given:

    -e:1: invalid regular expression; there’s no previous pattern, to which ‘*’ would define cardinality at 1: /*|?/


    • Tavis says:

      Nice trick but you can also just use aliasing:

      alias connect=’ssh name@server’

      Then all you have to type is ‘connect’ isn’t that easier than all this?

      • luca says:

        it’s easier if you just need to alias one single host, as you’re aliasing the whole command
        instead, with the regular expression, you’ll be able to use a whole catalogue of aliases as you’re aliasing just the host-side of the ssh-command.

    • lkuty says:

      Backslashes have disappeared.

      Before s (3 of them), *, ? in regular expressions above we need a backslash.

Leave a Reply


Shop on Amazon.com and help support OSXDaily!

Subscribe to OSXDaily

Subscribe to RSS Subscribe to Twitter Feed Follow on Facebook Subscribe to eMail Updates

Tips & Tricks


iPhone / iPad



Shop on Amazon to help support this site