Bash History Sync Across Multiple Linux Sessions
Managing shell history across multiple concurrent Bash sessions in
Linux requires balancing in-memory command buffers with persistent disk
storage. By default, Bash isolates history per session, loading commands
from the ~/.bash_history file upon launch and writing them
back only when the session closes, which often causes commands from
parallel terminals to overwrite each other. True synchronization is
achieved by leveraging internal Bash builtins—specifically manipulating
PROMPT_COMMAND, shell options like histappend,
and file read/write triggers (history -a,
history -n, or history -r) to share commands
in near real-time across all active terminals.
The Default In-Memory Model
When a new Bash session begins, it reads existing commands from the
file defined by the HISTFILE variable (typically
~/.bash_history) into an internal memory buffer. During the
session:
- Newly entered commands are stored solely in this local memory list.
- The disk-based history file remains untouched while the session is active.
- When the session exits, Bash writes the in-memory buffer to the history file.
Under default settings, if you open Session A and Session B simultaneously, each operates on an isolated copy of the history. Whichever session closes last may overwrite the changes made by the session that closed first. Even if the shell is configured not to overwrite, the commands from Session A will not appear in Session B until Session A exits and Session B explicitly reloads the history.
Preventing Overwrites
with histappend
The first step in coordinating multiple sessions is preventing
sessions from truncating the history file on exit. This is controlled by
the histappend shell option.
shopt -s histappendWhen histappend is enabled, Bash appends its in-memory
history to the file upon termination rather than replacing the file
contents. While this prevents data loss from the "last-exit-wins"
scenario, it still does not provide real-time visibility across
concurrently running windows.
Real-Time
Synchronization via PROMPT_COMMAND
To achieve immediate synchronization across active terminals, Bash
must be instructed to write each command to disk immediately after
execution and read incoming changes before displaying the next prompt.
This is orchestrated through the PROMPT_COMMAND environment
variable, which executes assigned shell commands prior to generating the
primary prompt (PS1).
Synchronization relies on the history builtin flags:
history -a: Appends unwritten lines from the current session's memory buffer toHISTFILE.history -c: Clears the current session's in-memory history buffer.history -r: Reads the entireHISTFILEand appends its contents to the current in-memory history buffer.history -n: Reads only the lines appended toHISTFILEsince the start of the current session or the last read operation.
A standard implementation in ~/.bashrc combines these
operations:
# Append to the history file, clear local buffer, and re-read the full file
export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"In this setup:
- You run a command in Terminal A.
- Terminal A completes execution, triggers
history -a, and commits the command to~/.bash_history. - When you press Enter or run a command in Terminal B, its
PROMPT_COMMANDrunshistory -c; history -r. - Terminal B now contains Terminal A's recent commands immediately
available in its reverse search (
Ctrl+R) and history list.
An alternative configuration uses
history -a; history -n. This avoids repeatedly clearing and
re-reading the entire file, which reduces disk I/O overhead in systems
with large history allocations (HISTSIZE and
HISTFILESIZE).
Ordering and Timestamps
Because multiple terminals write to the same file concurrently, commands can become interleaved. To maintain a coherent timeline and diagnose execution order across multiple sessions, Linux allows timestamps to be recorded alongside entries:
export HISTTIMEFORMAT="%F %T "When HISTTIMEFORMAT is set, Bash writes a comment line
containing the epoch timestamp prior to each command entry in
~/.bash_history. When reloaded, Bash uses these timestamps
to reconstruct chronological order.