Making use of Bash History

As George Santayana famously said, those who forget history are condemned to repeat it.

While using a graphical user interface, you often find that you have to constantly move your mouse to click though the same menus and icons again and again. One of my favourite things about the command-line, is that you do not have to repeat yourself and retype the same commands over and over.

One way common way in to create a bash script. This is just a simple text file with successive commands separated by line breaks. My /root and /home directory is full of all kinds of scripts. However another way to save time is to make use of the Bash history functions.

Bash History file

You may know already that you can press the up and down arrows to dig out a recent command (you can also use control-p and control-n). These commands are stored in a file called .bash_history which is stored in your home directory. For example:

/home/warrior/.bash_history /root/.bash_history

The file is very simple, new commands are just added to the file. Open your own history file to have a look. For example:

cat ~/.bash_history | less

History Command

The command 'history' prints out the history file and adds a line number to each line.

$ history
1 elinks http://www.commandline.org.uk/
2 mplayer *.ogg
3 mplayer *.mp3
4 mplayer MTLC-Enterprise2-2005-12-01.mp3
5 history
6 mutt
7 cat ~/.bash_history | less
8 history

If the file contains any confidential information such as usernames, or if the file has become to large for your liking, you can use history -c to empty the bash history file.

Output to grep

A simple way to find a past command is to pass the output of history to grep. For example:

$ history | grep Enter
4 mplayer MTLC-Enterprise2-2005-12-01.mp3``

You can call a line by typing the exclamation mark followed by the line number. So for example, I can type !4 to re-enter the command:

$ !4
mplayer MTLC-Enterprise2-2005-12-01.mp3

Reverse-i-search

A great way to re-enter a past command is to use the reverse incremental/interactive search. Just hit control and r and begin typing the command. It will complete the command with the most recent matching command from the history file.

If there is more than one relevant command in the history file and the one you need is not the most recent, then just type a few more letters to distinguish the command. It is actually much simpler to use than I have made it sound! Give it a try now!

Using the exclamation mark.

We have already seen that ! followed by a number, e.g. !4 , gives us the forth command from the history file. Two marks, !! , re-enters the last command. A mark followed by a keyword enters the last command starting with that keyword. For example:

$ !mpla
mplayer MTLC-Enterprise2-2005-12-01.mp3

To match a keyword found anywhere in the line, use the exclaimation mark followed by the question mark then the keyword, for example:

More information

These are the history functions that I use, for more options you can read the history man page, (type man history). If you have a history tip that is not covered here then please leave a comment below and let us all know about it!

4 thoughts on “Making use of Bash History

  1. <p>Useful stuff, thanks Zeth!</p>
    <p>I noticed that you're using <tt class="docutils literal"><span class="pre">cat</span> <span class="pre">~/.history</span> <span class="pre">|</span> <span class="pre">less</span></tt></p>
    <p>To save yourself a bit of typing (this works on my system at least) you can
    just type <tt class="docutils literal"><span class="pre">less</span> <span class="pre">~/.history</span></tt> <img src="/static/forum/img/smilies/smile.png"></p>

  2. <p>One of the things I use a lot is the !$ combination. This is shorthand for
    the last argument of the previous command. Really useful for stuff like</p>
    <div class="highlight"><pre>$ mkdir very_long_directory_name_for_text_files
    $ mv *.txt !$
    $ cd !$
    </pre></div>

  3. <p>Hey Zeth,</p>
    <p>some real interesting stuff on your site mate, even for us criminals down
    here in Australia. One thing I did notice missing from your discussion of the
    bash history though was a neat little trick that I picked up a while back</p>
    <p>stick the following lines in your ~/.bash_profile (or ~/.bashrc which is
    where I put all my scripts now as bash profile doesn't get called when you
    are creating a new screen, but I digress).</p>
    <p># rebind Ctrl+n and Crtl+n to search history based on command line rather
    than just browse through history
    bind &quot;C-p&quot;:history-search-backward
    bind &quot;C-n&quot;:history-search-forward</p>
    <p>What this allows you to do is to type the first few letters of a previous
    command, say</p>
    <p>mpl</p>
    <p>then press Ctrl-P or Ctrl-N to cycle through the commands which match
    that....</p>
    <p>mpl ^P =&gt; mplayer MTLC-Enterprise2-2005-12-01.mp3</p>
    <p>I find it invaluable</p>

  4. <p>A very good tip, I did not know bash could do this, and this is one of the
    primary reasons I use zsh (which does this automatically and with the cursor
    keys).
    When I am or go back to using bash, this will be the first thing I add!
    Thanks.</p>

How about Global Thermonuclear War? Wouldn't you prefer a good game of chess? Powered by zpress