fc is a shell built-in command that provides a superset of the C shell history mechanism. You can use it to examine the most recent commands you entered, to edit one or more commands with your favorite "real" editor, and to run old commands with changes without having to type the entire command in again. We'll look at each of these uses.
The -l option to fc lists previous commands. It takes arguments that refer to commands in the history file. Arguments can be numbers or alphanumeric strings; numbers refer to the commands in the history file, while strings refer to the most recent command beginning with the string. fc treats arguments in a rather complex way:
A few examples should make these options clearer. Let's say you logged in and entered these commands:
ls -l more myfile vi myfile wc -l myfile pr myfile | lp -h
If you type fc -l (or history ) with no arguments, you will see the above list with command numbers, as in:
1 ls -l 2 more myfile 3 vi myfile 4 wc -l myfile 5 pr myfile | lp -h
The option -n suppresses the line numbers. If you want to see only commands 2 through 4, type fc -l 2 4 . If you want to see only the vi command, type fc -l 3 . To see everything from the vi command up to the present, type fc -l v . Finally, if you want to see commands between more and wc , you can type fc -l m w , fc -l m 4 , fc -l 2 4 , etc.
The other important option to fc is -e for "edit." This is useful as an "escape hatch" from vi- and emacs-modes if you aren't used to either of those editors. You can specify the pathname of your favorite editor and edit commands from your history file; then when you have made the changes, the shell will actually execute the new lines.
Let's say your favorite editor is a little home-brew gem called zed . You could edit your commands by typing:
$ fc -e /usr/local/bin/zed
This seems like a lot of work just to fix a typo in your previous command; fortunately, there is a better way. You can set the environment variable FCEDIT to the pathname of the editor you want fc to use. If you put a line in your .profile or environment file saying:
you will get zed when you invoke fc . FCEDIT defaults to the old line editor ed , so that the overall default is also ed .
fc is usually used to fix a recent command. Therefore it handles arguments a bit differently than it does for the fc -l variation above:
Remember that fc actually runs the command(s) after you edit them. Therefore the last-named choice can be dangerous. The Korn shell will attempt to execute all commands in the range you specify when you exit your editor. If you have typed in any multiline constructs (like those we will cover in Chapter 5, Flow Control ) the results could be even more dangerous. Although these might seem like valid ways of generating "instant shell programs," a far better strategy would be to direct the output of fc -l with the same arguments to a file; then edit that file and execute the commands when you're satisfied with them:
$ fc -l cp > lastcommands $ vi lastcommands $ . lastcommands
In this case, the shell will not try to execute the file when you leave the editor!
There is one final use for fc . If you specify the editor - (i.e., type fc -e - ), the Korn shell will skip the editing part and just run the command(s) specified by the argument(s). Why is this useful? For one thing, just typing fc -e - causes the previous command to repeat, just like the C shell !! command. The Korn shell provides the built-in alias r for this, so that if you type r and hit RETURN , you will repeat the last command.
This form of fc allows yet another type of argument, of the form old= new , meaning "change occurrences of old in the specified previous command to new and then run it." For example, if you wanted to run a complex command like the following on two sets of files:
$ tbl ch2.tbl | nroff -mS -Tepson > ch2.out
you can enter the command and then type fc -e - 2=3 . (You could also use the alias, r 2=3 .) This command would then run:
tbl ch3.tbl | nroff -mS -Tepson > ch3.out