If you work with multiple terminal tabs or windows—especially in iTerm or Terminal.app—you've probably noticed that each session maintains its own isolated command history. This becomes frustrating when you run a command in one tab and want to recall it in another. By default, bash only saves history when a session closes, and each session can overwrite the others' history.
The Problem
Bash's default behavior creates several issues for multi-tab workflows:
- Isolated histories: Each terminal session maintains its own separate history in memory
- Last-write-wins: When sessions close, the last one to exit overwrites the history file
- Lost commands: Commands from other still-open sessions get lost
- No real-time sync: You can't access commands from other active sessions
This makes it difficult to "backtrack your steps" when working across multiple terminals, especially during complex debugging or deployment tasks.
The Solution: Synchronized History
You can configure bash to share history across all sessions in real-time by adding a few lines to your shell configuration file.
Configuration
Add this code to your ~/.profile (or ~/.bash_profile or ~/.bashrc):
export HISTCONTROL=ignoredups:erasedups # no duplicate entries
export HISTSIZE=100000 # big big history
export HISTFILESIZE=100000 # big big history
shopt -s histappend # append to history, don't overwrite it
# Save and reload the history after each command finishes
export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"
How It Works
Let's break down each configuration line:
Prevent Duplicates:
export HISTCONTROL=ignoredups:erasedups
Prevents duplicate commands from cluttering your history. The ignoredups option ignores consecutive duplicates, while erasedups removes all previous instances of a command when you run it again.
Increase History Size:
export HISTSIZE=100000
export HISTFILESIZE=100000
By default, bash only keeps 500 commands. These settings increase the in-memory history (HISTSIZE) and the history file (HISTFILESIZE) to 100,000 commands each—enough for months of work.
Append Instead of Overwrite:
shopt -s histappend
Changes bash's behavior to append to the history file instead of overwriting it. This is crucial for preventing sessions from clobbering each other's history.
Real-Time Synchronization:
export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"
This is the key to real-time history sharing. The PROMPT_COMMAND runs after every command you execute. It performs three operations:
history -a: Appends the current session's new history to the history filehistory -c: Clears the current session's in-memory historyhistory -r: Reads the entire history file back into memory
This cycle ensures every terminal session always has the complete, up-to-date history from all sessions.
Installation
- Edit your profile file:
bash nano ~/.profile(Or~/.bash_profileor~/.bashrcdepending on your system) - Add the configuration shown above
- Apply the changes:
bash source ~/.profile - Test it: Open two terminal tabs, run a unique command in one tab, press Up arrow in the other tab—you should see the command from the first tab.
Benefits
Access Any Command from Any Session:
Run ls -la in tab 1, and you can immediately recall it with Up arrow in tab 2.
Never Lose History: Even if a session crashes, all commands are safely written to the history file immediately.
Better Workflow: Jump between tabs freely without worrying about losing track of what you've run.
Huge History: With 100,000 entries, you can search back through months of work.
Notes
Performance: The real-time sync adds minimal overhead. On modern systems, the delay is imperceptible.
Choose the Right File:
- On Mac OS X, use
~/.profileor~/.bash_profile - On Linux, use
~/.bashrc - When in doubt, check which file your system sources by default
History Search:
Use Ctrl+R to search through your shared history interactively. With 100,000 entries and all sessions synchronized, this becomes incredibly powerful.
Preserving Existing PROMPT_COMMAND:
The configuration appends to $PROMPT_COMMAND (note the $PROMPT_COMMAND at the end), so it won't break any existing prompt customizations.
View the original code on Gist.