#!/bin/bash function helpexit() { echo "Simple Timer." echo '$PREFIX is printed before the time' echo '$POSTFIX is printed after the time' echo '$TIMERPID is a PID number. When the process ends, timer ends.' echo 'Reset timer with kill -10' echo ' # use cases: # timer | sleep 10 # # timer & # sleep 10; kill -10 %1; sleep 5; kill %1 # # PREFIX=$'"'"'\033[33;1m'"'"' POSTFIX=$'"'"'\033[0m'"'"' timer | sleep 5 # # sleep 4 & # p=$! # TIMERPID=$p timer & # sleep 10 ' exit } for (( i=1; i<=$#; i++ )); do [[ "${!i}" = "--help" ]] && helpexit [[ "${!i}" = "-h" ]] && helpexit done function displaytime { local T=$1 local D=$((T/60/60/24)) local H=$((T/60/60%24)) local M=$((T/60%60)) local S=$((T%60)) printf '\r%s[' $PREFIX (( $D > 0 )) && printf '%dd ' $D (( $T > 3599 )) && printf '%02d:' $H printf '%02d:%02d]%s\r' $M $S $POSTFIX } function finish_up { echo "Timer terminated" >&2 displaytime "$SECONDS" >&2 echo "" >&2 exit } function reset { STARTED=$SECONDS } trap finish_up EXIT 9 15 trap reset 10 STARTED=$SECONDS while true; do # Were in terminal if [[ -t 1 ]]; then printf '\033[s'; fi displaytime $(( SECONDS - STARTED )) >&2 if [[ -t 1 ]]; then printf '\033[u'; fi # die if parent dies kill -0 $PPID 2>/dev/null || { exit; } # if stdout is pipe, print time there # if pipe dies, timer dies too if [[ ! -t 1 ]]; then displaytime "$SECONDS"; fi if [[ -n "$TIMERPID" ]]; then kill -0 "$TIMERPID" 2>/dev/null || { exit; } fi sleep 1 done