Saturday, November 15, 2008

Update Bash History in Realtime


I have long been annoyed by the behavior of Bash's history file. If you use multiple terminals all history is lost except that of the last terminal closed. The correct behavior should be to save all history from all terminals! An easy way to make that happen is just to save commands to the history file in realtime. Thanks to the Linux Commando I know how to make this happen. Here is the secret:
shopt -s histappend
PROMPT_COMMAND="history -a;$PROMPT_COMMAND"
Put those lines in your bash_profile or bashrc. The first line tells bash to append to the history instead of completely overwriting. The second line calls history -a every time the prompt is shown, which essentially appends the last command to the history file. So simple. I wish I had known this years ago!

7 comments:

Ted Pollari said...

I dunno if I agree with your conclusion about what the proper behavior should be -- if you save all commands, across terminal sessions, you're kinda taking away the point of having multiple terminal sessions, to some extent -- i.e. having independent and isolated working environments. Would you advocate having all environmental variables shared and instantly updated across shells too?

I mean, don't get me wrong, if it works for you, great, but I think you'd find a number of people objecting to your system if it were made a default for anyone else's experience.

Shlomo said...

Ted, the change I suggest doesn't affect the independence of your sessions as you suggest. Each shell maintains a unique history in memory so modifying the history file has no affect on running terminals. The only time the history file is read is when you start a new terminal. I recommend you try my suggestion. Really, all I am doing is eliminating the race condition that causes the bash history file to have inconsistent data.

Thanks for the feedback.

Ted Pollari said...

Thanks for the correction/clarification -- I will probably go ahead and try it then -- my apologies for not following (or trying it before I opened my mouth).

-t

Anonymous said...

awesome! thanks so much, this has always driven me nuts as well.

Shlomo said...

Jessy, you should also check out http://shellsink.com which is an open source tool for aggregating your shell history to a server. I wrote it up here http://www.cuberick.com/2009/02/bash-history-in-cloud.html

zak said...

if you actually do want to mix history between terminals (as is my preference), I humbly suggest:

export PROMPT_COMMAND="history -a; history -n; $PROMPT_COMMAND"

Shlomo said...

Good one Zak. Thanks