Description

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 1)

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…

forced to immediately do the next iteration using the continue command, optionally as continue N analog to break N

Bash knows an alternative syntax for the for loop, enclosing the loop body in {...} instead of do ... done:

for ((x=1; x<=3; x++))
{
echo $x
}

This syntax is not documented and should not be used. I found the parser definitions for it in 1.x code, and in modern 4.x code. My guess is that it's there for compatiblity reasons. This syntax is not specified by POSIX(R).

Return status

The return status is the one of the last command executed from <LIST> or FALSE if any of the arithmetic expressions fail.

Examples

Simple counter

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.

it initializesx = 0

before every iteration it checks if x ⇐ 100

after every iteration it changesx++

for ((x = 0 ; x <= 100 ; x++)); do
echo "Counter: $x"
done

Stepping counter

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

Bits analyzer

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).

Portability considerations

C-style for loops aren't POSIX. They are available in Bash, ksh93, and zsh. All 3 have essentially the same syntax and behavior.

Bugs

* There appears to be a bug as of Bash 4.2p10 in which command lists cannot be distinguished from the for loop's arithmetic argument delimiter (both semicolons), so command substitutions within the C-style for loop expression cannot contain more than one command. This appears specific to Bash. ksh93 and zsh behave correctly. It's also pretty obscure and useless - you probably shouldn't be doing that anyway.

EDIT: Chet says it'll be fixed in the next version.

See also

However, as with all arithmetic, it is possible to have command substitutions contained within. Note that command substitutions are processed before arithmetic, so any control flow such as the ternary operator, or short circuiting, have no effect on the command substitution's evaluation. Rather, the expression resulting from the command substitution's output plus surrounding text ends up processed as arithmetic. See also the above bug.