O'Reilly logo

Unix in a Nutshell, 4th Edition by Arnold Robbins

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Command History

Both shells let you display or modify previous commands. Commands in the history list can be modified using:

  • Line-edit mode

  • The fc and hist commands

Bash also supports a command history mechanism very similar to that of the C shell. Because the interactive line-editing features are considerably superior, and because Bash's command history is almost identical to that of the C shell, we have chosen not to cover those features here. See Chapter 5 and the Bash manpage for more information.

Line-Edit Mode

Line-edit mode emulates many features of the vi and emacs editors. The history list is treated like a file. When the editor is invoked, you type editing keystrokes to move to the command line you want to execute. You can also change the line before executing it. When you're ready to issue the command, press the ENTER key.

In ksh, line-edit mode can be started in several ways. For example, these are equivalent:

    $ VISUAL=vi
    $ EDITOR=vi
    $ set -o viOverrides value of VISUAL or EDITOR

For Bash, you must use either set -o vi or set -o emacs; assignment to the VISUAL or EDITOR variables has no effect.

Note that vi starts in input mode; to type a vi command, press the Escape key first.

Common editing keystrokes






Get previous command.



Get next command.

/ string

CTRL-r string

Get previous command containing string.



Move back one character.



Move forward one character.



Move back one word.



Move forward one word.



Delete previous character.



Delete character under cursor.



Delete word forward.



Delete word backward.



Transpose two characters.

The fc and hist Commands

"fc" stands for either "find command" or "fix command," since it does both jobs. Use fc -l to list history commands and fc -e to edit them. See the fc entry in the later section "Built-in Commands (Bash and Korn Shells)," for more information.

In ksh93, the fc command has been renamed hist, and alias fc=hist is predefined.


    $ history             
                     List the last 16 commands
    $ fc -l 20 30         
                     List commands 20 through 30
    $ fc -l -5            
                     List the last 5 commands
    $ fc -l cat           
                     List all commands since the last command beginning with cat
    $ fc -l 50            
                     List all commands since command 50
    $ fc -ln 5 > doit     
                     Save command 5 to file doit
    $ fc -e vi 5 20       
                     Edit commands 5 through 20 using vi
    $ fc -e emacsEdit previous command using emacs

The following only work in the Korn shell, which predefines the r alias:

    $ r              
                     Reexecute previous command
    $ r cat          
                     Reexecute last cat command
    $ r doc=Doc      
                     Substitute, then reexecute last command
    $ r chap=doc cReexecute last command that begins with c, but change string chap to doc

For both shells, the interactive line-editing is easier to use than fc, since you can move up and down in the saved command history using your favorite editor commands (as long as your favorite editor is either vi or Emacs!). Current versions of both shells also let you use the Up and Down arrow keys to traverse the command history.

Programmable Completion (Bash Only)

Bash and the readline library provide completion facilities, whereby you can type part of a command name, hit the TAB key, and have Bash fill in part or all of the rest of the command or filename. Programmable completion lets you, as a shell programmer, write code to customize the list of possible completions that Bash will present for a particular, partially entered word. This is accomplished through the combination of several facilities.

  • The complete command allows you provide a completion specification, or compspec, for individual commands. You specify, via various options, how to tailor the list of possible completions for the particular command. This is simple, but adequate for many needs. (See the complete entry in the section "Built-in Commands (Bash and Korn Shells)," later in this chapter.)

  • For more flexibility, you may use complete -F funcname command. This tells Bash to call funcname to provide the list of completions for command. You write the funcname function.

  • Within the code for a -F function, the COMP* shell variables provide information about the current command line. COMPREPLY is an array into which the function places the final list of completion results.

  • Also within the code for a -F function, you may use the compgen command to generate a list of results, such as "usernames that begin with a" or "all set variables." The intent is that such results would be used with an array assignment:

    COMPREPLY=( $( compgen options arguments ) )

