Creative and involving signals, you say? OK:
trap on_exit EXIT
trap on_usr1 USR1
trap '' USR1
killall -u "$USER" -USR1 bash
Chuck that in
.bashrc and go. This uses signals to tell every
bash 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. The
EXIT event is any controlled termination of the shell, while
SIGUSR1, a meaningless signal we're appropriating.
Whenever the shell exits, we:
- Append all history to the file explicitly.
- Disable the
SIGUSR1 handler and make this shell ignore the signal.
- Send the signal to all running
bash processes from the same user.
SIGUSR1 arrives, we:
- Load all new entries from the history file into the shell's in-memory history list.
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 into
PROMPT_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 other
bash processes (running shell scripts, for example) will be killed.
.bashrc is not loaded by non-interactive shells. Instead, a file named by
BASH_ENV is loaded: you can set that variable in your environment globally to point to a file with:
trap '' USR1
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.