for (( <EXPR1> ; <EXPR2> ; <EXPR3> )); do <LIST> done
The C-style for-loop is, as the name says, derived from the C-keyword "for", but in Bash, it only allows arithmetic expressions as header contents, not arbitrary commands.
It operates as follows: The arithmetic expression <EXPR1> is evaluated, then <EXPR2> is checked, if it's true, then the loop body is executed. After the first iteration, the <EXPR3> is evaluated, <EXPR2> is checked again, if it's true, the loop body is executed, etc...
<EXPR1> is to initialize before the first run<EXPR2> is to check if the loop should be ran<EXPR3> is to change conditions after every loop runIt's very simple. Another equivalent loop using a while-construct with arithmetic expressions compound command would be:
(( <EXPR1> )) while (( <EXPR2> )); do <LIST> (( <EXPR3> )) done
If one of these arithmetic expressions in the for-loop is empty, it behaves as if it would be 1 (TRUE in arithmetic context).
Like all loops (both for-loops, while and until), this loop can be
break command, optionally as break N to break N levels of nested loopscontinue command, optionally as continue N analog to break N
The return status is the one of the last command executed from <LIST> or FALSE if any of the arithmetic expressions fail.
A simple counter, the loop iterates 101 times ("0" to "100" are 101 numbers → 101 runs!), and everytime the variable x is set to the current value.
x = 0x ⇐ 100x++
for ((x = 0 ; x <= 100 ; x++)); do echo "Counter: $x" done
This is the very same counter (compare it to the simple counter example above), but the change that is made is a x = x + 10. That means, it will count from 0 to 100, but with a step of 10.
for ((x = 0 ; x <= 100 ; x = x + 10)); do echo "Counter: $x" done
This is a bit more complex, but really just a little bit.
It loops through the bit-values of a Byte, beginning from 128, ending at 1. If that bit is set in the testbyte, it prints "1", else "0" ⇒ it prints the binary representation of the testbyte value (8 bits).
testbyte=123
for (( n = 128 ; n >= 1 ; n = n / 2 )); do
if (( testbyte & n )); then
echo -n "1"
else
echo -n "0"
fi
done
echo # final linefeed
Why that one begins at 128 (highest value, on the left) and not 1 (lowest value, on the right)? It's easier to print from left to right...
Discussion