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 spaceignoredups
— ignore duplicate commands andignoreboth
— 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) andHISTFILESIZE
— 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.