This is actually a really interesting behavior and I confess I have greatly underestimated the question at the beginning. But first the facts:
1. What works
The functionality can be achieved in several ways, though each works a bit differently. Note that, in each case, to have the history "transferred" to another terminal (updated), one has to press Enter in the terminal, where he/she wants to retrieve the history.
shopt -s histappend
PROMPT_COMMAND="history -a; history -n; $PROMPT_COMMAND"
This has two drawbacks:
- At login (opening a terminal), the last command from the history file is read twice into the current terminal's history buffer;
- The buffers of different terminals do not stay in sync with the history file.
PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"
(Yes, no need for
shopt -s histappend and yes, it has to be
history -c in the middle of
This version has also two important drawbacks:
- The history file has to be initialized. It has to contain at least one non-empty line (can be anything).
history command can give false output - see below.
"And the winner is..."
shopt -s histappend
PROMPT_COMMAND="history -n; history -w; history -c; history -r; $PROMPT_COMMAND"
This is as far as it gets. It is the only option to have both
erasedups and common history working simultaneously.
This is probably the final solution to all your problems, Aahan.
2. Why does option 2 not seem to work (or: what really doesn't work as expected)?
As I mentioned, each of the above solutions works differently. But the most misleading interpretation of how the settings work comes from analysing the output of
history command. In many cases, the command can give false output. Why? Because it is executed before the sequence of other
history commands contained in the
PROMPT_COMMAND! However, when using the second or third option, one can monitor the changes of
.bash_history contents (using
watch -n1 "tail -n20 .bash_history" for example) and see what the real history is.
3. Why option 3 is so complicated?
It all lies in the way
erasedups works. As the bash manual states, "(...)
erasedups causes all previous lines matching the current line to be removed from the history list before that line is saved". So this is really what the OP wanted (and not just, as I previously thought, to have no duplicates appearing in sequence). Here's why each of the
history -. commands either has to or can not be in the
history -n has to be there before
history -w to read from
.bash_history the commands saved from any other terminal,
history -w has to be there in order to save the history to file and erase duplicates,
history -a must not be placed there instead of
history -w, because it does not trigger erasing duplicates,
history -c is also needed because it prevents trashing the history buffer after each command,
history -r is needed to restore the history buffer from file, thus finally making the history shared across terminal sessions.