Compspecs may be associated with either a full pathname for a command, or more commonly, with the an unadorned command name (/usr/bin/man versus plain man). Completions are attempted in the following order, based on the options provided to the complete command.

  1. Bash first identifies the command. If a pathname is used, Bash looks to see if a compspec exists for the full pathname. Otherwise, it sets the command name to the last component of the pathname, and searches for a compspec for the command name.

  2. If a compspec exists, Bash uses it. If not, Bash falls back to the default built-in completions.

  3. Bash performs the action indicated by the compspec to generate a list of possible matches. Of this list, only those that have the word being completed as a prefix are used for the list of possible completions. For the -d and -f options, the variable FIGNORE is used to filter out undesirable matches.

  4. Bash generates filenames as specified by the -G option. GLOBIGNORE is not used to filter the results, but FIGNORE is.

  5. Bash processes the argument string provided to -W. The string is split using the characters in $IFS. The resulting list provides the candidates for completion. This is often used to provide a list of options that a command accepts.

  6. Bash runs functions and commands as specified by the -F and -C options. For both, Bash sets COMP_LINE and COMP_POINT as described previously. For a shell function, COMP_WORDS and COMP_CWORD are also set.

    Also for both, $1 is the name of the command whose arguments are being completed, $2 is the word being completed, and $3 is the word in front of the word being completed. Bash does not filter the results of the command or function.

    1. Functions named with -F are run first. The function should set the COMPREPLY array to the list of possible completions. Bash retrieves the list from there.

    2. Commands provided with -C are run next, in an environment equivalent to command substitution. The command should print the list of possible completions, one per line. An embedded newline should be escaped with a backslash.

  7. Once the list is generated, Bash filters the results according to the -X option. The argument to -X is a pattern specifying files to exclude. By prefixing the pattern with a !, the sense is reversed, and the pattern instead specifies that only matching files should be retained in the list.

    An & in the pattern is replaced with the text of the word being completed. Use \& to produce a literal &.

  8. Finally, Bash prepends or appends any prefixes or suffixes supplied with the -P or -S options.

  9. In the case that no matches were generated, if -o dirnames was used, Bash attempts directory name completion.

  10. On the other hand, if -o plusdirs was provided, Bash adds the result of directory completion to the previously generated list.

  11. Normally, when a compspec is provided, Bash's default completions are not attempted, nor are the readline library's default filename completions.

    1. If the compspec produces no results and -o bashdefault was provided, then Bash attempts its default completions.

    2. If neither the compspec nor the Bash default completions with -o bashdefault produced any results, and -o default was provided, then Bash has the readline library attempt its filename completions.

Ian Macdonald has collected a large set of useful compspecs, often distributed as the file /etc/bash_completion. If your system does not have it, one location for downloading it is http://www.dreamind.de/files/bash-stuff/bash_completion. It is worth retrieving and reviewing.


Restrict files for the C compiler to C, C++ and assembler source files, and relocatable object files:

    complete -f -X '!*.[Ccos]' gcc cc

For the man command, restrict expansions to things that have manpages:

    # Simple example of programmable completion for manual pages.
    # A more elaborate example appears in the bash_completion file.
    # Assumes   man [num] command   command syntax.

    shopt -s extglob                                      Enable extended pattern
    _man () {
        local dir mandir=/usr/share/man                   Local variables

        COMPREPLY=()                                      Clear reply list
        if [[ ${COMP_WORDS[1]} = +([0-9]) ]]              Section number provided
            # section provided: man 3 foo
            dir=$mandir/man${COMP_WORDS[COMP_CWORD-1]}    Look in that directory
            # no section, default to commands
            dir=$mandir/'man[18]'                         Look in command
        COMPREPLY=( $( find $dir -type f |                Generate raw file list
                sed 's;..*/;;' |                          Remove leading directories
                sed 's/\.[0-9].*$//' |                    Remove trailing suffixes
                grep "^${COMP_WORDS[$COMP_CWORD]}" |      Keep those that match
                                                          given prefix
                sort                                      Sort final list
                ) )
    complete -F _man man                                  Associate function withcommand

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required