X

Using and managing the Terminal history in OS X

The Bash Terminal shell in OS X (or other Unix-like systems, for that matter) contains a history feature that can be quite useful.

Topher Kessler MacFixIt Editor
Topher, an avid Mac user for the past 15 years, has been a contributing author to MacFixIt since the spring of 2008. One of his passions is troubleshooting Mac problems and making the best use of Macs and Apple hardware at home and in the workplace.
Topher Kessler
6 min read

There are times when using the Terminal that you might enter a command or two and then want to either run it again or review a whole sequence of commands that have been entered. This can easily be done by pressing the up arrow, scrolling through the previous commands, and then pressing Enter to execute the selected one again. In addition to this approach, the Terminal supports a number of other options for revealing and rerunning entered commands.

The Terminal is able to do this because it stores a small history of the commands you have run both in its current history buffer (memory not written to disk) as well as storing the history buffers from prior Terminal sessions in a small hidden file called ".bash_history." While using the up and down arrows will allow you to navigate these, you can also list them all or part of them both for your account and for other accounts, and also rerun commands quickly, in addition to using the history to transfer commands to other Terminal sessions.

Listing the history

Terminal history in OS X
The Terminal history will reveal all commands entered in the current session and those from any prior (but now closed) sessions. Screenshot by Topher Kessler/CNET

There are several options for listing the Terminal history. The first is to directly access the history file for your user account, which is a hidden file called ".bash_history" at the root of your home directory. These files can be opened with the following two commands (among others) in a fresh Terminal window:

open .bash_history
cat .bash_history

With these commands you should see a listing of the commands previously run for your account, but can also use these commands to target the history files of other users on the system, such as the following:

open /Users/user1/.bash_history
open /Users/user2/.bash_history

The one caveat to accessing the history file directly is it will only contain the commands from closed Terminal sessions. If someone has a Terminal session open and has run three or four commands, then these will not be written to the history file until the session is closed.

While accessing the history files can be done as stated, the more complete way to do so (at least for your account's history) is to use the "history" command in the Terminal. Unlike opening the history file, the history command will include the contents of both the file and the active history buffer.

The output of the history command can be long at times and show hundreds of prior commands, so if you would only like to show the most recent ones, you can supply a number after the word "history" to show only that number of previous commands (e.g., "history 10" to show the last 10 commands entered).

Rerunning commands

Rerunning Terminal commands from the history
You can rerun prior commands by referencing them from the history. In this example command number 3 (ls) was rerun. Screenshot by Topher Kessler/CNET

In reviewing the output of the "history" command, there are various approaches you can use to rerun the previously entered commands. The more common approach besides using the arrow keys is to use the Terminal's repeat character, which is a simply exclamation point. This character will reference the Terminal's history, and give you options to rerun various commands.

This approach has more use than the up arrow key because it allows you to rerun commands with extra conditions. For example, if you've tried to open a deeply buried system file only to realize you forgot to include "sudo" to edit it with administrative privileges, then you can rerun the edit command in the following way:

sudo !!

As in the example above, the primary use of this feature is to simply enter two exclamation points to reference the last command, but when used with the output of the "history" command you can be more specific on the commands you target. For example, in the history output you will see a number next to each command that identifies it, and you can run a desired command again by its number:

!523

Therefore, if you have supplied multiple commands but wish to access a prior one to run as admin and redirect its output to a text file for troubleshooting purposes, then you can output a brief history with "history 10" and then run the command "sudo !NUMBER > redirect.txt" on the specified history line to repeat that command.

You can also rerun a prior command by its relative position using negative numbers. For example, to run the last command you can enter "!!" or you can use a minus one and enter "!-1." This approach can be used to rerun the second or third previous commands, by using a -2 or -3, and so on.

In addition to referencing the history by number, you can do so by name. For example, if you have run a command that begins with "pico" to invoke this editor on a document but since then have changed directory or listed directory contents a few times, you can immediately repeat the command that began with "pico" by the following command:

!pico

This can be used to locate the last command that begins with the provided text, but a final approach here is to repeat the last command that includes the mentioned text, which may be convenient to pick out one of many commands that were run with "sudo." For instance, if you have edited a script and then run it with admin privileges, your history will be as follows:

sudo pico path/to/script.sh
sudo path/to/script.sh

In this scenario, you can repeat the "pico" command by issuing the following in the Terminal:

!?pico?

(The question marks here are like wild cards, so you can remove the one at the end to have the first command run that ended in the included string, which might be a convenient way to re-edit a specific script file if you have just run commands to edit a number of different scripts).

NOTE: A similar approach to the exclamation point can be done by entering the command "fc -s" alone or followed by the name of the prior command to run. This can be aliased or scripted as a separate command, but is a bit redundant to the use of the exclamation point.

Transferring commands

The Terminal history will not be written to the history file until you close the current Terminal session, so this approach can be useful for transfering commands from one Terminal session to another. For instance, if you have two Terminals open and enter a complex command in one, to get it to the second Terminal window, simply close the first (this will write its history buffer to the history file), and then in the second window type "history -r" to re-read the saved history file.

With these actions done, then scroll up using the arrow keys in the second Terminal window (you can also use the history function to location the position of the command from the closed Terminal session). After you scroll through the second window's history buffer it will start revealing the commands in the history file, with the first one being the complex command from the initial Terminal window.

Managing the history

Clearing the Terminal history
Clearing the Terminal history involves running these two commands, though in doing so they will be appended to the newly cleared history. Screenshot by Topher Kessler/CNET

Using the history in the manners mentioned can be useful, but in addition you may wish to remove an entry or two from the history, or clear it completely if needed. To do this, you can either close the Terminal windows and then remove the history file, or in what is a simpler approach, run "history -c" in the Terminal to clear the history, followed by entering "history -w" to write the now empty history file.

These steps will clear the entire history, which may not always be desired, especially if you only wish to remove a single command that perhaps shows the location of a private file or is one you would perhaps not wish to inadvertently run again. To do this, you can remove the history line by number. First use the history command by itself to list the entire history (or at least enough lines of it to reveal the unwanted command), and then note the identifier number for the command and run the following to remove it from the history:

history -d NUMBER



Questions? Comments? Have a fix? Post them below or e-mail us!
Be sure to check us out on Twitter and the CNET Mac forums.