I’ve never been able to trust Over the past eight years, I’ve hoarded ¾ million lines of bash
history: This accounts for every shell command I’ve run since 2016—all saved
to a 102MB file: It’s a perfect, searchable archive of my work. I’ve come to rely on To save my history, I exploit the bash Bash will execute anything you assign to You can use this variable to write the output of
I started doing this in 20151, but the more
metadata I added—bash process ID, current directory, user—the more
powerful my history became. Today, my history file looks like this: Now, I can crawl these bits of metadata to look at my history in
interesting ways. For example: My eternal shell history has been working well for eight years. But
every solution has tradeoffs and problems: Goals of And the hacks I’ve seen to juice bash’s built-in
Other pitfalls: I’ve set some sensible defaults and ignored clever ideas. Here are my
settings: When I read the wonderful, shorter
version of this article: Andy Teijelo Pérez’s Bash
eternal history↩︎ I scraped
of GitHub for HISTSIZE=. It’s all over the place. Max:
10,000,000,000,000,000; 25 percentile: 1,000; 75th percentile: 100,000;
median: 10,000. I set mine at the median. Works fine.↩︎
~/.bash_history.
Regardless of my configuration, I was forever searching for that one
gnarly jq
filter that had somehow disappeared. Then, I found a better way.$ wc -l < ~/.muh_history
763075~/.muh_history.$ ls -lh ~/.muh_history
-rw------- 1 thcipriani thcipriani 102M Feb 27 21:23 /home/thcipriani/.muh_history
~/.muh_history to take notes for me
while I focus on solving problems. I trust this system, because it’s so
simple.🛟 Simple history via prompt command
PROMPT_COMMAND
variable.PROMPT_COMMAND
before showing your prompt:$ export PROMPT_COMMAND='fortune && echo 🥳'
Q: Do you know what the death rate around here is?
A: One per person.
🥳
$history 1 to a file:$ export PROMPT_COMMAND='history 1 >> ~/.muh-history.test'
$ fortune
Caution: breathing may be hazardous to your health.
$ cat ~/.muh-history.test
6851 2024-02-25 18:44:30-0700 export PROMPT_COMMAND='history 1 >> ~/.test-history'
6852 2024-02-25 18:44:35-0700 fortune$ tail -1 ~/.muh-history
847008 /home/thcipriani thcipriani 2024-02-27T15:52:16-0700 echo 'Weeee!' | figlet | lolcat
🧐 Problems and tradeoffs of
~/.muh_history
HISTCONTROL=ignorespace setting helps—it makes
history ignore commands that start with a space.PROMPT_COMMAND and history (e.g., zsh’s
preexec, fish’s fish_preexec).PROMPT_COMMAND
under the hood. Maybe I’d start there if I were starting today, but
~/.muh_history pre-dates both projects.⚠️ Flailing at bash’s built-in history
~/.muh_history:
ctrl-r should work in the default way.ctrl-r.~/.bash_history fail at least one of these:
HIST(FILE)SIZE=<huge number>2 –
On startup, bash loads a HISTSIZE amount of
HISTFILE into memory—this could cause lag
during bash startup unless you logrotate regularly. And there’s a
risk of losing commands if/when your sessions crash.unset HIST(FILE)SIZE/HIS(FILE)SIZE=-1 –
This should make HIST(FILE)SIZE infinite, so the same
caveats apply as using a huge number. Plus, this has a history of failing
in some instances.HISTFILE=~/.history/$(date -I) – For the first bash
session you start in the morning ctrl-r will give you
nothing.PROMPT_COMMAND='history -a && history -r' –
Before showing your prompt, write your in-memory history to
HISTFILE and re-read it into memory. This mixes up the
history of different sessions, so hitting “↑” may show history from a
different session.
exit a
session, bash dumps HISTSIZE lines of your command history
into ~/.bash_history. If your session crashes: all gone.
This makes HIST(FILE)SIZE unappealing to me.histappend, bash will overwrite
~/.bash_history rather than append your session history on
exit.~/.bash_history.# append to history vs. overwrite
shopt -s histappend
# ignore commands starting with space; ignore duplicates
HISTCONTROL=ignoredups:ignorespace
# Up the history in memory: 500 → 10,000
HISTSIZE=10000
# Up the history on disk: 500 → 20,000
HISTFILESIZE=20000
# RFC 3339 format; e.g., 2024-02-27T15:52:16-0700
HISTTIMEFORMAT='%FT%T%z '
Posted