Learn Docker With My Newest Course

Dive into Docker takes you from "What is Docker?" to confidently applying Docker to your own projects. It's packed with best practices and examples. Start Learning Docker →

Clearing and Restoring Your Current and Saved Shell History with Zsh

blog/cards/clearing-and-restoring-your-current-and-saved-shell-history-with-zsh.jpg

You may want to do this before recording videos, giving presentations at work, demoing something for clients or live streaming.

Quick Jump: Current Shell | Saved History | Combining Scripts and Aliases | Demo Video

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.

Never Miss a Tip, Trick or Tutorial

Like you, I'm super protective of my inbox, so don't worry about getting spammed. You can expect a few emails per month (at most), and you can 1-click unsubscribe at any time. See what else you'll get too.



Comments