for: for NAME [in WORDS ... ;] do COMMANDS; done
The `for' loop executes a sequence of commands for each member in a
list of items. If `in WORDS ...;' is not present, then `in "$@"' is
assumed. For each element in WORDS, NAME is set to that element, and
the COMMANDS are executed.
for ((: for (( exp1; exp2; exp3 )); do COMMANDS; done
Equivalent to
(( EXP1 ))
while (( EXP2 )); do
COMMANDS
(( EXP3 ))
done
EXP1, EXP2, and EXP3 are arithmetic expressions. If any expression is
omitted, it behaves as if it evaluates to 1.
If you're interested only in Bash, the "for(( ... ))" solution presented above is the best, but if you want something POSIX SH compliant that will work on all Unices, you'll have to use "expr" and "while", and that's because "(())" or "seq" or "i=i+1" are not that portable among various shells.
I commonly like to use a slight variant on the standard for loop. I often use this to run a command on a series of remote hosts. I take advantage of Bash's brace expansion to create for loops that allow me to create non-numerical for loops.
Example:
I want to run the uptime command on frontend hosts 1-5 and backend hosts 1-3:
% for host in {frontend{1..5},backend{1..3}}.mycompany.com
do ssh $host "echo -n $host; uptime"
done
I typically run this as a single-line command with semicolons on the ends of the lines instead of the more readable version above. The key usage consideration are that braces allow you to specify multiple values to be inserted into a string (e.g. pre{foo,bar}post results in prefoopost, prebarpost) and allow counting/sequences by using the double periods (you can use a..z, etc.). However, the double period syntax is a new feature of Bash 3.0; earlier versions will not support this.