Skip to content

Instantly share code, notes, and snippets.

@ryangreenberg
Last active December 22, 2015 19:58
Show Gist options
  • Save ryangreenberg/eb725206c9e59cf261d6 to your computer and use it in GitHub Desktop.
Save ryangreenberg/eb725206c9e59cf261d6 to your computer and use it in GitHub Desktop.
tellme: A simple wrapper to execute commands and provide notification of the results
#!/bin/bash
# Executes the provided command and provides notification when execution has
# completed
#
# Usage: tellme <cmd>
#
# Examples:
#
# tellme ./pants compile science::
# tellme curl http://example.com/giant_file
#
# Settings are controlled by environment variables (instead of flags) to
# simplify running the provided command.
#
# Control which forms of notification you want by setting the environment
# variables TELLME_SUCCESS and TELLME_FAILURE to a comma-separated list of the
# following values:
#
# - bell: output the bell character (^G) in the terminal
# - beep: play the system alert sound
# - notification_center: show a message in OS X's Notification Center
# - play: play the sound file at the provided path (play /foo/bar/baz.wav), or
# play a random file in the provided directory. The file must be a format
# supported by `afplay`.
# - say: use the `say` command to speak the subsequent string
#
# Examples:
#
# TELLME_SUCCESS="say Command exited successfully,play $HOME/crowd_cheering.wav"
# TELLME_SUCCESS="notification_center,play --volume 0.25 $HOME/nbajam_heating_up.wav"
# TELLME_FAILURE="beep,say,notification_center"
# TELLME_FAILURE="say --voice Cellos What you started has ended in failure"
#
# If you configure your defaults in a shell file (.bashrc, .zshrc) remember to
# export the values:
#
# export TELLME_SUCCESS="..."
tellme_success=${TELLME_SUCCESS-say Success,notification_center}
tellme_failure=${TELLME_FAILURE-beep,say Failure,notification_center}
default_success_msg=Success
default_failure_msg=Failure
## ACTION HANDLERS ##########################################################
# Runs the provided command using `afplay`. This function assumes that the
# last argument is a file name or directory. If it is a directory, a random
# file is selected from within that directory.
function background_play() {
local cmd=("$@")
# OS X uses an old version of bash which does not support cmd[-1]
# See http://unix.stackexchange.com/questions/198787
local file="${cmd[${#cmd[@]}-1]}"
if [[ -d $file ]]; then
unset cmd[${#cmd[@]}-1]
cmd+=($(random_file $file))
fi
(afplay "${cmd[@]}" &)
}
function background_say() {
(say $@ >/dev/null 2>&1 &)
}
function beep() {
osascript -e "beep 1"
}
function bell() {
tput bel
}
function notification_center() {
local title=$1
local msg=${@:2}
osascript -e "display notification \"$msg\" with title \"$title\""
}
## HELPERS ##################################################################
function strip() {
local to_strip=$1
echo "${@:2}" | sed "s/$to_strip[ =]//"
}
# Select a random file from the specified directory
function random_file() {
local dir=$1
files=($dir/*)
local num_files=${#files[@]}
# See http://stackoverflow.com/questions/2388488
RANDOM=$$$(date +%s)
selected_file=${files[$RANDOM % $num_files]}
echo $selected_file
}
## "main" ###################################################################
# Run the provided command
cmd="$@"
"$@"
result=$?
escaped_cmd=$(echo $cmd | sed 's/\"/\\"/g')
# Select actions based on success or failure
if [[ $result -eq 0 ]]; then
actions=$(echo $tellme_success | sed -E "s/say(,)|say$/say $default_success_msg\1/")
else
actions=$(echo $tellme_failure | sed -E "s/say(,)|say$/say $default_failure_msg\1/")
fi
# Process actions
echo $actions | tr ',' '\n' | while read action; do
case "$action" in
say*)
background_say $(strip say $action)
;;
notification_center*)
notification_center "Command result" $escaped_cmd
;;
bell*)
bell
;;
beep*)
beep
;;
play*)
background_play $(strip play $action)
;;
esac
done
exit $result
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment