Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 505
Classified Avatar asked Jun 19 '13 02:06

Classified


People also ask

What is $1 and $2 in bash?

$1 is the first argument (filename1) $2 is the second argument (dir1)

What is $@ in bash?

bash [filename] runs the commands saved in a file. $@ refers to all of a shell script's command-line arguments. $1 , $2 , etc., refer to the first command-line argument, the second command-line argument, etc. Place variables in quotes if the values might have spaces in them.

What does $2 do in bash?

$2 is the second command-line argument passed to the shell script or function. Also, know as Positional parameters.

How do you increment a variable in bash?

Increment Bash Variable with += Operator Another common operator which can be used to increment a bash variable is the += operator. This operator is a short form for the sum operator. The first operand and the result variable name are the same and assigned with a single statement.


2 Answers

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 
like image 57
perreal Avatar answered Oct 05 '22 03:10

perreal


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 
like image 29
paxdiablo Avatar answered Oct 05 '22 03:10

paxdiablo