In response to a comment of mine to this question on SF the OP asserts that the
for i in {1..$NUM}
expands correctly in bash. I have access to bash 4.0.33 (Ubuntu), 3.2.25 (Centos) and 3.00.16(1) (solaris 10). None of these will expand the {1..$NUM}.
Does anyone know which versions of bash do the expansion? If it’s not bash what is it ? I know zsh will do the expansion but in the OP’s script the shebang should remove the possibility of an alias ?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
I’m pretty sure the person asking the question on server fault is wrong. They’re either leaving out some detail intentionally or are unaware of some weird configuration on the machine (/bin/bash as a link to something else). I tried on the two-week-old bash 4.2 release, on bash 3.2 from CentOS 5, and on bash 2.05a (from 2001) which I built myself just now to try.
The oldest source on ftp.gnu.org is 1.14, but that doesn’t build cleanly, and I’m not sure trying it is worthwhile. The documentation for that release contains the exact same key phrases as in the modern documentation:
The order of expansions is: brace expansion, tilde expan- sion, parameter, variable, command, and arithmetic substitu- tion (done in a left-to-right fashion), word splitting, and pathname expansion.
But actually, now that I think of it, that’s pointless, since the “{x..y}” syntax was added in bash 3.0, making looking before that useless.
So, let me try 3.0 … right. Same behavior.
So yeah. I’m extremely skeptical. Something doesn’t add up.
(Later…)
Aha! The server-fault questioner admits “Sorry. my mistake. I’ve put for actual number in i in {1..10}, so it worked well.” So, there ya go.
The answer to this question is “no version of bash works like that”. 🙂
Method 2
To expand this you’d have to use eval:
$ echo {1..5}
1 2 3 4 5
$ NUM=5
$ echo {1..$NUM}
{1..5}
$ eval "echo {1..$NUM}"
1 2 3 4 5
Be very, very careful with eval though! Make sure you check that it’s really a number before you execute something like this if you’re accepting user input. As my colleague observed: “eval is evil!”
Method 3
Brace expansion does not expand variables, because the brace expansion is the very first step of the shell expansion and the variables are expanded later.
From the bash man page:
Brace expansion is performed before
any other expansions, and any
characters special to other expansions
are preserved in the result. It is
strictly textual. Bash does not apply
any syntactic interpretation to the
context of the expansion or the text
between the braces.
So:
NUM=4
for i in {1..$NUM}
do
echo $i
done
prints
{1..4}
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0