astroboylrx astroboylrx - 2 months ago 11x
Bash Question

Save Zsh history to ~/.persistent_history

Recently I want to try Z shell in Mac. But I'd like to continue also saving the command history to ~/.persistent_history, which was what I did in Bash (ref).

However, the script in the ref link doesn't work under Zsh:

$(history 1) =~ ^\ *[0-9]+\ +([^\ ]+\ [^\ ]+)\ +(.*)$
local date_part="${BASH_REMATCH[1]}"
local command_part="${BASH_REMATCH[2]}"
if [ "$command_part" != "$PERSISTENT_HISTORY_LAST" ]
echo $date_part "|" "$command_part" >> ~/.persistent_history
export PERSISTENT_HISTORY_LAST="$command_part"

Is there anyone who can help me get it working? Many thanks!


After so much Googling, I finally found out the way to do this. First, in ~/.zshrc, add the following options for history manipulation:

setopt append_history # append rather then overwrite
setopt extended_history # save timestamp
setopt inc_append_history # add history immediately after typing a command

In short, these three options will record every input_time+command to ~/.zsh_history immediately. Then, put this function into ~/.zshrc:

precmd() { # This is a function that will be executed before every prompt
    local date_part="$(tail -1 ~/.zsh_history | cut -c 3-12)"
    local fmt_date="$(date -d @${date_part} +'%Y-%m-%d %H:%M:%S')"
    # For older version of command "date", comment the last line and uncomment the next line
    #local fmt_date="$(date -j -f '%s' ${date_part} +'%Y-%m-%d %H:%M:%S')"
    local command_part="$(tail -1 ~/.zsh_history | cut -c 16-)"
    if [ "$command_part" != "$PERSISTENT_HISTORY_LAST" ]
        echo "${fmt_date} | ${command_part}"  >> ~/.persistent_history
        export PERSISTENT_HISTORY_LAST="$command_part"

Since I use both bash and zsh, so I want a file that can save all their history commands. In this case, I can easily search all of them using "grep".