My goal is to have a timer function that operates from the bash linux command line. I am looking for review and feedback. Printing the expected number of characters (dots, dashes, or bars) is nice-to-have, not a must-have.
For instance, I type "timer 10", and the function waits for 10 seconds before saying "timer complete". While it counts down, it outputs a single period "." for each second of the countdown.
So it would look like this:
$> timer 10
.......... timer complete
The code for that is:
function timer {
time=${1}
end=$((SECONDS+time))
while [ $SECONDS -lt $end ]; do
printf '.';
sleep 1;
done
echo ' timer finished.';
}
export -f timer
You could take it further to handle hours and minutes as well as seconds, and to use units (h, m, s). For hours, each dot would represent 5 min, and each hour would end in a "|". For minutes, each dot would represent 15 sec, and each minute would end in a "-".
So that would look like this:
$> timer 1 h 5 m 10 s
...........|
...-...-...-...-...-
.......... timer complete
I am having some trouble getting the expected number of dots to be printed to screen. I think it has something to do with my calculations of $((operation here)) slowing things down. Here is that code:
# 'counter' utility method:
# ie: counter 5 # wait 5 seconds
function counterSec {
time=${1}
end=$((SECONDS+time))
sleep 1;
while [ $SECONDS -lt $end ]; do
printf '.';
sleep 1;
done
}
export -f counterSec
# 'counter' utility method:
# ie: counter 5 # wait 5 minutes
function counterMin {
time=${1}
end1=$((SECONDS+(time*60)))
while [ $SECONDS -lt $end1 ]; do
end2=$((SECONDS+45))
while [ $SECONDS -lt $end2 ]; do
sleep 15;
printf '.';
done
sleep 15;
printf '-';
done
}
export -f counterMin
# 'counter' utility method:
# ie: counter 5 # wait 5 hours
function counterHour {
time=${1}
end1=$((SECONDS+(time*3600)))
while [ $SECONDS -lt $end1 ]; do
end2=$((SECONDS+3300)) # (55*60)
while [ $SECONDS -lt $end2 ]; do
sleep 300; # (5*60)
printf '-';
done
sleep 300; # (5*60)
printf '|';
done
}
export -f counterHour
# 'counter' utility method
# more complex version of timer
function counter {
time1=${1} # hour or min or sec
time2=${3} # min or sec
time3=${5} # sec
unit1=${2}
unit2=${4}
unit3=${6}
if [ $# -eq 2 ]; then
# hour, min, or sec
if [ "$unit1" == "h" ]; then
counterHour $time1
fi
if [ "$unit1" == "m" ]; then
counterMin $time1
fi
if [ "$unit1" == "s" ]; then
counterSec $time1
fi
elif [ $# -eq 4 ]; then
# hour, min / hour, sec / min, sec
if [ "$unit1" == "h" ]; then
counterHour $time1
printf "\n";
if [ "$unit2" == "m" ]; then
counterMin $time2
elif [ "$unit2" == "s" ]; then
counterSec $time2
fi
elif [ "$unit1" == "m" ]; then
counterMin $time1
printf "\n";
if [ "$unit2" == "h" ]; then
counterHour $time2
elif [ "$unit2" == "s" ]; then
counterSec $time2
fi
elif [ "$unit1" == "s" ]; then
counterSec $time1
printf "\n";
if [ "$unit2" == "h" ]; then
counterHour $time2
elif [ "$unit2" == "m" ]; then
counterMin $time2
fi
fi
elif [ $# -eq 6 ]; then
# hour and min and sec
if [ "$unit1" == "h" ]; then
counterHour $time1
printf "\n";
if [ "$unit2" == "m" ]; then
counterMin $time2
printf "\n";
if [ "$unit3" == "s" ]; then
counterSec $time3
fi
elif [ "$unit2" == "s" ]; then
counterSec $time2
printf "\n";
if [ "$unit3" == "m" ]; then
counterMin $time3
fi
fi
elif [ "$unit1" == "m" ]; then
counterMin $time1
printf "\n";
if [ "$unit2" == "h" ]; then
counterHour $time2
printf "\n";
if [ "$unit3" == "s" ]; then
counterSec $time3
fi
elif [ "$unit2" == "s" ]; then
counterSec $time2
printf "\n";
if [ "$unit3" == "h" ]; then
counterHour $time3
fi
fi
elif [ "$unit1" == "s" ]; then
counterSec $time1
printf "\n";
if [ "$unit2" == "h" ]; then
counterHour $time2
printf "\n";
if [ "$unit3" == "m" ]; then
counterMin $time3
fi
elif [ "$unit2" == "m" ]; then
counterMin $time2
printf "\n";
if [ "$unit3" == "h" ]; then
counterHour $time3
fi
fi
fi
fi
echo ' counter finished.';
}
sleepdelays execution by at least the number of seconds that you specify. There is no guarantee of exactness. \$\endgroup\$