#!/bin/bash ######################################## ## Rings buzzer (console beep) like crazy until keypress ## Usage: alarm [-t#] [message] ## If the first parameter begins with ONE dash, the number it contains ## will be the beep interval in seconds. ## Any other parameters are considered a message to display. ## You can change the action performed on the interval by setting $BEEP ## Default: alarm -t0.5 'ALARM, ALARM!! PRESS A KEY! ' ## ## alarm 0.4, Copyright (c) 2002-8 by Adam Katz , GPL2+ ######################################## # This script requires bash, sleep, and date. # GNU sleep allows decimal intervals, GNU date is more efficient. # A carriage return is required for older versions of bash. # just in case you've got your own beep program (like the Debian one) if [ -z "$BEEPER" ] then which beep >/dev/null 2>&1 && BEEPER=beep || BEEPER="printf \a" fi # toggle all LEDs to be more annoying (uncomment the three for just scroll lock) function BEEP() { nice -n19 xset led 3 "$BEEPER" nice -n19 xset -led 3 } # helper for non-GNU date # doesn't mimic %s, but it does give the day's time in seconds function ngDATE() { # hash notation forces base 10, since a leading 0 sets octal mode let "HOUR=10#`date +%H`" let "MIN=10#`date +%M`" let "SEC=10#`date +%S`" echo $((HOUR*3600+MIN*60+SEC)) unset HOUR MIN SEC } # determine if date understands %s, seconds since 1970 UTC # (currently a GNU-only ability) if date --help 2>&1 |grep "seconds since.*1970" >/dev/null then DATE='date +%s' else DATE=ngDATE fi # helper that beeps like crazy on given interval ($1, defaults to 0.01) function ALARM() { BEEP # look for interval parameter [ -n "$1" ] && T="${@//[-=a-zA-Z]/}" # T=`echo $1|sed s/[-a-zA-Z]//g` [ -z "$T" ] && T='0.5' # if sleep can't handle decimals, truncate (provide for non-GNU sleep) if ! sleep --help 2>&1 |grep floating >/dev/null; then T="${1/%.*/}" # T=`echo $T|sed "s/\..*$//"` # T is now empty if it started with a decimal point. fix: [ -z "$T" ] && T=0 fi case $TERM in # try to determine if we can print to the window's titlebar xterm* | vt100* |rxvt* |Eterm* ) began=`$DATE` w="seconds ago, interval of $T seconds" while true do [ "$T" = 0 ] || sleep $T # get current date as a number now=`$DATE` BEEP printf "\033]0;ALARM: started $((now-began)) $w\007" done ;; # default case (just beep) *) while true do sleep $T BEEP done ;; esac } # note - this function needs to be killed to stop if [ -n "$1" ] then echo $1|grep "^-*help" >/dev/null && \ grep '^## ' `which $0 2>/dev/null || echo $0`|sed 's/^..//' && exit 0 # --help # look for beep interval, take it out of $@ echo $1|grep "^-[\.0-9A-Za-z]" >/dev/null && T=$1 && shift fi # ensure read likes the -n# parameter read --help 2>&1 |grep "\-n " >/dev/null && \ nchar="-n1" && akey="A KEY" || akey="ENTER" [ "$@" ] && echo -n "$@" || printf "ALARM, ALARM!! PRESS $akey! " ALARM $T& PID="$!" # the most recent bg'd process (ALARM) trap "kill -9 $PID 2>&1|true; exit 0" 0 1 2 5 9 15 # stop alarm on exit or break # get keypress read $nchar nothing # if a letter was pressed, there was no linefeed. fix: [ -n "$nothing" ] && printf "\n" exit 0