Configuring BASH History

If you use BASH, then you’re probably already using the command history. BASH history allows you to access a list of previous commands executed in the shell. It can make you more productive and efficient: do more and do it quicker.

The default configuration of BASH history will suit most purposes. But, like most things in the Linux universe, it’s possible to tweak that configuration to suit your specific requirements. In this post I’ll present some of those configuration options.

Surveying History

You can take a look at your command history using the history command. It will dump the entire history to standard output, ordered from least to most recent.

history
    1  ls                                     # ⏰ Least recent
    2  cat /etc/passwd
    3  whoami
    4  history                                # ⏰ Most recent

You can navigate through the commands in your history with the up or down arrow keys. You can also search using Ctrl+R.

History Format

It can be useful to show when a command was executed. Define the HISTTIMEFORMAT environment variable to set this up. It makes use of the standard date and time placeholders (for more information see man date). Here %F gives the date and %T the time.

# 📢 Set the HISTTIMEFORMAT environment variable.
#
export HISTTIMEFORMAT='%F %T - '

Now each command is preceded by the date and time at which it was executed.

history
    1  2023-04-04 06:20:20 - ls
    2  2023-04-04 06:20:25 - cat /etc/passwd
    3  2023-04-04 06:20:29 - whoami
    4  2023-04-04 06:20:32 - history

Forgetting History

You can clear the history by invoking history with the -c option.

# Clear BASH history.
history -c

What goes into the History?

You might want to be selective about which commands are stored in the history. By default every command is added. This means that it can become cluttered with duplicate or trivial commands. Even the history command itself will get added to the history.

This is not great:

    1  ls                                     # 🥱 Not very useful.
    2  cat /etc/passwd
    3  whoami
    4  history                                # 🥱 Redundant?
    5  ls                                     # 🥱 Duplicate!
    6   mysql -p=kjRpp9u@^p9E@g -u=admin      # 😱 Insecure!

The HISTCONTROL environment variable applies high level control over what gets stored in the history. There are three options for HISTCONTROL:

  • ignorespace — ignore commands that start with a space
  • ignoredups — ignore duplicate commands and
  • ignoreboth — both of the above.

You very likely do not want to retain duplicates in your command history, so ignoredups makes sense. The ignorespace option enables a nifty trick for excluding a command from the history by simply preceding it with a space. This is useful, for example, if you are running a command which includes sensitive information. This is not a feature which I use frequently, but there seems no harm in enabling it.

# 📢 Set the HISTCONTROL environment variable.
#
export HISTCONTROL=ignoreboth

The HISTIGNORE environment variable gives you more granular control over what to ignore. Set it to a list of command patterns which should not be stored in the history.

# 📢 Set the HISTIGNORE environment variable.
#
export HISTIGNORE="clear:history:[bf]g:exit:date:* --help"

With these settings in place the history above would be reduced to:

    1  ls
    2  cat /etc/passwd
    3  whoami

Where did the extra commands go? The risky mysql command and second instance of ls were removed by HISTCONTROL. The history command was eliminated by HISTIGNORE.

Save History to File

For the duration of a BASH session the command history is held in memory. At the end of the session it’s saved to the ~/.bash_history file in a user’s home directory, which looks like this:

#1680589220
ls
#1680589225
cat /etc/passwd
#1680589229
whoami

Each command is preceded by an integer timestamp. A timestamp is always recorded, regardless of whether or not you are displaying it in the history output.

💡 Although ~/.bash_history is the default location for storing BASH history, you can choose an alternative location via the HISTFILE environment variable.

When to Save History?

By default ~/.bash_history will only be updated when you close the BASH session. However, if you have multiple BASH sessions running and you want to share the history between those sessions then it makes sense to update ~/.bash_history immediately. Use the PROMPT_COMMAND environment variable to set this up. 💡 The utility of the PROMPT_COMMAND environment variable extends well beyond this use case. Its contents are executed as a BASH command immediately before BASH displays the prompt. Multiple commands (separated by a ;) can be executed via PROMPT_COMMAND.

# 📢 Append (rather than overwrite) history.
#
shopt -s histappend

# 📢 Append commands to history file immediately (not at end of session).
#
export PROMPT_COMMAND='history -a'

The -a option causes commands executed since beginning of BASH session to be immediately added to ~/.bash_history.

How Much History?

If you spend a lot of time in BASH then your command history can become very long indeed. There are two environment variables which can be used to cap the number of items retained in the history:

  • HISTSIZE — the number of history commands that will be stored in memory (default: 500) and
  • HISTFILESIZE — the number of history commands that will be stored on disk (default: 500).

When either of these limits are reach the least recently executed commands are discarded first.

# 📢 Set how many history commands will be stored in memory.
#
export HISTSIZE=2000

# 📢 Set how many history commands will be stored on disk.
#
export HISTFILESIZE=5000

Persisting History Configuration

Once you’ve got your history working just right you should store the configuration in your ~/.bashrc file.