Tip

Mastering the Linux history command

"Linux users who forget history are doomed to type too much."

And that is why the powerful history command (including the Bash shell's history variant) is incredibly useful for not only repeatedly

    Requires Free Membership to View

invoking previously executed commands without having to retype them, but also for recalling otherwise seldom used commands, saving you the hassle of having to research their usage anew. The command produces a chronological list of previously executed commands.

An example of the output of this command follows:

$ history
...
62  rm 092210.sql
63  mysqldump
64  mysqldump -u root -p dev_gamenomad_com > 092210.sql
65  more 092210.sql
66  rm 092210.sql
...
9991  mkdir chapter05
9992  cd chapter05
9993  dir
9994  npm install websocket-server
9995  node hello.js
9996  exit
9997  history

The sequence number associated with each command serves an important purpose, allowing the user to execute the associated command anew by supplying the sequence number directly following an exclamation mark, like this:

$ !10000
sudo /etc/init.d/apache2 start
 * Starting web server apache2      

But that’s not all. The Linux history command is capable of  much more, as will be covered in this tip.

Mastering history expansion
Pressing the up arrow will display the previously executed command, and pressing the Enter key will execute it anew. But a second, possibly faster option involving a feature known as history expansion is also available:

$ !!

If you were repeatedly executing varying sequences of the same two or three commands, you also have the option of executing a command that appeared somewhere previous to the last command by identifying its negative index offset. For example to execute the command that was executed prior to the previous (two commands back), use the following sequence:

$ !-2

Another way to execute an earlier command is to type the beginning of the command sequence following the exclamation point. The first command matching that string will be executed. For example, suppose the last three commands looked like this:

$ history
...
9876 build-book /home/wjgilmore/easy_php
9877 mkdir chapter05
9878 cd chapter05
9879 touch chapter05.md

You can execute the build-book script again simply by running the following command:

$ !b

Creating a new directory and navigating to enter it in a two step process can be shortened using history expansion. In this example, I created a new directory named easy_bash, located in /home/wjgilmore/books. To enter that directory use the !$ to obtain the last "word" found in the previous command:

$ mkdir /home/wjgilmore/books/easy_bash
$ cd !$

Searching the command history
While it's certainly possible to page through the command history (or use the grep command), it is possible to recall a fragment of the command after opening up the option to search for it using Ctrl+R. After pressing Ctrl+R, the command line prompt will look like this:

(reverse-i-search)`':

Start typing the command fragment, and the command line will update in real-time to reflect the closest match. This is what the command line looks like after typing apa:

(reverse-i-search)`apa': sudo /etc/init.d/apache2 start

When you see the desired command, press Enter to execute it, or press the right arrow to modify the command before executing it anew.

Tweaking historical behavior
There are a number of interesting configuration changes you can make in order to control how the command history behaves. For instance the Bash shell sets the default history size to 500 entries, a limit that will quickly be reached even with minimal command-line interaction. You can increase this limit by setting the HISTSIZE variable found in your Bash configuration file (.bashrc, located in your home directory):

HISTSIZE=10000

You'll also commonly encounter another history-related variable in .bashrc named HISTCONTROL. This variable helps to determine exactly what is saved to the history file (located in.bash_history, also found in your home directory). For instance, you might repeatedly execute the tail command when examining the latest additions to a log file, over the course of a few minutes running tail a few dozen times. It would be impractical to clutter the history file with this repetition; set the HISTCONTROL variable to ignore duplicate lines by setting it to ignoredups:

HISTCONTROL=ignoredups

Another HISTCONTROL setting of dubious utility is ignorespace. Setting HISTCONTROL to this will result in any commands executed with a prefixed space being omitted from the history file. It seems counterproductive to not track every single command, but if you'd like to enable this feature in addition to the ignoredups setting you can set both to:

HISTCONTROL=ignoreboth

Command substitutions
One last feature I'd like to touch upon is command substitution. Suppose you wanted to rapidly configure a bunch of virtual hosts based on a virtual host configuration file template. These command sequences can be rather long, looking something like this:

$ cp vhost.template /etc/apache2/sites-available/dev.example.com
$ cp vhost.template /etc/apache2/sites-available/forum.example.com
$ cp vhost.template /etc/apache2/sites-available/staging.example.com

Usually you would execute this sequence of commands by typing and executing the first, then arrowing up, deleting the trailing string fragment (dev.example.com), and then typing the next fragment (forum.example.com), and executing anew. Alternatively, you can use command substitution to rapidly substitute one relevant string with another, like this:

$ !!:s/dev/forum

The command line already offers users considerable advantages over a point-and-click interface, allowing for task execution and operating system navigation to be carried out with speed and grace. Exploiting the history command to its fullest extent only adds to these capabilities, boosting productivity even further.

ABOUT THE AUTHOR: Jason Gilmore is founder of the publishing, training, and consulting firm WJGilmore.com. He is the author of several popular books, including "Easy PHP Websites with the Zend Framework", "Easy PayPal with PHP", and "Beginning PHP and MySQL, Fourth Edition". Follow him on Twitter at @wjgilmore.

This was first published in June 2011

There are Comments. Add yours.

 
TIP: Want to include a code block in your comment? Use <pre> or <code> tags around the desired text. Ex: <code>insert code</code>

REGISTER or login:

Forgot Password?
By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy
Sort by: OldestNewest

Forgot Password?

No problem! Submit your e-mail address below. We'll send you an email containing your password.

Your password has been sent to:

Disclaimer: Our Tips Exchange is a forum for you to share technical advice and expertise with your peers and to learn from other enterprise IT professionals. TechTarget provides the infrastructure to facilitate this sharing of information. However, we cannot guarantee the accuracy or validity of the material submitted. You agree that your use of the Ask The Expert services and your reliance on any questions, answers, information or other materials received through this Web site is at your own risk.