Is there a way to define an unlimited history in Bash ?
6 Answers
Add this to your .bashrc (Linux) or .bash_profile (MacOS):
export HISTFILESIZE=
export HISTSIZE=
There you go, unlimited history. Currently I have 27000 entries :)
From man bash:
If
HISTFILESIZEis not set, no truncation is performed.
That means .bash_history is never truncated
Also the same seems to apply to HISTSIZE, although I couldn't find that documented.
Another neat feature I'm going to try is this:
If the
HISTTIMEFORMATvariable is set, time stamps are written to the history file, marked with the history comment character, so they may be preserved across shell sessions, like the following:
export HISTTIMEFORMAT="%F %T "
Let me know if you have tried that already...
- 321
- 1,136
After many large, ugly iterations and weird edge cases over the years, I now have a concise section of my .bashrc dedicated to this.
First, you must comment out or remove this section of your .bashrc (default for Ubuntu). If you don't, then certain environments (like running screen sessions) will still truncate your history:
# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
# HISTSIZE=1000
# HISTFILESIZE=2000
Second, add this to the bottom of your .bashrc:
# Eternal bash history.
# ---------------------
# Undocumented feature which sets the size to "unlimited".
# https://stackoverflow.com/questions/9457233/unlimited-bash-history
export HISTFILESIZE=
export HISTSIZE=
export HISTTIMEFORMAT="[%F %T] "
# Change the file location because certain bash sessions truncate .bash_history file upon close.
# http://superuser.com/questions/575479/bash-history-truncated-to-500-lines-on-each-login
export HISTFILE=~/.bash_eternal_history
# Force prompt to write history after every command.
# http://superuser.com/questions/20900/bash-history-loss
PROMPT_COMMAND="history -a; $PROMPT_COMMAND"
Note: every command is written immediately after it's run, so if you accidentally paste a password you cannot just "kill -9 %%" to avoid the history write, you'll need to remove it manually.
Also note that each bash session will load the full history file in memory, but even if your history file grows to 10MB (which will take a long, long time) you won't notice much of an effect on your bash startup time.
-
8The history file gets truncated when you set
HISTFILESIZE, this is why you should remove any occurence of such event except the one you want. It'll be also truncated on shell exit (but that is expected). And you shouldn't needexport. – vaab Jan 23 '15 at 02:22 -
5@vaab If you do not export, doing something like
bash --norcwill truncate the history again. – Yongwei Wu Nov 02 '16 at 02:58 -
2I use
export HISTFILE="/home/$USER/hist/\uname -n``tty | tr '/' '-'`"` to keep shell history separate per session (based on hostname and tty name). Of course I have to create ~/hist directory first. – Jeff Learman Nov 29 '16 at 21:40 -
FYI, on my Fedora system, "~" doesn't work in HISTFILE; it doesn't get expanded. No idea why; it works in other contexts. – Jeff Learman Nov 29 '16 at 21:54
-
4Note you may want to check the value of PROMPT_COMMAND and not blindly append this repeatedly as it will do crazy things to your system. A null check or better yet a shell variable expansion search is probably safer. – dragon788 Jun 20 '17 at 21:44
-
1@fotinakis Why are you doing
export HISTFILESIZE=instead ofHISTFILESIZE=when it is default in .bashrc? Don't all variables get inherited by subshells ifexportis not mentioned ? – GypsyCosmonaut Jul 06 '17 at 21:47 -
6I use this to avoid the issue @dragon788 referred to:
PROMPT_COMMAND="${PROMPT_COMMAND:+${PROMPT_COMMAND} ;}history -a";– Brian Vandenberg Oct 09 '17 at 19:20 -
I've used this for a while and I find that the "eternal" history file still gets truncated, albeit after a much longer time period. I still haven't tracked down why this is happening or under what conditions. – Ethan T Dec 20 '21 at 15:56
-
Question: why the
HISTTIMEFORMAT? Removing it was the only way i could find of successfully copying my previous.bash_historyover into the new one. – Sean Bone Apr 05 '23 at 12:53
Include in ~/.bashrc:
# append a session's history on shell exit
shopt -s histappend
export HISTFILESIZE=
export HISTSIZE=
This answer satisfies the following criteria:
a separate master history (no session can interrupt your history)
automatic history writing (no hotkeys)
infrequent writes (no appending after each command)
background
On interactive startup, if $HISTFILESIZE is set to a number, bash truncates $HISTFILE to that number. On interactive close, if the shell option histappend is set, bash appends $HISTSIZE lines to $HISTFILE, otherwise it overwrites $HISTFILE.
tips for OSX (Terminal)
Every time a tab is created in Terminal, ~/.bash_profile is read, which means bash doesn't go on to read your ~/.bashrc. Add the following line to your ~/etc/bash_profile:
# if bashrc has content, source it
[[ -s ~/.bashrc ]] && . ~/.bashrc
tips for screen
If you use screen, your configuration file is ~/.screenrc. If you want screen to record history, you just need to set it to use a login shell which will source your bash startup files (and record your history).
# use bash, make it a login shell
defshell -bash
- 662
-
setting
histappendwith apple terminal disables apples session history for the shell. The session history is very useful, doing what most people want -- restoring the history in the event of a crash or restart, and merging the history of mulitple sessions so new sessions start with the merged history of the past. – SpinUp __ A Davis Jul 22 '22 at 00:58
A different concept (may not be applicable) but you can have unlimited history when using shell-sink.
- 6,342
Sorry for may be late answer, but for completeness: at me (Debian Bullseye) works
HISTSIZE=-1
HISTFILESIZE=-1
- 101
I never could get increased history to work on my Mac so I created my own.
I added this code to my .zshrc, pretty sure it would work in .bashrc as well. It captures every command you do and writes it to the file, with a line number.
It gives you a new command hist on the command line. You can pass it hist -10 and it will show the last 10 lines of your new history file. Just hist will default to 20 lines.
history_file=~/Documents/history
precmd() {
local last_command=$(history | tail -n 1 | sed 's/^[[:space:]]*[0-9]*[[:space:]]*//')
local counter=1
# If the file exists and is not empty, get the last number and increment it
if [[ -s $history_file ]]; then
counter=$(( $(tail -n 1 "$history_file" | awk '{print $1}') + 1 ))
fi
echo "$counter $last_command" >> "$history_file"
}
hist() {
local num_lines=20 # default number of lines
# Check if an argument is provided and it's a valid number
if [[ $# -eq 1 && $1 =~ ^-?[0-9]+$ ]]; then
num_lines=$1
fi
# Display the specified number of lines from the history file
tail -n $num_lines "$history_file"
}
- 6,771
- 1
gdb; if you set anHISTSIZEvariable it will take it as a 0, thus disabling history size entirely. – Matteo Italia Dec 05 '14 at 08:37export,HISTFILESIZEis in number of lines (not bytes), and history file truncating happens when you set variableHISTFILESIZE(and when shell exits). So don't set it twice in your config file with different values... – vaab Jan 23 '15 at 02:17unsetinstead of exporting empty? – oneat Jan 10 '22 at 08:36