1 # Simple bourne shell based stopwatch
2 # Requires 'kvs' and the id 'stopwatch' therein
3 # so make sure you set 'kvs' before sourcing this script if necessary.
5 # After loading, the following commands are available:
8 # stopwatch <tag> start
14 # stopwatch <tag> stop
17 # stopwatch <tag> reset
20 if [ -z "${__stopwatch_sh_loaded}" ]
22 __stopwatch_sh_loaded=yes
24 [ "${kvs}" ] || kvs="$(mktemp -t ".stopwatch.XXXXXXXX")"
28 echo "Usage: stopwatch <tag> <start|lap|stop|reset>" >&2
32 # Try and format a passed integer number of seconds into something more
33 # useful (like 6m10s or something)
34 _stopwatch_timefmt() {
35 local secs mins hurs days
36 [ "${1}" -a "$(echo "${1}" | tr -Cd '0-9')" = "${1}" ] || return 255
40 [ "${secs}" -lt 60 ] || {
41 mins=$(( ${secs} / 60 ))
42 secs=$(( ${secs} % 60 ))
44 [ "${secs}" -gt 0 ] || secs=""
45 [ "${mins}" -lt 60 ] || {
46 hurs=$(( ${mins} / 60 ))
47 mins=$(( ${mins} % 60 ))
49 [ "${mins}" -gt 0 ] || mins=""
50 [ "${hurs}" -lt 24 ] || {
51 days=$(( ${hurs} / 24 ))
52 hurs=$(( ${hurs} % 24 ))
54 [ "${hurs}" -gt 0 ] || hurs=""
56 [ "${days}" -o "${hurs}" -o "${mins}" -o "${secs}" ] || printf "0s"
57 printf "%s%s%s%s" "${days:+${days}d}" "${hurs:+${hurs}h}" "${mins:+${mins}m}" "${secs:+${secs}s}"
60 # Start a named stopwatch, but do nothing if the named stopwatch is already
63 name="${1:-stopwatch}"
64 [ "${nao}" ] || nao="$(date +%s)"
65 # Is the stopwatch running?
66 if kvs_has_key stopwatch "${name}"
68 printf "Stopwatch: %s is already running.\n" "${name}"
71 accum="$(kvs_get stopwatch "${name}_accumulator")"
72 kvs_set stopwatch "${name}" "${nao}"
73 [ "${accum}" ] && restart="$(printf " at %s." "$(_stopwatch_timefmt "${accum}")")"
74 printf "Stopwatch: %s starts running%s.\n" "${name}" "${restart}"
78 # 'Lap' the named stopwatch: print out a line indicating how long the named
79 # stopwatch has been running, but do not stop nor reset the stopwatch.
81 name="${1:-stopwatch}"
82 [ "${nao}" ] || nao="$(date +%s)"
83 # Is the stopwatch running?
84 if kvs_has_key stopwatch "${name}"
86 # emit a line indicating how long it has been running
87 start="$(kvs_get stopwatch "${name}")"
88 accum="$(kvs_get stopwatch "${name}_accumulator")"
89 delta="$(( ${nao} - ${start} ))"
90 [ "${accum}" ] && delta="$(( ${delta} + ${accum} ))"
91 printf "Stopwatch: %s is running at %s.\n" "${name}" "$(_stopwatch_timefmt "${delta}")"
93 accum="$(kvs_get stopwatch "${name}_accumulator")"
94 [ "${accum}" ] && printf "Stopwatch: %s is stopped at %s.\n" "${name}" "$(_stopwatch_timefmt "${accum}")"
98 # Stop the named stopwatch and print out a line indicating how long it had
99 # been running up until that point; do not reset the stopwatch.
101 name="${1:-stopwatch}"
102 [ "${nao}" ] || nao="$(date +%s)"
103 if kvs_has_key stopwatch "${name}"
105 start="$(kvs_get stopwatch "${name}")"
106 accum="$(kvs_get stopwatch "${name}_accumulator")"
107 delta="$(( ${nao} - ${start} ))"
108 [ "${accum}" ] && delta="$(( ${delta} + ${accum} ))"
109 kvs_set stopwatch "${name}_accumulator" "${delta}"
110 kvs_unset stopwatch "${name}"
111 printf "Stopwatch: %s stops running at %s.\n" "${name}" "$(_stopwatch_timefmt "${delta}")"
113 accum="$(kvs_get stopwatch "${name}_accumulator")"
114 [ "${accum}" ] && printf "Stopwatch: %s is already stopped at %s.\n" "${name}" "$(_stopwatch_timefmt "${accum}")"
118 # Reset the named stopwatch back to zero.
120 name="${1:-stopwatch}"
121 [ "${nao}" ] || nao="$(date +%s)"
122 kvs_unset stopwatch "${name}"
123 kvs_unset stopwatch "${name}_accumulator"
124 printf "Stopwatch: %s is reset to 0s.\n" "${name}"
128 [ "${1}" -a "${2}" ] || stopwatch_help;
131 [Ss][Tt][Aa][Rr][Tt]) stopwatch_start "${1}" ;;
132 [Ll][Aa][Pp]) stopwatch_lap "${1}" ;;
133 [Ss][Tt][Oo][Pp]) stopwatch_stop "${1}" ;;
134 [Rr][Ee][Ss][Ee][Tt]) stopwatch_reset "${1}" ;;