Log Your Entire ZSH History

Previously, I wrote a blog post called How (and Why) to Log Your Entire Bash History. A few years ago, I switched from bash to zsh, and in doing so realized that my bash technique was no longer applicable.

I needed to find a new way to log every command to files corresponding to the date they were executed.

Zsh History Configuration

zsh itself has a number of configuration options for fine tuning control of its built-in history functionality.

As pointed out in a comment on my original post, this Stack Overflow answer indicates that it’s possible to configure zsh to save every command before it’s executed, and to read the history file every time history is accessed:


  setopt inc_append_history
  setopt share_history

This allows for the sharing of the built-in zsh history across terminals/sessions with zsh. And that’s great – but it doesn’t help with my desire for daily logs of commands that have been executed.

Zsh Hooks

My bash solution was to append the previous command to a file as part of the PROMPT_COMMAND variable. Another commenter on my original post suggested that it’s possible to do the same in zsh by using the preexec hook.

The Mastering ZSH book has the following description of the preexec hook:

preexec is executed between when you press enter on a command prompt but before the command is executed.

By adding the following to my .zshrc file, I was able to reproduce the same functionality I had in bash.


  preexec () {
    local fmt_date="$(date +'%Y-%m-%d.%H:%M:%S')" >& /dev/null
    echo "${fmt_date} \"${PWD}\" $1" >> ~/.logs/zsh-history-$(date "+%Y-%m-%d").log
  }

Conclusion

I’ve now been storing every single command to daily log files for over 12 years. There have been countless times when I’ve gone spelunking in those logs to try to piece together something I had done in the past. I know there are more sophisticated ways to do this – but the simplicity of this approach has worked well for me.

Conversation

Join the conversation

Your email address will not be published. Required fields are marked *