ZSH Autocomplete with SSH Config File
If you do any kind of web work for a living, you probably deal with ssh on a daily basis. You also probably have multiple servers that you need to ssh into at any given time. If you’re like me, you probably don’t like wasting time trying to figure out ssh params (did the ip address end in 173 or 137?). Well in recent times I’ve found that the built in ssh config file has some pretty awesome capabilities as well as ZSH has some nice autocompletion to boot. Together they make a pretty good workflow and you can spend time solving problems and not remembers ports and ip addresses.
Alias the SSH command
It might seem like over-engineering but ever since I really started getting into
using bash aliases I’ve followed a personal rule that any command that I use
on a daily basis should be as few keystrokes as possible. Even though it’s only
saving 2 keystrokes I still keep this alias in my ~/.zshrc
file:
alias s='ssh'
Get Some ZSH Autocomplete
Tab completion is your best friend when it comes to the command line, utilize it. ZSH has a very extensive autocomplete system which can be a little difficult to grasp but I’ve pulled out the essential parts out my zshrc to give a quick snippet which will give you full ssh autocompletion:
# Highlight the current autocomplete option
zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}"
# Better SSH/Rsync/SCP Autocomplete
zstyle ':completion:*:(scp|rsync):*' tag-order ' hosts:-ipaddr:ip\ address hosts:-host:host files'
zstyle ':completion:*:(ssh|scp|rsync):*:hosts-host' ignored-patterns '*(.|:)*' loopback ip6-loopback localhost ip6-localhost broadcasthost
zstyle ':completion:*:(ssh|scp|rsync):*:hosts-ipaddr' ignored-patterns '^(<->.<->.<->.<->|(|::)([[:xdigit:].]##:(#c,2))##(|%*))' '127.0.0.<->' '255.255.255.255' '::1' 'fe80::*'
# Allow for autocomplete to be case insensitive
zstyle ':completion:*' matcher-list '' 'm:{[:lower:][:upper:]}={[:upper:][:lower:]}' \
'+l:|?=** r:|?=**'
# Initialize the autocompletion
autoload -Uz compinit && compinit -i
This snippet by itself is decent enough but where it really comes in handy is when you pair is with the ssh config file.
The Magic Config File
I actually didn’t know about this for a long time, way longer than I should have. Previously the most I’d ever done with my config file was adding options to maximize the life of my ssh connections. But then something spectacular happened, I learned you could use the config file to store your server’s ssh information. But first off, you’re going to need a config file so make sure that you got one by running the following command:
touch ~/.ssh/config
Alright, now before now you’ve probably been typing in a string similar to the following to initiate a server connection:
ssh myuser@myserver.com
or if you have ssh running on a different port:
ssh myuser@myserver.com -p 31313
This works for a while, maybe you have a 2 or 3 servers and it’s super easy to
remember all the information. But what happens when you bump up to 50 or 100
servers? Chances are that you won’t have such an easy time remembering all the
servers’ information, especially if they have different setups. Using the
previous ssh command you can add the following snippet to your ~/.ssh/config
file:
Host servername
Hostname myserver.com
User myuser
Port 31313
And now when you want to connect to that server you can type, (Remembering that I’ve aliased ’s’ to ‘ssh’):
s servername
and you will connect to your server. Now servername
can be any name that you
want it to be it doesn’t have to be anything related to the server. The best
part now is with the ZSH autocompletion in the previous section you can type:
s s<tab>
s servername
Whamo! Minimizing keystrokes. Now you create an entry for each server and have a much easier time connecting to each one without having to remember and of the ssh information.