This command line timer should run on any unix and has been tested on linux and Mac OS X.
Here is an example run, and following is a discussion of the script's internals for those interested...
Space for lap | ? for split | Ctrl-C to stop | Space to start... 1.28 (1) 3.15 (2) 2.39 (3) 6.87This shell script has an unusual requirement in that it must respond immediately to a user at a terminal, entering 3 separate inputs (stop, lap, split). As I see it, there are 2 options to do that, "raw" mode and signals.
Raw ModeSetting the terminal into raw mode, where characters are immediately progagated up to the application is problematic because if you hit the arrow keys for example, multiple characters will be present in the input buffer, which will cause the loop to execute multiple times. Dear lazy web, is there any way to clear the input buffer in a shell script?
while true; do echo -n "Hit a key: " stty raw char=`dd if=/dev/tty bs=1 count=1 2>/dev/null` stty -raw echo -e "\ngot [$char]" done
SignalsI went with this option because it maps explicit keys to operations, rather than responding to any key as in raw mode. Also it doesn't change the terminal away from its default "cooked" mode. We need 3 separate user inputs as mentioned above and neatly there are 3 interrupts that can be generated by a user at a terminal: SIGTSTP (^Z), SIGINT (^C) and SIGQUIT (^\). Now we also want the signals to terminate a process, since timing the run length of a process is the method I used to obtain lap times. I couldn't get SIGTSTP to do this, so I used ^C, ^\ and ^D with the `cat` program.
Note there is an issue where "eof" (^D), since it doesn't actually generate a signal, it is ignored unless it's on a new empty line (or is entered twice). Also since "eof" (^D) doesn't generate an signal, there may be an extra delay in processing on heavily loaded systems where this script and its subprocesses take a while to be scheduled. In general on heavily loaded systems, one can get better response by running the script using the sudo nice -n-20 sw command. Talking about delays, SIGQUIT (^\) can also have delayed processing on ubuntu due to this bug.
Now ^\ and ^D etc. are awkward to type, so one can map the actual characters used to generate these on a terminal using the `stty` command. This is illustrated in the example script using the signalling method below:
ulimit -c 0 #no cores from SIGQUIT trap '' SIGTSTP #ignore Ctrl-Z save_tty=`stty -g` && trap "stty $save_tty" EXIT #restore tty on exit stty quit ' ' #space for laps rather than Ctrl-\ stty eof '?' #? for splits rather than Ctrl-D stty -echo #don't echo input echo "space for lap | ? for split | Ctrl-C to stop" while true; do cat >/dev/null echo "got [$?]" done