30

I'm looking for the zsh equivalent of the bash command history -c, in other words, clear the history for the current session. In zsh history -c returns 1 with an error message history: bad option: -c.

Just to clarify, I'm not looking for a way to delete the contents of $HISTFILE, I just want a command to reset the history to the same state it was in when I opened the terminal. Deleting the contents of $HISTFILE does the opposite of what I want: it deletes the history I want to preserve and preserves the history I want to delete (since current session's history would get appended to it, regardless if its contents was previously erased).

There is a workaround I use for now, but it's obviously less than ideal: in the current session I set HISTFILE=/dev/null and just close and reopen the terminal. This causes the history of the closed session not be appended to $HISTFILE. However, I'd really like something like history -c from bash, which is much more elegant than having to close and restart the terminal.

4
  • What history-related shell options are you using? Are you, for example, sharing history between shell sessions with setopt SHARE_HISTORY or are you using setopt INC_APPEND_HISTORY (both of these writes commands to the history as they are entered)?
    – Kusalananda
    Sep 29, 2019 at 22:45
  • I am using setopt APPEND_HISTORY. I'm quite happy with how that works, it appends the current session's history to the $HISTFILE whenever the terminal is closed. But sometimes I want to clear the history during the session (when I write something stupid), but preserve what is in $HISTFILE
    – Kresimir
    Sep 29, 2019 at 22:47
  • 4
    are you looking for history -p?
    – uniqueid
    Dec 16, 2019 at 15:39
  • It seems like you could use the title like: "How to reset the zsh histroy to a predefined set when I login", otherwise you will keep seeing "history -p" around Jan 5 at 2:16

4 Answers 4

27

The equivalent to history -c on zsh is history -p

5
  • 4
    This has been suggested twice in (now-deleted) answers, and OP's response was "It works, but it does not do what the question asks"
    – muru
    Sep 2, 2020 at 17:39
  • I think the equivalent to history -cw on bash is history -p on zsh?
    – McKay
    Apr 28, 2021 at 19:44
  • Note that history -p in zsh doesn't include the history -p command itself. In bash, it removes the command itself from history
    – Typewar
    Nov 4, 2021 at 21:36
  • This works perfectly. thanks :)
    – Kamlesh
    Dec 19, 2021 at 20:09
  • OP should have state that in title he/she wanted to restore history to a previous state. Jan 5 at 2:14
26

To get an empty history, temporarily set HISTSIZE to zero.

function erase_history { local HISTSIZE=0; }
erase_history

If you want to erase the new history from this shell instance but keep the old history that was loaded initially, empty the history as above then reload the saved history fc -R afterwards.

If you don't want the erase_history call to be recorded in the history, you can filter it out in the zshaddhistory hook.

function zshaddhistory_erase_history {
  [[ $1 != [[:space:]]#erase_history[[:space:]]# ]]
}
zshaddhistory_functions+=(zshaddhistory_erase_history)

Deleting one specific history element (history -d NUM in bash) is another matter. I don't think there's a way other than:

  1. Save the history: fc -AI to append to the history file, or fc -WI to overwrite the history file, depending on your history sharing preferences.
  2. Edit the history file ($HISTFILE).
  3. Reload the history file: fc -R.
7
  • Thank you! This is a good enough workaround that gives the result that I wanted. The only issue I have with it that the call to the erase_history function gets appended to the HISTFILE and thus remembered, but that's a minor inconvenience. I can run a script that erases every instance of erase_history from the HISTFILE.
    – Kresimir
    Oct 3, 2019 at 18:27
  • 1
    @Kresimir Since a few versions ago you can filter which commands enter the history with a zshaddhistory hook. See my edit. Oct 3, 2019 at 19:38
  • Hmm... It doesn't work. The hook works (if I add echo TEST to the zshaddhistory_erase_history function it echos it on every prompt), but the erase_history still gets added to the HISTFILE. I'm probably doing something wrong.
    – Kresimir
    Oct 3, 2019 at 20:11
  • However, I thought of a workaround. If I use setopt HIST_IGNORE_SPACE I can call erase_history with a space in front of it and it will not get added to the HISTFILE.
    – Kresimir
    Oct 3, 2019 at 20:17
  • 1
    @Kresimir Works for me: pastebin.com/Ct4JVjYX with 5.4.2. Maybe you don't have extended_glob turned on? That would cause # not to be a wildcard. I didn't think of it because pretty much everyone has it on. Oct 3, 2019 at 20:27
1

Try running the following command:

kill -9 $$

It will kill the current terminal without saving session history.

The following may be useful too:

rm -f ~/.zsh_history && kill -9 $$

This will remove the history file and kill the current terminal without saving session history.

1
  • This works (leaving no trace) in macOS Catalina. I suspect it works on other versions and platforms as well because of how it works.
    – Colin
    Dec 21, 2021 at 12:32
0

Similar to @Gimi 's answer but a bit more gentle, instead of removing the file I erase all of it's content.

echo -n > ~/.zsh_history

or

:>.zsh_history
0

Not the answer you're looking for? Browse other questions tagged or ask your own question.