Zsh Command Execution Time Notification Plugin

July 19, 2026 ยท View on GitHub

A Zsh plugin that automatically calculates the execution time of commands. If a command runs longer than a given threshold, it notifies you with the command's name (arg0), execution time, and exit code.

Notifications are delivered via:

  1. OSC Escape Sequences (OSC 9 and OSC 777), which are natively supported by modern terminal emulators like iTerm2, Windows Terminal, Kitty, WezTerm, foot, and urxvt to show native system notifications.
  2. An External Command (configured via ET_NOTIFY_COMMAND), which is executed asynchronously in the background.

Features

  • Automatic Hooking: Seamlessly integrates using standard Zsh hooks (preexec and precmd).
  • Precision Time Measurement: Uses $EPOCHREALTIME to measure duration with microsecond precision.
  • Smart Command Parsing: Extracts the exact executable name (arg0 only) by skipping environment variable overrides and stripping path prefixes.
  • Custom Threshold: Configurable notification threshold in milliseconds.
  • Asynchronous External Notifications: Run custom notifications, Slack hooks, or scripts without locking up your shell prompt.

Installation

Manual

  1. Clone or download this repository.
  2. Add the following line to your ~/.zshrc:
    source /path/to/execution-time.plugin.zsh
    

Using Oh My Zsh

  1. Clone this repository into your custom plugins directory:
    git clone https://github.com/yourusername/execution-time.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/execution-time
    
  2. Enable it by adding execution-time to your plugins list in ~/.zshrc:
    plugins=(... execution-time)
    

Configuration

You can configure the behavior of the plugin by setting the following environment variables in your ~/.zshrc before or after loading the plugin:

ET_NOTIFY_TIMEOUT (msec)

The threshold duration in milliseconds. A notification is triggered only if the command runs longer than this threshold.

  • Default: 5000 (5 seconds)
  • Example:
    # Notify for commands taking longer than 2 seconds (2000 ms)
    ET_NOTIFY_TIMEOUT=2000
    

ET_NOTIFY_OSC9 and ET_NOTIFY_OSC777

Notify the user via OSC9 and OSC777 escape sequence. The terminal should support it.

  • Default: empty; no notifications through OSC9 and OSC777
  • Example:
    # Notify the user via OSC9 escape sequence
    ET_NOTIFY_OSC9=yes
    

ET_NOTIFY_COMMAND

An optional external shell command/command string to run when a command exceeds the threshold. This command is executed asynchronously (non-blocking) in a background subshell.

To allow custom notification formats, the plugin exports the following environment variables to the command context:

  • ET_COMMAND: The name of the command executed (arg0 only).
  • ET_ELAPSED: The exact duration in milliseconds (integer).
  • ET_EXIT_CODE: The exit status of the command.
  • ET_DURATION_STR: The duration formatted cleanly (e.g. 2.50s or 450ms).
  • ET_MESSAGE: A pre-formatted message: <arg0>: Took <duration> (exit: <exit_code>).

Examples

Using notify-send (Linux):

ET_NOTIFY_COMMAND='notify-send "Command Finished: $ET_COMMAND" "Took $ET_DURATION_STR (exit: $ET_EXIT_CODE)"'

Using osascript (macOS):

ET_NOTIFY_COMMAND='osascript -e "display notification \"Took $ET_DURATION_STR (exit: $ET_EXIT_CODE)\" with title \"Finished: $ET_COMMAND\""'

Triggering a script with arguments:

ET_NOTIFY_COMMAND='/path/to/my-notifier.sh "$ET_COMMAND" "$ET_ELAPSED" "$ET_EXIT_CODE"'

Testing

To run the plugin's test suite, execute:

zsh test_plugin.zsh