As you work under Linux, you will often find that you are repeatedly executing the same small sequence of commands. For example, during program development and debugging you will often iterate around the standard loop: edit the source code, compile the source into an executable file, run the executable file to test its performance and then round again to the start. In order to save you repeatedly having to retype the same commands, bash stores your commands as you type them so that you can easily return to them again if you wish. The store that bash uses for this purpose is called the history list and, by default, this list can store the last 500 command lines you have entered.
A history list this size can quite literally represent all the commands entered during many days of work. In order for it to make sense to use a history list of this size, bash automatically arranges to save the current list to a file when you logout. The default file name bash uses is .bash/history, which it stores in your home directory. Notice that the dot at the start of the file name means that the file will not be listed by ls unless the -a command line switch is used. When you login at the start of the next session, the shell will automatically load the contents of the history file into its history list, effectively allowing you to continue on from where you left off at the end of the previous session.
In order to see the stored list of previously entered lines, you use the history command. Remember that the list is up to 500 lines long so you may want to pipe the output of the history command into more or tail:
$ history | tail -5 511 cat >text.file 512 cd 513 ls -al 514 cd book 515 history | tail -5
The lines in the history list are each called events and the numbers along side each line are called event numbers. Once you know the event number for the line you want to repeat, it is a simple matter to execute it. Suppose you wanted to repeat the history command (event number 515) in the previous example, you just use the history substitution operator (!) followed by the event number:
$ 515 history | tail -5 512 cd 513 ls -al 514 cd book 515 history | tail -5 516 history | tail -5
If the event you wish to repeat happens to be the last command, as in the previous example, you could just use the special notation !!, as in:
$ !! history tail -5 513 ls -al 514 cd book 515 history tail -5 516 history tail -5 517 history tail -5
As well as referring to events by number, it is also possible to have the shell search textually through its history list to find a particular command for you. In this case you use the history substitution operator followed by a string of characters. The shell will search backwards through the history list and execute the first event it can find whose command line begins with the specified string:
$ !ls ls -al -rw-r--r-- 1 pc book 3392 May 29 07:55 .bash_history -rw------- 1 pc book 25 Mar 26 1994 .profiie drwxr-xr-x 3 pc book 1024 May 28 23:30 book
Looking at the previous example, it is event 513 which gets executed in this case. If the search string you specify is enclosed in a pair of ‘?' characters, then the shell will search for the string anywhere along each command line, not just at the start. If there is nothing following the trailing ‘?' then it may be omitted:
$ !?456 ls /dev/tty? [23456] /dev/ttyS2 /dev/ttyp2 /dev/ttyq2 /dev/ttyr2 /dev/ttys2 /dev/ttyS3 /dev/ttyp3 /dev/ttyq3 /dev/ttyr3 /dev/ttys3 /dev/ttyS4 /dev/ttyp4 /dev/ttyq4 /dev/ttyr4 /dev/ttys4 /dev/ttyS5 /dev/ttyp5 /dev/ttyq5 /dev/ttyr5 /dev/ttys5 /dev/ttyS6 /dev/ttyp6 /dev/ttyq6 /dev/ttyr6 /dev/ttys6
In this way you can still repeat an event, even if its command name has been used more recently for another purpose. Sometimes it will happen that you wish to repeat a previous command, but with some small modification. This can be done by specifying a substitution on the end of the line, of the form :s/old/new/, where the first occurrence of string old on the selected command line will be replaced by the string new, as follows:
$ !?456?:s/234/4/ ls /dev/tty? [456] /dev/ttyS4 /dev/ttyp4 /dev/ttyq4 /dev/ttyr4 /dev/ttys4 /dev/ttyS5 /dev/ttyp5 /dev/ttyq5 /dev/ttyr5 /dev/ttys5 /dev/ttyS6 /dev/ttyp6 /dev/ttyq6 /dev/ttyr6 /dev/ttys6
Notice that by the time you reach this level of complexity, it is almost easier just to retype the required command line.