To understand the behaviour of the bash history first you have to know the following:
- There is a history file.
- There is a history in a running bash session.
- Multiple bash session each have their own history and do not sync with each other.
- The session history is not synced with the history file unless explicitly asked to or during some specific event (see below).
Using the default settings, the lifecycle of a bash session with regard to the history is as follows:
- During startup bash will read the history file. The content of the history file is now the bash session history.
- During normal use only the session history is manipulated.
- During shutdown the history file is overwritten with the session history. All previous content of the history file is gone.
Read the bash manual for a more detailed explanation of the startup and shutdown process: http://www.gnu.org/software/bash/manual/html_node/Bash-History-Facilities.html#Bash-History-Facilities
The seemingly nondeterministic behaviour you have observed is mostly because the content of the history file is always the session history of the last closed bash session. And bash only reads the history file during startup.
Note that with default settings I mean the default settings from bash. Your distribution might have provided a .bashrc (or /etc/bash.bashrc) which change this behaviour.
By enabling the shell option histappend you can tell bash to append instead of overwriting the history file. You can enable histappend using the command shopt -s histappend. To have this option always enabled you have to put the command in your .bashrc (or other initialization file). Read more about the shopt command in the bash manual: http://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html#The-Shopt-Builtin
Note that enabling histappend will not reduce the seemingly nondeterministic behaviour by much. This is because every bash session still has it's own session history.
using the builtin command history you can explicitly tell bash to read from the history file to session history or the write the session history to history file.
For example: history -r will read the content of the file and append it to the session history (this mimics bash behaviour during start). history -w will write the session history to history file, overwriting the previous content (this mimics bash behaviour during shutdown). Read more about the history command in the bash manual: http://www.gnu.org/software/bash/manual/html_node/Bash-History-Builtins.html#Bash-History-Builtins
For completeness here is a list of the internal variables which modify the history behaviour:
HISTFILE: the file to read from and write the history to.
HISTCONTROL, HISTIGNORE: prevent some commands from being saved to history. applies only to session history. not history file.
Read the bash manual for more: http://www.gnu.org/software/bash/manual/html_node/Bash-Variables.html#Bash-Variables
With a bit of hacking it is possible to have a mostly synchronized bash history. There is a discussion how to get every bash process to have a mostly synced history in stack overflow: https://stackoverflow.com/questions/103944/real-time-history-export-amongst-bash-terminal-windows/3055135#3055135