typingbreak

A typing break reminder Bash script, plain text, no-fuss, KISS

Usage

typingbreak [B] [S]

With default settings the script will print every 2 minutes the current time and the number of minutes left until the next break. It will beep after B minutes, and make more noise after B+S.

 press r to have typingbreak restart itself (resets the counter)
 press s to have typingbreak snooze (adds S minutes to B)
 press +/- to adjust B up or down by 1 minute
 
 press ^C to kill the script

Defaults for B (47) and S (9) are set in the script or optionally in a conf file.

The script

typingbreak.sh
#!/bin/bash
#
me=typingbreak
#
# plain text no-fuss typing break reminder script
#
prgversion="$me * 2017-07-30 (c) Andreas Schamanek"
#
usage=\
"
$prgversion
 
   $me [B] [S]
 
      beep after B minutes, make more noise after B+S
 
        press r to have typingbreak restart itself
        press s to have typingbreak snooze (adds S minutes to B)
        press +/- to adjust B up or down by 1 minute
 
        press ^C to kill the script
"
 
[[ $1 != -h && $1 != --help ]] || { echo "$usage"; exit 0; }
 
# defaults
: ${beepafter:=${1:-47}}  # B
: ${seriously:=${2:-10}}  # S
: ${quitafter:=$((beepafter+(2*seriously)))} # quit script after $quitafter
: ${terse:=no}            # terse format: "time $passed/$beepafter: $left"
: ${curt:=no}             # curt format: "$left"
: ${datetimef='%H:%M'}    # date(1) format string for current time
 
# functions beep() and seriously() define the actions to get attention
beep() { echo -ne "\a"; }
if [[ -r ~/.typingbreak.wav ]] ; then
   seriously() {
      printf '%b' "$text4seriously"
      aplay ~/.typingbreak.wav 2>/dev/null
   }
else
   seriously() {
      printf '%b' "$text4seriously"
      beep; sleep 2; beep; sleep 2; beep
   }
fi
# Other examples ;-)
#seriously() { echo "OK, I'll call your SO!"; send_sms lover "Pull the plug! Now!"; }
#seriously() { echo "You've been warned."; sleep 47; ssh server ups poweroff; }
 
: ${sleepinterval:=120}}             # seconds to sleep between status updates
: ${red:=$(tput bold;tput setaf 1)}  # color used to highlight alarm status
: ${normal:=$(echo -e "\e[0m")}      # reset text color
 
# text and format to use in various modes
if [[ $terse == no && $curt == no ]] ; then
   output() { echo -n "[$(date +$datetimef)] Of $beepafter minutes $passed passed, $left left"; }
   output4quit() { echo "[$(date +$datetimef)] I quit"; }
   text4seriously="Seriously, take a break!\n"
elif [[ $curt == no ]] ; then
   output() { echo -n "[$(date +$datetimef)] $passed/$beepafter: $left"; }
   output4quit() { echo "[$(date +$datetimef)] I quit"; }
   text4seriously="Take a break!\n"
else
   output() { echo -n "$left"; }
   output4quit() { echo ':-X'; }
   text4seriously=""
fi
 
set -eu
passed=0; left=$beepafter; SECONDS=0
 
# read conf file if it exists
[[ ! -r $0.conf ]] || . "$0.conf"
 
while true ; do
   (( left <= 0 )) && echo -n "$red"
   output # print date/time $passed $left etc.
   echo "$normal"
 
   read -s -N1 -t$sleepinterval key || true
   case $key in
      r) # restart counters if r was pressed
         clear; passed=0; left=$beepafter; SECONDS=0; continue;;
      s) # snooze: provide $seriously more minutes
         beepafter=$((beepafter+seriously)); quitafter=$((quitafter+seriously));;
      # adjust remaining time up or down by 1 minute
      \+) beepafter=$((beepafter+1)); quitafter=$((quitafter+1));;
      \-) beepafter=$((beepafter-1)); quitafter=$((quitafter-1));;
   esac
 
   passed=$((SECONDS/60)); left=$((beepafter-passed))
 
   (( (left+seriously) <= 0 )) && seriously || { (( left <= 0 )) && beep ; }
 
   (( passed > quitafter )) && output4quit && { read -s -N1 key; exit 1; }
done

(Click on "typingbreak.sh" to download.)