My biggest sticking point moving from bash to zsh is the history configuration. Using oh-my-zsh there is a history.zsh file in #ZSH/lib that I found (I think) can be disabled via unsetopt share_history
in .zshrc.
I want to just mimic my bash history setup that uses PROMPT_COMMAND bash env that runs after each interactive action (command entered). I found here that zsh has a hook called precmd
that is somewhat similar.
Below is my custom bash history setup that writes history to the ~/.logs directory in files of the current date, i.e. bash-history-2020-10-27.log
# Saving history to file
export PROMPT_COMMAND='if [ "$(id -u)" -ne 0 ]; then echo "$(date "+%Y-%m-%d.%H:%M:%S") $(pwd) $(history 1)" >> ~/.logs/bash-history-$(date "+%Y-%m-%d").log; fi'
export HISTSIZE=100000
export HISTTIMEFORMAT="%d/%m/%y %T "
# Avoid duplicates
export HISTCONTROL=ignoredups:erasedups
# When the shell exits, append to the history file instead of overwriting it
#shopt -s histappend
# After each command, append to the history file and reread it
export PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND$'\n'}history -a; history -c; history -r"
The modified zsh version is shown below. This config lives in the $ZSH_CUSTOM directory.
# Saving history to file
setopt INC_APPEND_HISTORY
setopt EXTENDED_HISTORY
setopt HIST_FIND_NO_DUPS
setopt HIST_IGNORE_ALL_DUPS
unsetopt share_history
export HISTSIZE=1000000000
export HISTFILESIZE=1000000000
export HISTTIMEFORMAT="%d/%m/%y %T "
# Functions
precmd() { eval 'if [ "$(id -u)" -ne 0 ]; then echo "$(date "+%Y-%m-%d.%H:%M:%S") $(pwd) $(history 1)" >> ~/.logs/zsh-history-$(date "+%Y-%m-%d").log; fi' }
Which certainly does write to the .logs directory in a file named the date, i.e. zsh-history-2020-10-27.log
, however my timestamp and current directory formatting is not being leveraged from within the file, i.e.:
9 ls -a
10 vi .zshrc
11 cd Dev
12 ls
When the bash setup writes to the file like this:
2018-10-30.10:27:56 /Users/raysmets/dev/nexkey/nk-backend 201 30/10/18 10:27:56 git st
2018-10-30.10:27:59 /Users/raysmets/dev/nexkey/nk-backend 209 30/10/18 10:27:58 git log
2018-10-30.10:28:59 /Users/raysmets/dev/nexkey/nk-backend 202 30/10/18 10:28:59 git st
Furthermore while a dated file is created, the whole .zsh_history file is just being written and not incrementally the last command entered in the shell. What I mean is the shells logs from 10/28 contain all the logs from 10/27, which contains all the shell logs from 10/26... which is not ideal.
Curious if anyone more familiar with zsh & oh-my-zsh configs can help me? It would much appreciated! I love the flow of having timestamp shell logs written to calendar date files that I then use an aliased function to search over. In case anyone is interested here is the one I use in my bash setup:
alias s='search'
search() {
ls -rt ~/.logs/*.log | xargs grep -rnw "$1"
}
Also curious to hear about alternative zsh history setups that you would recommend and does a better jobs segmenting by date. Thank you!
My current work around is working ok, but still not ideal. I am using the native oh-my-zsh history functionality which has the time however it just dumping everything to a flat file and no current directory information.
alias s='search'
search() {
omz_history -i | grep "$1"
}
Which outputs results similar to:
2992 2020-11-13 15:56 terraform init
3000 2020-11-13 16:03 cd .terraform.d
3016 2020-11-13 16:24 mkdir terraform-modules
precmd
), or do it specifically with oh-my-zsh?bash-history-2020-11-15.log
precmd
because I looked at it extensively and couldn't make it work. However if there is another means I would love to try it.