Disclaimer: I don't use eshell, so take this with a grain of salt.
eshell appears to call
eshell-write-history to write history, which takes an optional argument
append which defaults to
nil. This argument seems to be unused in
eshell presently, but does appear to work (it passes the argument through to
write-region, which does properly append).
There are a couple of options here.
(setq eshell-save-history-on-exit nil) and call
eshell-write-history to satisfy your requirement.
Personally, I'd go with 1.
As an example:
(setq eshell-save-history-on-exit nil)
(defun eshell-append-history ()
"Call `eshell-write-history' with the `append' parameter set to `t'."
(let ((newest-cmd-ring (make-ring 1)))
(ring-insert newest-cmd-ring (car (ring-elements eshell-history-ring)))
(let ((eshell-history-ring newest-cmd-ring))
(eshell-write-history eshell-history-file-name t)))))
(add-hook eshell-pre-command-hook #'eshell-append-history)
Thanks to @joseph-garvin for the corrected, working
This doesn't handle dynamically loading the new history contents into a shell (eg run command
X in shell A, and having it appear in history in shell B without reloading; like zsh's SHARE_HISTORY). I don't know how efficient
eshell-read-history is, so I'd be hesitant to run it in a hook.
It is also possible that you will end up with duplicate entries with this
eshell-append-history function. You may need to do some shenanigans with clearing all but the most recent entry from
eshell-history-ring, then resetting it to the old value after writing history.
(let ((old-ring (copy-list eshell-history-ring)))
(setq eshell-history-ring (list (car eshell-history-ring)))
(setq eshell-history-ring old-ring))