3

How can I use variable in for loop digits?

for example:

num="12"
for i in {0..$num}; do
        ...
done
0

2 Answers 2

6

Brace expansion with variables doesn't work as one would expect (see Appendix B for juicy details), i.e. {0..$num} would only return {0..12} literally instead of a list of number.

Try seq instead like this:

num="12"
for i in $(seq 0 $num); do
    echo $i
done

Appendix B: Juicy details

The bash manual saith,

The order of expansions is: brace expansion, tilde expansion, parameter, variable, and arithmetic expansion and command substitution (done in a left-to-right fashion), word splitting, and filename expansion.

At the time shell expands {0..$num} (brace expansion), $num isn't expanded (variable expansion) yet. The sequence expression a..b needs both a and b to be numbers to generate a sequence, but here we have one number and one non-number (the literal string $num). Failing this, the shell falls back to interpreting {0..$num} literally. Then variable expansion takes over, and finally we get {0..12}

Sign up to request clarification or add additional context in comments.

3 Comments

Brace expansion doesn't support variables not entirely true :)
@JS웃, yeah the wording is wrong. I added a more proper explanation.
+1 for the update and added explanation. Though minor correction, $num will get expanded after a failed brace expansion reporting as {1..12} instead of {1..$num} but I guess OP will now get the bigger picture.
2

Bash does brace expansion before variable expansion, so you will get output like {1..12}. With use of eval you can get it to work.

Test:

$ num=5
$ for i in {1..$num}; do echo "$i"; done
{1..5}
$ for i in $(eval echo {1..$num}); do echo "$i"; done
1
2
3
4
5

Please note: eval is evil in disguise.

1 Comment

eval and evil even sound alike!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.