Bash history nirvana

09 October 2015 by Lincoln Ramsay

I thought I’d written about this ages ago. But it turns out I didn’t.

The default bash history handling is terrible. Run one shell at a time and always cleanly exit the shell and it’s ok, but run more than one shell at a time and abnormally exit shells and disaster will strike. The number of saved entries is relatively tiny. Duplicates are saved and you can’t really share history between running shells.

Here’s how you fix it.

First, we want to append to the history file rather than clobbering it.

shopt -s histappend

I once had a bash start and fail to read .bashrc properly. It clobbered my history. So now I use a non-standard file to keep broken bash shells from clobbering the history.

HISTFILE=$HOME/.bash_history.nirvana

Store lots and lots of history.

HISTFILESIZE=1000000000
HISTSIZE=1000000

I don’t want duplicates in the history. Also, I ignore commands that start with a space (eg. for those times when you have to give something sensitive like a password to a command).

#HISTCONTROL=ignorespace # start a command with a space and it doesn't go into history
#HISTCONTROL=ignoredups # ignore duplicates
HISTCONTROL=ignoreboth # both of the above

You can run history -a to dump the history immediately and history -n to import history into a running shell. I like to automate the dumping so that an abnormally terminating shell doesn’t take it’s history with it. I get bash to call a function just before showing a prompt. I do lots of other things in here, and dump history too.

precmd()
{
    ...
    history -a # export history immediately
}
PROMPT_COMMAND=precmd

I don’t automate history importing.

If you’re looking for the copy+paste version, here it is.

# Don't clobber history
shopt -s histappend
HISTFILE=$HOME/.bash_history.nirvana
HISTFILESIZE=1000000000
HISTSIZE=1000000
HISTCONTROL=ignoreboth

precmd()
{
    history -a
}
PROMPT_COMMAND=precmd