[Chapter 11] 11.14 More Ways to Do Interactive History Editing
Author: Jerry Peek, Tim O'Reilly & Mike Loukides
Date: 1998-08-04T21:36:17Z

#

| Chapter 11 The Lessons of History |

## 11.14 More Ways to Do Interactive History Editing

tcsh (8.3) is a version of csh that provides history editing (among other things). If you don't want to switch to tcsh, you can simulate history editing using redo. If you're using bash or ksh, you probably already know about your shell's editing - but you may not know about its fc command.

### 11.14.1 In the C Shell: redo

redo is a C shell script that is run by being sourced (44.23) into the current shell using an alias. The original version was posted to Usenet in the 1980s, author unknown. The version shown here was reposted in 1987 by Dave Patterson. The alias puts you in an ex open-mode (30.36) editing buffer, a comfortable environment for vi users. You can browse through the previous 22 commands and press RETURN when you want to execute the current line. Before executing, you can edit the commands as you would in vi. You can even search for strings using `/`; just remember to press ESC instead of RETURN after the search string.

To use redo, first install it read-only with no execute permission (22.2), and then create an alias with the script's absolute pathname (14.2) to execute it:

>     alias r source ~/.lib/redo

When you run the alias, it reads a set of commands from the sourceable script file (10.5).

Here's the redo script:

    echo...33'
    map

    tail

    !...
    history -h 22 >! /tmp/redo.$$

    # Put CR in $c[1] and ESC in $c[2]:
    set c=(`echo "m e" | tr me '\015\033'`)
    # Make CR map to :wq! and start ex quietly at 2nd to last line in open mode.
    (setenv EXINIT "map $c[1] :.wq\!$c[2]|map! $c[1] ${c[2]}:.wq\!$c[2]";\
       ex '+$-1 open' /tmp/redo.$$)
    tail -1 /tmp/redo.$$ >! /tmp/cmd.$$

    # Insert into history without executing.
    source -h /tmp/cmd.$$

    # Clear out temporaries.
    /bin/rm -f /tmp/{cmd,redo}.$$
    unset c

    # If thing chosen to redo is the redo alias itself then DON'T redo it.
    if (!-2:0 != !!:0) !!

Type `r` to invoke the alias. Then use cursor motion keys (`jk`) to get to the line you want to edit. Edit the line (remember that you're in the open mode (30.36) of ex). When you're done, press RETURN. (Don't type `ZZ` or `q`.)

### 11.14.2 In ksh and bash: fc

ksh and bash have a built-in command called fc (for "fix command"). It's like redo, but more powerful. We'll cover the basics here; check your shell's manpage or its Nutshell Handbook for details.

To see a list of your previous commands, use the option `-l` (lowercase L, for "list"):

>     $ fc -l
>        ...
>     19      ls -F
>     20      less expn.c
>     21      vi $_
>     22      make
>     23      expn info@ora.com
>     24      fc -l

To get a shorter list, give fc the first number or name you want to list. For instance, `fc -l vi` or `fc -l 21` would give the last four lines above.

fc can call a UNIX editor (vi, emacs, pico, etc.) to edit one or more of the previous commands. You can name an editor with the -e option each time you use fc, but it's probably easier to store the editor in the FCEDIT shell variable (in your .profile or .bashrc files (2.2)).

To edit the commands above, between `vi` and `expn`, you would type `fc v e` or `fc 21 23`. Your editor will start with the three command lines in it. You can make any changes you want: add commands, rearrange them, and so on. When you exit the editor, the commands you saved with your editor will be executed. If you change your mind and don't want to execute anything, just delete all lines in your editor before you save - or replace them with a dummy command like `echo hi`.

- LM, JP

11.13 Shell Command-Line Editing |  | 11.15 Changing C Shell History Characters with histchars