An introduction to bash completion: part 1

Posted by Steve on Fri 23 Dec 2005 at 09:34

One of the nicest facilities of the modern shell is the built in "completion" support. These facilities allow you to complete commands and their arguments easily. Read on for a brief introduction to adding your own command completions.

Most shells allow command completion, typically bound to the TAB key, which allow you to complete the names of commands stored upon your PATH, file names, or directory names. This is typically used like so:

ls /bo[TAB]

When you press the TAB key the argument /bo is automatically replaced with the value /boot.

Recently some shells have started allowing you to do even more: completing arguments to commands. Two notable shells which allow this are zsh, and bash. Since I'm a bash user I'm only going to cover that.

The Debian bash package supplies a command line completion file /etc/bash_completion which sets up some common support.

If you're not using it right now you can load it by typing into your shell ". /etc/bash_completion" as shown here:

skx@lappy:~$ . /etc/bash_completion
skx@lappy:~$ 

Once this is done you'll be able to TAB-complete many common arguments to programs, for example:

skx@lappy:~$ apt-get upd[TAB]
skx@lappy:~$ apt-get upg[TAB]

But how do you extend the support yourself? Well the completion routines supplied make use of several internal bash commands such as complete. These can be used by your own shell startup files, or more easily by creating a small file and dropping it into the directory /etc/bash_completion.d/.

When the bash_completion file is sourced (or loaded) everything inside the /etc/bash_completion.d directory is also loaded. This makes it a simple matter to add your own hooks.

One of the things which bash allows you to complete is hostnames, this can be very useful for some commands.

I remotely manage some computers using VNC and I usually do that by running the command "xvncviewer hostname".

To allow bash to complete the hostname fragment I type with we'll use the complete command to tell it that xvncviewer requires a hostname:

skx@lappy:~$ complete -F _known_hosts xvncviewer

Once I've done this I can type [TAB] to complete hostnames:

skx@lappy:~$ xvncviewer s[TAB]
savannah.gnu.org            ssh.tardis.ed.ac.uk
scratchy                    steve.org.uk
security.debian.org         security-master.debian.org
sun
skx@lappy:~$ xvncviewer sc[TAB]

This has now completed the hostname scratchy for me.

The function _known_hosts is defined in the file /etc/bash_completion. How did I know I could use it? By using the command "complete -p" to display all of the bindings in use:

skx@lappy:~$ complete -p
....
complete -F _known_hosts tracepath6
complete -F _known_hosts host
...

So what have we learnt so far?

In part two we'll look at defining custom command line handling routines - similar to those already in place. So we can add command line completion to our own programs, or commands not yet covered.

Until then you might want to experiment a little yourself.


This article can be found online at the Debian Administration website at the following bookmarkable URL (along with associated comments):

This article is copyright 2005 Steve - please ask for permission to republish or translate.