#! /bin/bash
istrue()
{
test 0 -ne "$1"
}
isfalse()
{
test 0 -eq "$1"
}
phelp()
{
echo "$name: repeatedly execute a command line.
$Usage
commandline is executed once for each integer from startcount through endcount
inclusive. The default for startcount is 1 if a positive endcount or no
endcount is given, and -1 if a negative endcount is given. A count
parameter consisting of a single number is taken to be an endcount. If
only an endcount is given and it is positive, commandline is executed
endcount times. endcount may be less than startcount. If no endcount is
given (e.g. a count parameter of \"10-\"), commandline execution repeats
indefinitely with the iteration variable incrementing in a positive
direction. A count parameter of consisting of \"-\" will repeat
indefinitely starting with 1.
Note that quoting and variables in commandline are interpreted twice, once
when it is passed to the repeat command, and once when it is actually executed.
The iteration variable is \"count\". If \$count is used in commandline, make
sure it is quoted with ' or \.
Options:
-h: Print this help.
-p: Print value of iteration variable on stderr before each iteration.
-s <sec>: sleep for <sec> seconds after each iteration except the last.
-v: Print start and end values before beginning."
}
name=${0Usage="Usage: repeat [-hpv] [-s <sec>] [[startcount]-][endcount] command [arg ...]"
typeset -i count=1 forever=0 sleep=0 print=0 verbose=0
while getopts :0123456789hpvs: opt; do
case $opt in
h) phelp; exit 0;;
s) sleep=$OPTARG || exit 1;;
p) print=1;;
v)verbose=1;;
[0-9]) break;;
+?) echo "$name: options should not be preceded by a '+'." 1>&2; exit 2;;
?) echo "$name: $OPTARG: bad option. Use -h for help." 1>&2; exit 2;;
esac
done
shift $((OPTIND-1))
if [ $ echo -e "$Usage\nUse -h for help." 1>&2
exit 2
fi
case "$1" in
-[0-9]*-|[0-9]*-)
count=${1%-}
forever=1
end="-1";
;;
-[0-9]*-[0-9]*|[0-9]*-[0-9]*)
s=${1%-}
end=${s count=${s%-$end}
;;
-[0-9]*|[0-9]*)
end=$1
case "$end" in
-\*) count=-1;;
esac
;;
-)
forever=1
end="-1";
;;
*)
echo "$name: bad count parameter: $1" 1>&2
exit 1
;;
esac
shift
[ -z "$end" ] && [ $count -le "$end" ] && increment=1 || increment=-1
istrue $verbose && echo "start=$count end=$end" 1>&2
typeset -i end
let end+=increment
while istrue $forever || [ $count -ne $end ]; do
istrue $print && echo $count 1>&2
eval "$@"
istrue $sleep && sleep $sleep
let count+=increment
done