4

Is it possible to have a single command history that gets shared between all shells?

I think by default the history gets overwritten by the shell that exits first. Before I've done stuff where each shell has a "name" and its own history file, but my use of shells is a little more lightweight nowadays so that feels like overkill.

Updates

It looks like I didn't has incappendhistory enabled:

> setopt | grep inc

Running setopt incappendhistory fixed this. I could then see bylooking at the history file that these files were appended immediately.

However this history only seems to become avaiable to other shells after a new shell is opened (which is probably the behaviour I am after). Setting sharedhistory with setopt made commands in other shells immediately available. I don't actually think this is what I'm after - since having distinct history in different shells is useful. I just don't want to lose history.

4
  • 1
    In zsh (unlike bash) this is the default. Maybe you've turned off the append_history option? The options inc_append_history and share_history make the order more real-time. See also unix.stackexchange.com/questions/111718/command-history-in-zsh Sep 21, 2021 at 13:33
  • Thanks Gilles. I think I might have just needed to restart the shelll to view the "old" history actually. As I didn't have shared_history enabled. I think I actually don't want shared_history... I just want to make sure I don't lose anything.
    – Att Righ
    Sep 21, 2021 at 14:29
  • 1
    So I still don't understand what you're asking. What history-related settings do you have? In what way does the current behavior differ from what you want? Sep 21, 2021 at 14:50
  • Well I guess my question was "can I have a combined history", and the answer was "yes, but the history does not become visible until such time as you start a new shell if you want the history to be immediately visible run setopt sharedhistory"
    – Att Righ
    Sep 21, 2021 at 14:55

1 Answer 1

7

First, by default, zsh doesn't save the command history. You need to set HISTFILE to the path to the file where you want to save the history and SAVEHIST to the number of lines you want to save. See Command history in Zsh. In the rest of this answer, I'll assume that the history is being saved, and discuss when it gets saved and loaded.

By default, zsh loads the history when it starts and saves it when it exits. When it saves the history, it appends the history of the current session to the history file. So no history is lost, even when there are concurrent sessions (until the history file reaches 1.2 times $SAVEHIST lines, at which point zsh will trim the file). The main advantage of this approach is that lines from a session remain grouped together. A downside is that lines from session A will only appear in sessions started after session A exits. Another downside is that if your machine (or zsh) crashes, the history is lost (but the history is saved if the terminal merely disappears, for example because an SSH connection dies due to a network problem).

If you turn on the share_history option, zsh will save each history line as soon as it's entered, and will load new history lines as soon as they become available. (Or more precisely, before displaying a new prompt; zsh won't read history while you're editing a command line.) The main advantage is that history lines are available immediately in all sessions. The main downside is that lines from different sessions will end up mixed, so lines that are consecutive in the history might not make any sense with respect to each other.

There are also the options inc_append_history and inc_append_history_time. They cause zsh to save the history as soon as it runs each command, but it won't read new history lines automatically (other than when it starts, of course). The _time variant saves the history after running a command, rather than before, which allows zsh to save the time it took to run.

You can turn off the append_history option, and zsh will overwrite the history file when it saves it, instead of appending to it. As a consequence, if you start session A, then start session B, then exit A, then exit B, the history from A will be lost. I can't think of a good reason for choosing this behavior (but it's the bash default).

You can import new lines the history file at any time by running fc -RI. This is useful if you don't use share_history, to explicitly import the history from other sessions from time to time.

You can save new lines to the history at any time by running fc -AI. This is useful if you don't use inc_append_history or share_history, to explicitly export the current session's history from time to time.

What I described as defaults in this answer are the zsh defaults. Some distributions and most zsh configuration frameworks will at least enable the history by default, and may change some history-related options.

1
  • Very nice and thorough answer, thanks!
    – Petr
    Jul 27, 2022 at 17:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .