3

So I was writing a for loop and getting some errors, to get an understanding of the errors I wrote this

 #! /bin/bash b=${1:- 10} echo $b for i in {0..$b} do echo "$i" done 

so if I run ./forloop.sh 10

I get

 10 {0..10} 

why doesn't the range work when I have a variable as the second argument?

1
  • Consider for i in $(seq 0 ${1:-10}). Commented May 16, 2013 at 2:44

3 Answers 3

5

Bash doesn't expand the range. Use this instead.

for (( i=0; i<=$b; i++)) 
Sign up to request clarification or add additional context in comments.

Comments

2

The part of bash that expands things like {1..10} into 1 2 3 4 5 6 7 8 9 10 runs before any parameters like $b are replaced by their values. Since {1..$b} doesn't look like a numeric range, it doesn't get expanded. By the time parameter expansion turns it into {1..10}, it's too late; nothing is going to come along and evaluate the curly-brace expression.

3 Comments

Do you know why it does this?
There has to be some order. The order in which the shell does this is well established and well documented. Read the Bash manual page for the nittty gritty. It doesn't have a rationale, but when you see how many different substitution mechanisms there are in the shell, I think you'll agree at least that there has to be an order. Fundamentally, it's just arbitrary.
What's the alternative, @JakeSchievink? If the shell went back and kept expanding things as long as anything looked expandable, you'd run into unpredictable results and lots of infinite recursion.
1

Change the script to use the following (http://ideone.com/MwAi16).

b=10 for i in $(eval echo {0..$b}) 

3 Comments

Don't use eval if you can at all avoid it. If the source of $b is even a little more remote than the immediately-prior assignment here, it's far too easy to wind up with code doing completely unexpected things.
@MarkReed Agreed. But the OP's question was about {0..$b}, and eval is just a way to solve it. There are numerous ways to write a loop, and it is just a solution. I do not see the reason for the down vote though.
@Bill Mark is simply pointing out that the eval can possibly be a security threat au should by avoided. Also your solution can be replaced with this: b=10; for i in $(seq 0 $b); do echo $i; done. No needs for the eval. eval is evil.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.