zsh post command function/hook

Is there an equivalent of zsh's precmd for performing a function after a command has completed?

I'm looking for a way to send myself a notification for any process that takes over 60 seconds. Zsh has a great ability to print a summary of the resources used for each command if the command takes longer than the value set in REPORTTIME seconds. From what I can tell, the only available option is to print the format in TIMEFMT.

(More specifically, I'm looking to send myself a notification with https://pushover.net/ if any process running in a detached tmux session takes over 60 seconds to complete.)


Solution 1:

notify() {
  emulate -L zsh  # Reset shell options inside this function.

  # Fetch the last command with elapsed time from history:
  local -a stats=( "${=$(fc -Dl -1)}" )
  # = splits the string into an array of words.
  # The elapsed time is the second word in the array.

  # Convert the elapsed minutes (and potentially hours) to seconds:
  local -a time=( "${(s.:.)stats[2]}" )
  local -i seconds=0 mult=1
  while (( $#time[@] )); do
    (( seconds += mult * time[-1] ))
    (( mult *= 60 ))
    shift -p time
  done

  (( seconds >= 60 )) &&
      print -r -- "'$stats[3,-1]' took $time seconds"
  # Replace the `print` statement above with your notification call.

  return 0  # Always return 'true' to avoid any hiccups.
}

# Call the function above before each prompt:
autoload -Uz add-zsh-hook
add-zsh-hook precmd notify