Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Keeping bash history in sync between multiple terminals (briancarper.net)
151 points by patpng on March 26, 2012 | hide | past | favorite | 34 comments


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.

Anyone else do something like this?


That is brilliant! Care to point me toward a working implementation? :)


Sure -- here is the actual version from my dotfiles:

https://github.com/aaronharnly/dotfiles-public/blob/master/....

(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 am totally going to try this out! Thanks!


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:

  shopt -s histappend


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.


Granted. But then if tomorrow you do want a record of what you did in terminal 2 today? Multiple histories?


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}"


A real trick would be keeping the bash history in sync between multiple machines.


I keep my ~/.bashrc in my Dropbox and symlink to it. You could do the same with ~/.bash_history.


Yeah, I do this as well. It is often very useful.


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."

Found a description here: http://www.halotis.com/2010/07/06/bash-keyboard-shortcuts/


Don't overwrite the PROMPT_COMMAND like this, you risk breaking other tools such as autojump. Instead, append to it.


How?


This is how autojump does it:

    export PROMPT_COMMAND="$AUTOJUMP ; ${PROMPT_COMMAND:-:}"


My bash-fu is weak; can you break that down for me?


${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.


It doesn't seem to work for me unless I switch the two commands:

  PROMPT_COMMAND='history -a;history -n'


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.


use ZSH! the autocomplete is much nicer as well. (check out oh-my-zsh for awesome configs)


I use a tmux session on my server, so all I need is to log in from any computer and bring the session back up


But... you still use different windows and panes, right?


use zsh, problem solved


zsh does a terrible job at keeping bash history in sync.


How?

(I use zsh. I also downvoted you.)


Because zsh has shared history, I'm not sure if it's enabled by default, but I use oh-my-zsh (highly recommended!) and shared history works.

Edit: How to enable in zsh: http://www.refining-linux.org/archives/49/ZSH-Gem-15-Shared-...


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.


He's joking that Zsh isn't Bash and therefor doesn't keep Bash's history in sync.


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.").


File not found.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: