简体   繁体   中英

Create custom accept-line to measure time taken by a command to run in zsh

I want to measure the time taken by a program to run in zsh. Based on the time difference, I want to print out the time taken. I edited the accept-line hook function for this:

my-accept-line () {
  CMD="$BUFFER"
  CMDSTART=$(date +%s)
  zle accept-line
  CMDRUNTIME=$((($(date +%s)-${CMDSTART})))
  if [[ $CMDRUNTIME -ge 100 ]]; then
    CMDRUNTIME_min=$(($CMDRUNTIME/60))
    echo "Last command ran for $CMDRUNTIME_min minutes."
  fi
}

# create a widget from `my-accept-line' with the same name
zle -N my-accept-line
# rebind Enter, usually this is `^M'
bindkey '^M' my-accept-line

But, the problem is that "zle accept-line" seems to run in the background. Because of that, I always end up getting CMDRUNTIME as 0. Is there a workaround for this?

You'd be better off doing this using the preexec and precmd zsh hooks.

Here's a little example (untested):

function pre_exec() {
  cmd_timestamp=$((EPOCHREALTIME*1000))
}

function pre_cmd() {
  local stop=$((EPOCHREALTIME*1000))
  local start=${cmd_timestamp:-$stop}
  local elapsed=$stop-$start
  (($elapsed > 0)) && echo $elapsed
  unset cmd_timestamp
}

zmodload zsh/datetime
autoload -Uz add-zsh-hook
add-zsh-hook precmd pre_cmd
add-zsh-hook preexec pre_exec

That will print the time it took to run the command in milliseconds before your prompt - you can alter the pre_cmd function to format this however you want.

For a more fully-featured example, look at the source of filthy , my ZSH prompt theme, which prints command timestamps in the prompt if they go over a threshold (default 500ms).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM