home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


Unix Power ToolsUnix Power ToolsSearch this book

28.6. Automatic Completion

If you hate typing long filenames, hostnames, command names -- or almost anything on a command line -- you should know about the shells' "completion" feature.

The basics are pretty simple: just press (in most shells) the TAB key, and the shell should "do the right thing." But how the shell decides what's "right" can be complicated -- especially in newer shells, and especially in the latest zsh, which has incredibly customizable completion. As an example, when you press TAB in bash, the shell tries to complete a shell variable if the word begins with $, a username if the word begins with ~, a hostname if the word begins with @, or a command (including aliases and functions). If none of these works, bash finally tries filename completion. As another example, the original Korn shell does only simple filename completion, but the public domain Korn shell has more features.

On more-sophisticated shells, completion is actually a function of the shell's built-in customizable command editor. For instance, in tcsh, the TAB key is bound to (in other words, it runs) the editor's complete-word command. This key binding can be changed. And tcsh, like other recent shells, has plenty of other completion-related editor commands.

bash allows for the customization of the different types of completions, as well; you can define a file containing the hostnames to check (in /etc/hosts format) when the shell is asked to complete a hostname. Just set the environment variable HOSTFILE to the name of the file you want. There are extensive built-in functions in bash, each associated with a key, to allow for extremely flexible management of completions.

As you can see, completion varies shell to shell, so we'll give an overview here. For more details, see your shell's manpage.

28.6.1. General Example: Filename Completion

Let's look at an example of one type of completion, filename completion. Other types of completion work in generally the same way.

Filename completion is one of the most common types. You can type the initial part of a filename and then press the TAB key. (In the C shell, first enable completion by setting the variable filec (Section 30.9) or complete, then press ESC.) If the shell can figure out the complete filename from the part that you've typed, it will fill in the rest of the name. If not, it will fill in as much of the name as is unambiguous and then let you type some more. For example:

$ ls
alpha.c    alpha.o   beta.c
$ cc b TAB
$ cc beta.c        Shell fills in the filename automatically

(With tcsh and csh, your terminal will beep if more than one file matches the name you've typed. If all this beeping drives you crazy, you can set the nobeep shell variable to turn it off.) In this case, only one filename begins with b, so the shell can fill in the entire name. This works with pathnames (Section 1.16) too: each time you press TAB, the shell completes the name up to the next slash (/) if it can.

If you type part of a filename and then type CTRL-d (in bash, type TAB twice), the shell lists all the files that match whatever you've typed. It then redisplays your command line and lets you continue typing. For example:

% cc a CTRL-d
alpha.c    alpha.o
% cc alpha.

Two files begin with the letter "a"; the shell lists them. It then redisplays the cc command, letting you finish the filename.

NOTE: Also, be forewarned that filename completion doesn't always work correctly. For example, you can't use filename completion within some older shell applications. You can't mix filename completion with wildcards in any shell except zsh. We won't go into detail about these rough edges, but if you're aware that they exist, you won't have trouble.

That last example shows a problem with filename completion: it's matching the ".o file," (Section 1.12) named alpha.o. It's a type of file that most users wouldn't want to manipulate from the command line; they'd rather the shell ignore all .o files. Section 28.7 explains the fignore list; it solves this problem in most cases. Section 31.10 shows an interesting shortcut to filename completion: cding to a directory by typing its "initials."

28.6.3. Command-Specific Completion

tcsh and zsh let you customize completion even farther: specific completion instructions for each Unix command you define. For instance, the mail command wants email addresses on its command line, and you can declare a list of addresses that are available to complete (this could be a list of friends and associates you send a lot of mail to). You might use the ssh and telnet commands (Section 1.21) to connect to particular remote hosts, and you'd like to be able to complete the hostnames for those particular hosts. (The bash hostname completion feature reads hostnames from a file like /etc/hosts -- but it only completes hostnames if the string starts with an @ character or if you use a special editor command for completing hostnames.)

The tcsh command complete defines these custom completions. The syntax is hairy, so I won't try to explain all of it here. Instead, let's look at an overall example from the MH email system (Section 6.2). You use MH commands directly from a shell prompt instead of first starting an email command interpreter and entering commands at the interpreter's own prompt, as you do with most other email packages. Most MH programs accept a mail folder name as one of their command-line arguments. A mail folder name starts with a + (plus sign)[85] and can appear anywhere in a command line.

[85]An MH folder name can also start with an @ (at sign), but that use is less common. Besides, this is just an example!

MH mail folders can be stored anywhere on the filesystem -- even on a networked filesystem on a remote computer. Here are the four lines that I put in my .tcshrc setup file (Section 3.3):

{ } Section 28.4

# Set up MH folder name completion for "folder", "refile", "scan", "show":
folders -fast -recurse | \
     sed -e '/DELETE$/d' -e 's/^/+/' > $HOME/Mail/folderlist
complete {folder,refile,scan,show} 'C@*@`cat $HOME/Mail/folderlist`@'

The first command builds a file named folderlist with a list of strings (in this case, folder names) to complete. I don't want completion to include folder names I'll never look in, so I filtered the folder output with sed (Section 34.1) to exclude the names I don't want -- in this case, folder names ending with DELETE. (This list is also useful in other places, it turns out, not just in tcsh completion.) A + is prepended to each folder name because folders doesn't add the plus signs, but we need them for tcsh matching. So the first few lines of folderlist look like this:

+drafts
+inbox
+jobs
+jobs/bay-area
+jobs/miscellaneous
   ...

The second command, complete, starts with a list in braces of the commands that should complete folder names. The next argument is complex and has lots of possible variations; this one matches any pattern included with backquotes (Section 28.14) from the cat (Section 12.2) command, which gives us the contents of folderlist. There are lots of variations! The bottom line is how this works... here's an example of completing a folder name:

tcsh> scan +j TAB
tcsh> scan +jobs/m TAB
tcsh> scan +jobs/miscellaneous last:20

After completing the folder name (in two steps), tcsh leaves a space; I type the rest of the command line and press ENTER to run it.



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.