Managing shell command history in OS X/Linux

One of the many benefits of using the command line shell in OS X or Linux (or any *nix or similar OS) is that the operating system keeps a history of all the commands you use, storing them in a dot file. These dot files are also known as hidden files, because they are usually hidden when you look at a listing of the directory (or folder, in the GUI).

For example, the file ~/.bash_history will be in your home directory if you use the Bourne shell on OS X–or ~/.bashrc in Linux. (NOTE: the characters ~/ in front of a directory/filename is *nix shorthand for “the current user’s home directory”.)

This file contains a rolling record of all commands entered at the command line–the number of commands saved depends on the system configuration, but in OS X, the default history size is 500 commands. “Rolling” means that when the history file reaches its maximum number of commands, it drops older commands and adds new ones as you enter them. Other OSes and distributions may have different default values for this; a recent Ubuntu install uses a default of 2000 commands.

There are two pertinent system variables to consider here, $HISTSIZE and $HISTFILESIZE.

$HISTSIZE specifies how many lines of commands are stored in the current terminal session. This command history does not get written into the history file (e.g., ~/.bash_history) until the terminal session is terminated gracefully (that is, not as a result of a crash or forcing a quit while some process is still running).

The default is 500, meaning 500 lines of commands that are stored in RAM during the terminal session, and that will be written to the $HISTFILESIZE when the terminal session is complete.

$HISTFILESIZE specifies how many lines the .bash_history file (for example) may contain. To understand how it works, consider if the $HISTFILESIZE is 1000, and $HISTSIZE is 500. When first using the shell, there will be no commands in the .bash_history file; let’s say the first session I do 400 lines of commands. My history file is still empty, but on exiting the terminal session, those 400 lines of commands will be written to disk (in .bash_history). On my second session, let’s say I do another 700 lines of commands; on exiting, those 700 lines will be written to the .bash_history file, and the first 100 lines of the file will be discarded–the history file will never be more than 1000 lines (unless $HISTFILESIZE is changed).

Thus, when using the command line to enter a GPG passphrase, there are a few different ways to prevent the passphrase from being stored in the history file:

  • Clear the terminal history before exiting/immediately after entering a sensitive command. This removes all commands entered during the current session. To clear the history, execute the command:
    $ history -c
    Opening a separate tab to enter sensitive commands only, and then clearing it before closing, is probably a reasonably safe approach.
  • Remove the history file, and prevent any history being written by adding the following line to the shell configuration file (e.g., ~/.bashrc in *nix or ~/.bash_profile in OS X):
    export HISTFILESIZE=0
    Doing this prevents the shell program from writing commands into the history file. For good measure, it makes sense to explicitly remove that file, as well:
    $ rm ~/.bash_history
    The shell will still remember command history during a terminal session, but those commands will be stored only in RAM, and not saved to a file.
  • Disable the session history by setting the $HISTSIZE variable to zero, adding or editing the line:
    export HISTFILE=0
    to the shell configuration file.
This entry was posted in Command Line, computer science, Editors, How-To, Linux Tech Talk, Open source software, Programmer's Tools, Secure computing, Security/Cryptography, Ubuntu Linux, Utilities. Bookmark the permalink.

One Response to Managing shell command history in OS X/Linux

  1. Pingback: Encrypting text at the command line with GnuPG | Loshin.com

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>