How to use variables in a bash for loop [duplicate]
How does one use a variable in a bash for loop? If I just use a standard for loop, it does what I expect
for i in {0..3}
do
echo "do some stuff $i"
done
This works fine. It loops thru 4 times, 0 to 3 inclusive, printing my message and putting the count at the end.
do some stuff 0
do some stuff 1
do some stuff 2
do some stuff 3
When I try the same thing with the following for loop, it seems to equal a string, which is not what i want.
length=3
for i in {0..$length}
do
echo "do something right $i"
done
output:
do something right {0..3}
I've tried
for i in {0.."$length"} and for i in {0..${length}} (both output was {0..3})
and
for i in {0..'$length'} (output was {0..$length})
and they both don't do what I need. Hopefully someone can help me. Thanks in advance for any bash expert's help with for loops.
One way is using eval
:
for i in $( eval echo {0..$length} )
do
echo "do something right $i"
done
Note what happens when you set length=;ls
or length=; rm *
(don't try the latter though).
safely, using seq
:
for i in $( seq 0 $length )
do
echo "do something right $i"
done
or you can use the c-style for loop, which is also safe:
for (( i = 0; i <= $length; i++ ))
do
echo "do something right $i"
done
In bash, brace expansion is the first step attempted so, at that point, $length
will not have been substituted.
The manpage for bash states clearly:
A sequence expression takes the form {x..y[..incr]}, where x and y are either integers or single characters ...
There are a number of possibilities, such as using:
pax> for i in $(seq 0 $length) ; do echo $i ; done
0
1
2
3
though that may give you a large command line if length
is massive.
Another alternative is to use the C-like syntax:
pax> for (( i = 0; i <= $length; i++ )) ; do echo $i; done
0
1
2
3
It's also possible to omit $
sign in double parentheses to refer a variable:
ubuntu@ip-172-31-28-53:~/playground$ length=3;
ubuntu@ip-172-31-28-53:~/playground$ for ((i=0;i<=length;i++));do echo $i;done
0
1
2
3