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!
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)
none of the above works without errors. tried them all.
What error did you get?
The simplified one just above your comment is missing a quote. Here is the corrected version of it:
complete -o default -o nospace -W “$(awk ‘/^Host / {print $2}’ < $HOME/.ssh/config)" scp sftp ssh
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 :)
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).
You can simplify even mor the awk command:
complete -o default -o nospace -W “$(awk ‘/^Host / {print $2}’ < $HOME/.ssh/config) scp sftp ssh
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
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
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
sigh. that should be
complete -o default -o nospace -W “$(grep “^Host” $HOME/.ssh/config | grep -v “[?*]” | cut -d” ” -f2)” scp sftp ssh
I’d prefer to use bash but this does not work for me
Hi,
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: /*|?/
greets,
luca
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?
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.
Backslashes have disappeared.
Before s (3 of them), *, ? in regular expressions above we need a backslash.