28

I've tried to search in ~/.bash_history for my recent commands while in a terminal session but they just weren't there. I guess this is because I have multiple terminal sessions open.

Is there a way that I can sync (ie. sync-push or sync-write-out) the current terminal session's command history into the bash_history file (without closing the session and losing that environment)?

(It would be remotely similar in idea to how the sync command stores the file-system modifications on some systems.)

I imagine I could set up bash to preserve multiple session history but the ability to push the current history buffer would still be useful in scenarios when you are working on a new machine and you accidentally forgot to set up bash the way you may would have wanted.

n611x007
  • 1,007

2 Answers2

35

Add this line to .bashrc:

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

Open new terminal and check.

Explanation

  • history -a appends new history lines to history file.
  • history -n tells bash to read lines that is not read from history file to current history list of session.
  • PROMPT_COMMAND: contents of this variable is run as regular command before bash show prompt. So every time after you execute a command, history -a; history -n is executed, and your bash history is synced.
David Birks
  • 490
  • 6
  • 6
cuonglm
  • 153,898
  • thanks! I don't know why did I get permission denied before but with new terminals now this seems to work as expected! I guess I should normally be able to use history -a in a terminal with unmodified bashrc too. – n611x007 May 22 '14 at 11:40
  • 1
    when do one have to start to worry about the performance implications of this? (I'm thinking about low-end devices, not sure how big overhead this makes.) – n611x007 May 22 '14 at 11:42
  • 2
    Also you might already have a prompt command, in this case it is better to use export PROMPT_COMMAND="${PROMPT_COMMAND};history -a; history -n" – Fabian May 22 '14 at 13:02
  • If ${PROMPT_COMMAND} is empty this gives an error because of the leading ; – Boris Däppen Mar 20 '17 at 13:16
  • @BorisDäppen is right, but this is easily remedied export PROMPT_COMMAND="${PROMPT_COMMAND}${PROMPT_COMMAND:+;}history -a; history -n" – TML Jun 11 '18 at 15:15
  • I would advise against messing with history after every command. I'm not sure about you, but when I press Up, I expect to see the command that was executed in this particular shell. The same goes for sudo !!. See this answer. – x-yuri Oct 11 '20 at 07:33
5

While I like being able to share history between terminals, especially new terminals. I would not want to share each and every command as it happens, as one window is often doing a specific task, separate form other windows. I would have them merge on shell exit, or when I request.

For a long time I looked for a way to merge bash history (with timestamps), and nothing seemed acceptable to me...

Finally I just 'bit the bullet' and DIY'ed a script to merge, the on-disk ".bash_history" with the in-memory shell 'history'. Preserving timestamp ordering, and command order within those timestamps.

Now when I source this (you could make it a alias or a function as you like), I use the alias 'hc'. My current shell session is merged between disk and memory, so history is updated from other previous merges, WHEN I WANT (or on logout from that shell via ".bash_logout").

Optionally you can remove unique commands (even if multi-line), and/or removing (cleaning out) simple and/or sensitive commands, according to defined perl RE's. Adjust to suit!

This is the result... https://antofthy.gitlab.io/software/history_merge.bash.txt

Enjoy.

anthony
  • 610
  • +1 good point about not wanting to load history from other terminals constantly. I decided to go with history -a in the PROMPT_COMMAND, and run (an alias for) history -n when I do want to load history from other shells. Your scripts looks good but it's over-powered for my current needs. – Sam Watkins Feb 10 '22 at 06:09
  • My current problem is bash's multi-line handling. On the startup history read, it does so BEFORE I set that I want multi-line history, so bash breaks all the multi-line commands to multiple single line commands! ARggghhh... Only does this on start up! Not during normal save, merge or re-read. – anthony Oct 09 '22 at 03:12