Clearing and Restoring Your Current and Saved Shell History with Zsh
You may want to do this before recording videos, giving presentations at work, demoing something for clients or live streaming.
My dotfiles have evolved over time. A while back I converted a bunch of aliases into dedicated scripts to make them more portable.
(2) of those scripts are related to helping me quickly start and stop recording videos which does a number of things such as modifying my terminal’s font size but most importantly it handles temporarily clearing and restoring my shell history. That helps me avoid accidentally sharing private commands related to client work.
Back when it was an alias, everything was fine because running the alias
affects your current shell. That’s perfect because I want to run
start-recording
and have my current shell’s history cleared. I don’t want to
have to open a new terminal window. Likewise stop-recording
should return my
history back to normal without needing to open a new terminal.
Now that they’re dedicated scripts, we have to find another way to modify the current shell.
# Current Shell
I did this to clear and restore the history from my shell using zsh:
# When starting to record...
HISTSIZE="0"
# When stopping the recording...
HISTSIZE="${SAVEHIST}"
fc -R
Both env variables are set in my .zshrc
file
and they are standard shell environment variables.
HISTSIZE
is the number of history lines stored in memory. Changing that to 0
immediately removes them so that if you hit CTRL+r
it will be empty.
However when restoring it, setting it back to 50000 or whatever you have
defined in your ${SAVEHIST}
which is the max number of commands in your
history requires also running fc -R
(zsh only) to read your history from a
given file in your current shell. You can find that detail in man zshbuiltins
.
That’s great but this doesn’t work if the above is inside of a script, not an alias. The script’s sub-shell will have the modifications done, not your current shell.
You can technically source the script instead of running it but you have to
jump through a few hoops if you want to make it compatible with both bash and
zsh, and chances are you’ll still want an alias because typing . start-recording
isn’t intuitive (at least not to me).
We’re going to go over how to address that in a few but first let’s talk about “really” clearing your history’s file on disk and restoring it afterwards.
# Saved History
For my specific use case I also wanted to clear my history file on disk while recording so if I open a new shell session such as a tmux window or pane it will have the cleared history. Then when I stop recording I wanted to restore my history from a backup.
That was easy enough to pull off:
# When starting to record...
cp "${HISTFILE}" "${HISTFILE}.bak"
rm "${HISTFILE}"
# When stopping the recording...
cp "${HISTFILE}.bak" "${HISTFILE}"
This takes the safer route vs mv
because I want there to be a 0% chance I ever
accidentally delete my shell’s history. I also go as far as leaving the .bak
file around just in case as a last resort insurance policy.
Now when new shell sessions are opened everything is good to go, but we still
have the problem of our current shell not having the changes reflected when the
HISTSIZE
values are changed in a script.
# Combining Scripts and Aliases
I ended up going with:
alias start-rec="start-recording && HISTSIZE=0"
alias stop-rec="stop-recording && HISTSIZE=${SAVEHIST} && fc -R"
The real scripts
handle most of the work while the alias handles adjusting your current shell.
It’s still not perfect because fc -R
only works with zsh but I use zsh. I do
try to make all of my scripts compatible with Bash but history -r
didn’t work
in zsh.
Perhaps a better solution exists but for now it works.
# Demo Video
Timestamps
- 1:07 – Showing my history normally and how I usually clear / restore it
- 2:41 – Clearing and restoring your current shell’s history (zsh)
- 3:59 – Showing my history related settings
- 4:57 – What about when you open a new shell?
- 5:29 – Temporarily clearing and restoring your history on disk
- 7:10 – Clearing the current shell in a separate script won’t work as is
- 8:35 – Creating aliases to do both at once
- 9:20 – I encourage you to open a PR if you want to make it work with bash too
- 9:36 – Investigating the man pages for zshbuiltins
References
How have you solved this problem? Let me know below.