19

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.

3
  • 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 '19 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 '19 at 22:47
  • 3
    are you looking for history -p?
    – uniqueid
    Dec 16 '19 at 15:39
23

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 '19 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 '19 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 '19 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 '19 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 '19 at 20:27
13

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

2
  • 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 '20 at 17:39
  • I think the equivalent to history -cw on bash is history -p on zsh?
    – McKay
    Apr 28 at 19:44
0

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.

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
5
  • Hm. Why is that more gentle? Also, if you want to clear a file, you could simply do :>.zsh_history.
    – AdminBee
    yesterday
  • @AdminBee well, if you delete the file then the OS will have to create it again as soon as you write a new command in order to save it, so even thought it's not a power/time expensive operation to recreate the file why force the system to do so if you can simply erase the text. I wasn't aware of this other solution, thanks.
    – serax
    yesterday
  • I just tried running your command and then history and it showed the previous commands so it doesn't work. @AdminBee
    – serax
    yesterday
  • But was the .zsh_history file truncated? The command history of the current shell is usually kept in RAM until the shell instance exits, and only then synced to the history file. So, erasing the history file does not immediately affect the history of your current shell instance, and consequently the output of the history command.
    – AdminBee
    21 hours ago
  • @AdminBee right, my bad. I will add it to my answer
    – serax
    13 hours ago

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.