A couple of posts back, I showed off some functions to pop up notifications when a host became pingable again or when a port became reachable. Today’s (semi) quick tip is how to use BASH’s autocomplete functionality add hostname autocompletion to those notifications functions.
BASH autocompletion is a system that provides tab completion of command arguments. You’re familiar with it’s default behavior which is to complete filenames and paths.
1 2 3 4
You can override this behavior by providing BASH with a list of possible completions. The list can be a literal list of words, or it can be a function that looks at the current environment ($PWD, user, time on day, etc) and generates context aware list.
So, what we want is a way to generate a list of hosts we know
about. And, it just so happens we have such a list lying around. You
know how the first time you SSH to a new server, your prompted to
confirm it’s identity? Well, that confirmation, along with the host’s
name is stored in
~/.ssh/known_hosts. From that file we can extract
a list which should cover most of the servers we care about.
The simple approach is to build a list when you login. If you Google around you’ll find lots of example scripts for pulling hostnames out of known_hosts, but the most common looks like:
The command that setups autocompletion is
complete. When giving it a list, pass them in as an augument to the
I’m capturing the output of the command with
$() and wrapping it in double quotes. The last argument is the name of the command (which can be also be a function or alias) that will use this autocompletion. Now we get this:
1 2 3
That works fine, but it’s static and applies only to one command. Instead you can create a reusable function.
1 2 3 4 5 6 7 8 9
BASH auto completion functions are powerful things, but for today
we’re keeping it simple. First we build a list of options as
before and store it in
$known_hosts. Second we get the current word, the
command argument, which is be tab completed. Finally, we pass that
list and that word into
compgen which is BASH’s internal
compgen has some powerful features, but in this case it’s
just going to return a list of hosts in
$known_hosts that start with
the word we hit tab on.
Then we tell the completion that we are using a function by giving it
-f option, along with the function name, instead of
And you can use the
_known_hosts function for other commands as
This is a good exercise in understanding autocompletion, but it’s pretty basic. Fortunately, people have already done all of the hard work in the bash-completion project. This ships by default with many Linux distros. On the Mac:
1 2 3
This will add context sensitive completion to everything from SSH to
rsync, and give you a much smarter
_known_hosts function you can use
with your own commands.
If you want to learn more, I suggest reading the bash-completion code. It does far more powerful things than I cover here and is a great jumping off point for your own completion functions.