I store a separate bash history per directory, in a tree under ~/.bash_history.d. Each time I change directories, my shell flushes its history to that directory's histfile, and loads in the histfile for the new directory.
It may sound weird, but look at this way: Usually I cd to a "place" to work on some particular project. When a cd to some project I haven't touched in a while, it's very useful to have, in 'history', a context – the usual commands I use to start up that server, the last few files I fiddled with, etc.
(You can skip the stuff wrapping virtualenv, obviously.)
Basically just define a function that does the write, set HISTFILE, read, and then elsewhere alias cd=mycd.
If anyone gives it a try, I'd love to hear how it works! I think it needs some tweaks -- for example, multiple terminals in the same directory are probably clobbering each other -- looks like this 'shopt -s histappend' would help with that.
I always thought I wanted an in-sync bash history but after a few days of trying I realised it actually slowed me down. I have multiple terminals open (with Terminator, most of the time) and different windows / tabs are for different projects or tasks. If I'm building / configuring a project in 1 window, suddenly having a few apt-gets or log tails interspersed is very unproductive.
Yes, I found that too. It's convenient that up-arrow is context-specific. However, as a commenter on the blog said, the first suggestion avoids the "last logout wins" problem:
histappend is a must for me for any decent bash history usage; I like to set HISTCONTROL=ignoredups along with it to keep things clean and I increased HISTSIZE and HISTFILESIZE from the defaults.
A good bash history can often save your behind when trying to reconstruct what you did or when you have to run that one magic command you last ran 5 months ago...
I am going to chime in with a similar sentiment. I also had bash configured like this for awhile when I realized it is not what I wanted.
If you typically use different terminal windows for different tasks (e.g. terminal #1 for compiling, terminal #2 for manpages, terminal #3 for vim, etc.), this will just clutter up your history with items unrelated to what your are doing.
I've found that one thing that was very helpful for me was to keep history per machine. For me having the history make sense in the context of the system function is very valuable and I know that I won't get other commands that I don't need or want to see in my history.
What I do it HISTFILE=$HOME/.history/`hostname`.history so then I have a nice record of what I've done on all the machines I log into. This is particularly nice when you have a central home directory.
Great post! I use screen a lot, and always miss having the other terminal histories readily available.
However, reversing PROMPT_COMMAND so that "history -a" comes first makes more sense: this way the last command executed on the current terminal has a better chance of being on top of the list for the next up-arrow (which more closely resembles usual behavior).
Also, as noted above, it's better to append to PROMPT_COMMAND rather than just overwriting it. Thus, my .bashrc now reads:
export PROMPT_COMMAND="history -a; history -n;${PROMPT_COMMAND}"
From the title, I thought he would do just that at first! But I guess since the HISTFILE is being constantly read like that anyway, you could just use rsync or similar means to keep it in sync across multiple machines.
I really like the "ctrl + o" trick mentioned in the third comment: "Normally, if you enter a series of commands, you can go back to the first one, and hit Ctrl-O repeatedly to run the current command and retrieve the next."
${VARIABLE:-value} expands to the contents of $VARIABLE, if it exists, or to "value" otherwise. In this case value is ":", a bash builtin that does nothing. Effectively, the above sets PROMPT_COMMAND to run the autojump command, then to run the pre-existing PROMPT_COMMAND, if any, or a no-op.
I was having some weird problems two, with some commands not even being recorded.
As people on the blog commented, I've followed and only include `history -a`. Running `history -n` would screw up the workflow of pressing the up cursor to scroll through the current terminal's history.
I suggest some of the following setopt's:
APPEND_HISTORY AUTO_CD HIST_IGNORE_SPACE HIST_IGNORE_DUPS HIST_NO_STORE
AUTO_CD is nice because you can just straight-up type a directory and it'll go there (i.e. .. or tilde).
HIST_IGNORE_SPACE and HIST_NO_STORE work out nicely when you want commands not to show up, i.e. stuff where maybe your password is inline, or you're handling something sensitive.
HIST_IGNORE_DUPS just saves space. HIST_IGNORE_ALL_DUPS even more so.
I think akkartik is responding to willlll (who posted "use zsh, problem solved"), not to silverstorm (who posted "zsh does a terrible job at keeping bash history in sync.").
It may sound weird, but look at this way: Usually I cd to a "place" to work on some particular project. When a cd to some project I haven't touched in a while, it's very useful to have, in 'history', a context – the usual commands I use to start up that server, the last few files I fiddled with, etc.
Anyone else do something like this?