78

How does Zsh keep track of command history?

I see two files in my home directory: .zhistory and .zsh_history. What is the difference between them? The files seem to contain all of my history. Does Zsh keep appending lines to one of them forever? Wouldn't that make history search too slow?

Can I safely make these files symbolic links to another location? (e.g. a git repository to keep track of changes to the history)

1
110

Zsh stores input lines (possibly with time information) in the file indicated by the variable HISTFILE. This should be an absolute file name (otherwise it will be interpreted relative to whatever directory is current at the time).

Zsh has no built-in default value for HISTFILE. The zsh distribution comes with a setup wizard for new users which has the value ~/.histfile built in, so this is what zsh users get by default. Oh-my-zsh comes with HISTFILE=.zhistory preset. So it looks like you tried zsh both with the default setup and with oh-my-zsh. Check your .zshrc (or the file dates) to see which one you're currently using.

How zsh opens the file, and therefore what happens if it is a symbolic link, depends on several options.

  • If one of the options append_history (set by default), inc_append_history or share_history is set, or when the history is saved explicitly with fc -AI, zsh appends to the existing file.
    Note that even under these settings, zsh occasionally overwrite the file as described below to trim it down to size.
  • Otherwise, if the option hist_save_by_copy is set (it's set by default since zsh 5.0, but does not exist in 4.2), zsh writes a temporary file then moves it in place when complete. In this case, if the history file was a symbolic link, the new file replaces the symbolic link.
  • Otherwise zsh overwrites the existing file in place.

Rather than point zsh to a symbolic link, set HISTFILE to wherever you want the history file to be.

How many lines of history are kept is configured through the variables HISTSIZE and SAVEHIST. HISTSIZE is the maximum number of lines that are kept in a session and SAVEHIST is the maximum number of lines that are kept in the history file.

To get some history saved at all, you need to set both HISTFILE and SAVEHIST, as the default value of SAVEHIST is 0. You may want to increase HISTSIZE as well (as of zsh 5.0, the default is only 30).

6
  • When I open different terminal connect into same remote machine, they don't see each others newly entered command history. Is it possible to let them see each others recently entered commands?
    – alper
    Jul 20 '20 at 15:45
  • @alper Yes, if you set inc_append_history. Jul 20 '20 at 17:16
  • I have following configuration (gist.github.com/avatar-lavventura/…) in my .zprofile (inc_append_history is included). When I open two window on a terminal. And do echo world_1 on first one, and echo world_2 on the seconds one, they don't see each others commands on the history. But third new terminal sees them
    – alper
    Jul 20 '20 at 17:47
  • You may have answered my question: Until I recently began digging into the history feature in zsh, I've assumed that ALL history was history that was stored in the history file. It's only occurred to me recently that there is also session history - which is stored in memory (??), and may or may not be in the history file depending on how certain options are set. Is that an accurate synopsis of it... two "memories" - one cached and one in a file?
    – Seamus
    Aug 4 '20 at 7:07
  • 2
    @Seamus Yes. Each instance of the shell keeps its own history in memory, and in addition there's a history file. Several settings control when history entries get written to the file: SAVEHIST, append_history, share_history, … Aug 4 '20 at 8:01

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.