In bash, is it possible to use an integer variable in the loop control of a for loop?

The reason for this is the order in which things occur in bash. Brace expansion occurs before variables are expanded. In order to accomplish your goal, you need to use C-style for loop:

upperlim=10

for ((i=0; i<=upperlim; i++)); do
   echo "$i"
done

To complete this in your style using nothing but built-ins you'd have to use eval:

d=12

for i in `eval echo {0..$d}`
do
echo $i
done

But with seq:

lowerlimit=0
upperlimit=12

for i in $(seq $lowerlimit $upperlimit)
do
echo $i
done

Personally I find the use of seq to be more readable.


The POSIX way

If you care about portability, use the example from the POSIX standard:

i=2
END=5
while [ $i -le $END ]; do
    echo $i
    i=$(($i+1))
done

Output:

2
3
4
5

Things which are not POSIX:

  • (( )) without dollar, although it is a common extension as mentioned by POSIX itself.
  • [[. [ is enough here. See also: https://stackoverflow.com/questions/13542832/bash-if-difference-between-square-brackets-and-double-square-brackets
  • for ((;;))
  • seq
  • {start..end}, and that cannot work with variables as mentioned by the Bash manual.
  • let i=i+1: POSIX 7 2. Shell Command Language does not contain the word let, and it fails on bash --posix 4.3.42
  • the dollar at i=$i+1 might be required, but I'm not sure. POSIX 7 2.6.4 Arithmetic Expansion says:

    If the shell variable x contains a value that forms a valid integer constant, optionally including a leading plus or minus sign, then the arithmetic expansions "$((x))" and "$(($x))" shall return the same value.

    but reading it literally that does not imply that $((x+1)) expands since x+1 is not a variable.