2

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
7
  • What do you mean by "my timestamp formatting is not being leveraged"? Could you simply post what are the expected and actual results, to show the difference? Besides, do you mean to attain what is stated in the title by whatever means (e.g., precmd), or do it specifically with oh-my-zsh? Nov 12 '20 at 8:31
  • The format I am aiming for is stated in the question. i.e. bash-history-2020-11-15.log
    – rsmets
    Nov 16 '20 at 0:11
  • Yes, you mention what you want. Then you say "... certainly does write to the .logs directory in a file named the date...", so it appears to me that you are getting what you want. But then you say "... however...". It is not clear to me how does the result differ from what you want, and that is why I asked you to post specifically the result you get (to me, "my timestamp formatting is not being leveraged" wasn't clear). And I asked a last question about oh-my-zsh, which I don't see clarified. I look forward to your clarifications to add extra info. Nov 16 '20 at 11:33
  • To answer your second question of the first comment: I just want to zsh logs in files with a date naming scheme by any means possible. I reference 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.
    – rsmets
    Nov 17 '20 at 16:32
  • @sancho.sReinstateMonicaCellio Just updated the question with a ton more detail. I couldn't fit all the text in this comment. Thanks for pushing for more info. The question did get a little long now which I worry will scare some individuals off but grateful for your time and energy justing to help me out!
    – rsmets
    Nov 17 '20 at 16:44
0

I am not certain what is the problem you are seeing.

In bash, a convenient structure to get a generic command working as prompt is (see also this)

function prompt_command {
  export PS1=$(~/bin/bash_prompt)
}
export PROMPT_COMMAND=prompt_command

and then write a script (in bash, perl, ruby, etc.), and place it in ~/bin/bash_prompt.

In zsh, you could use any of the options here. Perhaps your problem lays in the usage of quotes and double quotes.

Related:

  1. https://unix.stackexchange.com/questions/479592/zsh-consistent-history-between-machines
  2. https://unix.stackexchange.com/questions/432379/in-zsh-where-are-precmd-functions-defined
3
  • Thank you for the response but I already referenced the related precmd post in the question.
    – rsmets
    Nov 15 '20 at 23:54
  • @rsmets - I know you referenced use of precmd, but: 1) The post you linked is not the same as those I linked, and they may contain other relevant info. 2) I was specifically suggesting you check usage of quotes, either in precmd or other forms. I suggest you do not dump an answer or comment (either this one or another) just because there is a common "theme" with something you had already checked before. You might be overlooking the solution you are looking for. I look forward to your clarifications. Nov 16 '20 at 11:38
  • Thanks again for the suggestion. I will double check!
    – rsmets
    Nov 17 '20 at 16:46

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.