5

Following the answer:

When closing multiple bash instances at the same time, there is a known race condition that may cause the history to be cleared. This occurs because there is no locking used when the bash history file is written.

How can I prevent against this cause of bash history purge?

I use i3wm and I think that it happens mostly when I shutdown the computer before I manually close urxvt terminals. The command used (via keybind) for shutdown is systemctl poweroff.

  • very similar to question <unix.stackexchange.com/questions/1288/…> – Franklin Piat Mar 13 '15 at 21:02
  • Zsh doesn't have this bug... – Gilles Mar 13 '15 at 22:48
  • @FranklinPiat Similar object(bash+history), but quite different question. I don't want to share histories between already made sessions. I just want to keep all the commands I've used at next computer start-up. Also I want to prevent of history purge. – kravemir Mar 14 '15 at 9:07
  • @Giles I've just found slides "ZSH vs BASH". ZSH looks cool ^_^ – kravemir Mar 14 '15 at 9:47
2

The source of the race condition is because bash only writes the history file as the shell exits. Plus it will over write the existing history file if multiple shells are running, only the last to exit will dominate the history.

So one solution is to write history out, after EVERY command. There or some negative consequences to this, such as you'll be able to up arrow history events occurring in other windows, and therefor will expose to all open shells (that you own) what commands you just ran. The most likely place this will bite you is if you are doing a repetitive set of commands, like 'up arrow N times, then hit enter' over and over again. If in a closed window a background process ends, then suddenly you'll need to pay closer attention what command is really 'up arrow N+1 times' risking running the wrong command.

To turn 'history on with every command' try adding these to you .bashrc (number of lines of history to store are just examples, you can change them for your comfort)

HISTFILESIZE=400000000
HISTSIZE=10000
PROMPT_COMMAND="history -a"
export HISTSIZE PROMPT_COMMAND

shopt -s histappend
  • Interesting idea, but I don't want to share histories between running sessions. Would it be possible without affecting already made sessions? – kravemir Mar 14 '15 at 9:10
1

When you start bash, it will warn you if your history has been deleted (as measured by line count). If the history has not been deleted, it will be backed up.

~/.bashrc

# backup history/warn about deleted history
if (( $(wc -l < ~/.bash_history) < 1100 ))
then
    echo "#########################"
    echo ".bash_history was cleared"
    echo "#########################"
else
    cp ~/.bash_history ~/.bash_history.back
fi
  • 1
    (1) Can you explain how this answers the question?  (2) The question is about the risks of doing asynchronous file modification without benefit of a synchronization protocol like file locking.  This answer seems to be throwing gasoline on the fire, by writing the .bash_history.back file in every new bash process, in a context where the user may be opening multiple new windows at the same time. – Scott May 31 at 4:02
  • @Scott: (2) I really don't think the asker had any of that in mind. They just want to stop losing their history. (1) While I agree this solution doesn't answer the question directly (i.e. How can this problem be prevented?), this does help mitigate the damage. As for making the problem worse, I don't see an issue. My .bash_history is 100k lines and backing it up it adds 8ms to the startup time. Even more, the race condition is caused when the bash instances are closed, not started. – Evidlo May 31 at 4:31
  • @Evidlo added to my .bashrc thank you – somethingSomething May 31 at 4:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.