I know this question is not obscure, as it is asked here keep updating (and duplicated here).
What I'm trying to achieve is a bit different. I don't like the idea of my prompt rewriting a file every ls
I type (history -a; history -c; history -r
).
I would like to update the file on exit. That's easy (actually, default), but you need to append instead of rewriting:
shopt -s histappend
Now, when a terminal is closed, I would like to make all others that remain open to be aware of the update.
I prefer to do this without checking via $PS1
on every command
that I type. I think it would be better to capture some sort of signal. How would you do that? If not possible, maybe a simple cronjob
?
How can we solve this puzzle?
Best Answer
Creative and involving signals, you say? OK:
Chuck that in
.bashrc
and go. This uses signals to tell everybash
process to check for new history entries when another one exits. This is pretty awful, but it really works.How does it work?
trap
sets a signal handler for either a system signal or one of Bash's internal events. TheEXIT
event is any controlled termination of the shell, whileUSR1
isSIGUSR1
, a meaningless signal we're appropriating.Whenever the shell exits, we:
SIGUSR1
handler and make this shell ignore the signal.bash
processes from the same user.When a
SIGUSR1
arrives, we:Because of the way Bash handles signals, you won't actually get the new history data until you hit Enter the next time, so this doesn't do any better on that front than putting
history -n
intoPROMPT_COMMAND
. It does save reading the file constantly when nothing has happened, though, and there's no writing at all until the shell exits.There are still a couple of issues here, however. The first is that the default response to
SIGUSR1
is to terminate the shell. Any otherbash
processes (running shell scripts, for example) will be killed..bashrc
is not loaded by non-interactive shells. Instead, a file named byBASH_ENV
is loaded: you can set that variable in your environment globally to point to a file with:in it to ignore the signal in them (which resolves the problem).
Finally, although this does what you asked for, the ordering you get will be a bit unusual. In particular, bits of history will be repeated in different orders as they're loaded up and saved separately. That's essentially inherent in what you're asking for, but do be aware that up-arrow history becomes a lot less useful at this point. History substitutions and the like will be shared and work well, though.