Skip to content

Instantly share code, notes, and snippets.

@petethepig
Last active March 7, 2024 03:46
Show Gist options
  • Save petethepig/2d29e8b7e2ebc808bfe760b632608966 to your computer and use it in GitHub Desktop.
Save petethepig/2d29e8b7e2ebc808bfe760b632608966 to your computer and use it in GitHub Desktop.
Alert yourself after a long-running task in terminal

Alert yourself after a long-running task in terminal

For the last few months I've been working on pyroscope, I’ve often found myself getting distracted when I run any long tasks in the terminal (tests / docker builds).

This little snippet helps me get back to what I was doing in the terminal by alerting me via a sound message and also a macOS notification.

demo

Instructions

Step 1. Install terminal-notifier:

brew install terminal-notifier

Step 2. Add the following code to .bash_profile:

# Open ~/.bash_profile and add these functions:

function timer_start {
  timer=${timer:-$SECONDS}
}

# this makes bash run timer_start every time you run a command
trap 'timer_start' DEBUG

function notify_when_done {
  timer_show=$(($SECONDS - $timer))
  unset timer
  # 10 is the notification threshold in seconds
  if (( ${timer_show} > 10 )); then
    # modify this section to fit your needs:
    say "Done with task"
    terminal-notifier -title "Terminal" -message "Done with task! Exit status: $? Time: ${timer_show}s"
  fi
}

# this makes bash run notify_when_done command after every command
if [ "$PROMPT_COMMAND" == "" ]; then
  PROMPT_COMMAND="notify_when_done"
else
  PROMPT_COMMAND="$PROMPT_COMMAND; notify_when_done"
fi

Update: for information on how to set this up on Linux or with other shells (fish / zsh) see Hacker News comments.

@bertrand-caron
Copy link

bertrand-caron commented Feb 26, 2021

My version for zsh, that excludes long-running commands like vim, etc.:

### Source: https://gist.github.com/petethepig/2d29e8b7e2ebc808bfe760b632608966
function timer_start {
  timer=${timer:-$SECONDS}
}

# this makes bash run timer_start every time you run a command
trap 'timer_start' DEBUG

function notify_when_done {
  timer_show=$(($SECONDS - $timer))
  unset timer
  # 15 is the notification threshold in seconds
  if (( ${timer_show} > 15 )); then
    # modify this section to fit your needs:
    printf \\a
    terminal-notifier -title "Terminal" -message "Done with task $1! Exit status: $? Time: ${timer_show}s"
  fi
}

# export command we are about to run, so we can inject it in the notification once done
preexec() {
	export _CMD=$1
}
# this makes zsh run notify_when_done command after every command
precmd() {
    if ! [[ ${_CMD} =~ '^(v|vim|ssh|gc|gs|gd) ' ]] {
	    notify_when_done ${_CMD}
    }
}
### END

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment