ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
2. for I in 1 2 3 4 5 6 7 8 9 10; do echo $I; done|
3. for I in $(seq 1 10); do echo $I; done|
4. for ((I=1; I <= 10 ; I++)); do echo $I; done
I have a script which uses the 1st form of for loop. I'm trying to modify it to use a variable instead of a static hard-coded value in the section that controls the looping.of the for loop.
I've tried all different ways of quoting and escaping the variable, and the problem is that the quoting chars and escape char are being translated and passed into the loop along with the value stored in the variable.
For example, to change the start value of 1 to whatever value I want passed in through a variable:
Change: for i in {1..100}; do <something>; done
to: for i in {$a..10}; do <something>; done
I have tried: {{$a}..10} and {`$a`..10}, to have the variable evaluated first.
I have tried using the eval() function.
I have tried single and double quotes and the backslash escape character.
Nothing I've tried works. It's probably a syntax error, but as of now, I'm baffled.
Can anyone shed some light on the problem and solution, please? Thanks!
The problem is that the "brace expansion" is performed before the "variable expansion". See here for details about shell expansion, where they are listed in the order that they are expanded. Hence you have to use eval to let the bash do the variable substitution and then expand the resulting "extended brace" {1..10}. This should work
Code:
#!/bin/bash
start=1
for i in $(eval echo {$start..10})
do
echo $i
done
otherwise use the forms 3 or 4:
Code:
#!/bin/bash
start=1
for i in $(seq $start 10)
do
echo $i
done
for (( i = $start; i <= 10 ; i++ ))
do
echo $i
done
Last edited by colucix; 07-03-2009 at 08:07 AM.
Reason: Forgotten the link...
for a in "${array[@]}"; do ...
for a in "$@"; do ...
Unless brace expansion does not work within array assignments, the code above that assigns varlues for an array should work. Sorry i don't have access to a terminal now .
Last edited by konsolebox; 07-03-2009 at 08:38 AM.
Reason: clarity
Unless brace expansion does not work within array assignments, the code above that assigns values for an array should work. Sorry i don't have access to a terminal now .
If I understand this correctly, the issue with the expansion is that the expansion happens before the parameter substitution. Thus
{$start...7}
does not get expanded correctly.
simply put it that brace expansion does not parse variables and only raw data therefore we have to make the line *reappear* so that the variable will turn into a raw data:
if this works:
Code:
a=({1..10})
then evaluating the variable first then reparsing the line should work:
if a = 1:
The problem is that the "brace expansion" is performed before the "variable expansion". See here for details about shell expansion, where they are listed in the order that they are expanded. Hence you have to use eval to let the bash do the variable substitution and then expand the resulting "extended brace" {1..10}. This should work
Code:
#!/bin/bash
start=1
for i in $(eval echo {$start..10})
do
echo $i
done
otherwise use the forms 3 or 4:
Code:
#!/bin/bash
start=1
for i in $(seq $start 10)
do
echo $i
done
for (( i = $start; i <= 10 ; i++ ))
do
echo $i
done
Well, technically I tend to use # 3 because it's more versatile, and you won't have problems like this one. If I were writing scripts that I would have to update later ... that would be the one I'd pick. And, of course, I don't disagree finding out why # 1 causes problems, that helps to understand the inner workings, but in the end I wouldn't use that option.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.