MIN=1 && for i in $(seq $(($MIN*5)) -1 1); do echo -n "$i, "; sleep 60; done; while :; do beep -r 25 -l 3; sleep 5; done
I decided recently to experiment with the pomodoro work/learning technique and, since I am usually working with a computer, wanted to be able to cobble together a countdown/up timer with alarm that runs on the machine at which I'm working. In brief, I wanted to count down/up either a 25 minute or 5 minute interval, by minute, then have an alarm sound--an alarm that will sound until reset. I wanted this, by the way, to be a non-gui solution that I can run from a terminal
Searching the web, I came up with something that works (mostly taken from http://www.commandlinefu.com/commands/view/5886/countdown-clock )--see above. It counts down and displays time remaining by minutes and, when the specified interval ends, it plays a distinctive but fairly non-intrusive system bell pattern (uses the "beep" program) every 5 seconds until ctrl+c is entered in the terminal from which the script was run.
As I said, what I have put together seems like it will suit my needs adequately. But since my understanding of bash is quite limited--as, by looking at the script, should be evident to anyone with bash-scripting experience--I thought I would ask here what sorts of improvements might be made to this script? Can it be further condensed, and/or perhaps use different utilities to achieve the same end, but in a more elegant manner? Input will be appreciated.
LATER EDIT: Zoltan's suggestion of replacing MIN=1 && for i in $(seq $(($MIN*5)) -1 1);
with for i in $(seq 5 -1 1);
does, it seems to me, somewhat simplify and improve the script I posted. So a more sensible version of this as a one-liner would be for i in $(seq 5 -1 1); do echo -n "$i, "; sleep 60; done; while :; do beep -r 25 -l 3; printf " # "; sleep 5; done
. The version he posted does seem a far more capable and flexible script, so I will mark it as the best answer. Although it's good to have an option like that available, I think I'll go ahead and stick with the version I created (including the slight improvement suggested by Zoltan and one I thought up that adds a hash sign each time the beep goes off [to give me an idea, in case I should leave the computer, how long it's been beeping]--the printf " # "
part) that has the time interval hard-coded into the script. Thanks for the input.
I think Your script is fair enough.
I don't really see the point in the && at
MIN=1 && for
it means, if the first term is successful, only then execute the second term. I am not even sure, what is the logical value of an assignment, but it is is safe to assume, it is successful. So a
MIN=1; for ...
should suffice.
As for this 2-liner, the whole MIN=1 seems pointless, You could just write
for i in $(seq 5 -1 1); do ...
On the other hand, You might want to be able to change the alloted time, which can be achieved like this:
1) create a file like beeper.sh
2) make it executable by your user
chmod u+x beeper.sh
or by all user:
chmod a+x beeper.sh
3) write your script in the file, with a little tweak:
#!/bin/bash
# default timeout
timeout_mins=5
# while testing your script, making changes, you want this to be something like 1 or 2
sec_per_min=60
# check for command line input
if [ 0 -ne $# ]
then
# assign the first command line param, no check, if it is a number, though!
timeout_mins=$1
fi
# now it does make sense, to have a variable in the for loop core
for i in $(seq $timeout_mins -1 1)
do
echo -n "$i, "
sleep $sec_per_min
done
while :
do
beep -r 25 -l 3
sleep 5
done
4) execute your script like this (from the dir the script file is in):
# using the default time
./beeper.sh
# using 9min
./beeper.sh 9
# invalid input: the seq will fail -> the for will fail -> execute the beep
./beeper.sh bla