Shell script "for" loop syntax
Solution 1
Brace expansion, {x..y} is performed before other expansions, so you cannot use that for variable length sequences.
Instead, use the seq 2 $max
method as user mob stated.
So, for your example it would be:
max=10
for i in `seq 2 $max`
do
echo "$i"
done
Solution 2
Try the arithmetic-expression version of for
:
max=10
for (( i=2; i <= $max; ++i ))
do
echo "$i"
done
This is available in most versions of bash, and should be Bourne shell (sh) compatible also.
Solution 3
Step the loop manually:
i=0 max=10 while [ $i -lt $max ] do echo "output: $i" true $(( i++ )) done
If you don’t have to be totally POSIX, you can use the arithmetic for loop:
max=10 for (( i=0; i < max; i++ )); do echo "output: $i"; done
Or use jot(1) on BSD systems:
for i in $( jot 0 10 ); do echo "output: $i"; done
Solution 4
If the seq
command available on your system:
for i in `seq 2 $max`
do
echo "output: $i"
done
If not, then use poor man's seq
with perl
:
seq=`perl -e "\$,=' ';print 2..$max"`
for i in $seq
do
echo "output: $i"
done
Watch those quote marks.
Solution 5
We can iterate loop like as C programming.
#!/bin/bash
for ((i=1; i<=20; i=i+1))
do
echo $i
done
Related videos on Youtube
eykanal
I'm currently working at Google, helping build AI/ML tools for public sector. I've worn a number of hats in the past, including cybersecurity researcher, computational neuroscientist, healthcare technical manager, financial quant, freelance web developer, and IT consultant. I find writing therapeutic; you can read my musings on my blog. Most articles relate to technical management, with the occasional technical discussion. I also find poi spinning to be a pretty awesome hobby as well. You can learn more about me on my LinkedIn page.
Updated on July 22, 2020Comments
-
eykanal almost 4 years
I have gotten the following to work:
for i in {2..10} do echo "output: $i" done
It produces a bunch of lines of
output: 2
,output: 3
, so on.However, trying to run the following:
max=10 for i in {2..$max} do echo "$i" done
produces the following:
output: {2..10}
How can I get the compiler to realize it should treat $max as the other end of the array, and not part of a string?
-
whatsisname over 14 yearswhat system and shell are you using? What kind of goofy system has sh or bash, but doesn't have seq, a coreutil?
-
Rahul Das over 14 yearsFreeBSD doesn't.
-
a paid nerd over 14 yearsSmall style nit: I usually see the
do
andthen
keywords on the same line asfor
andif
, respectively. E.g.,for i in {2..10}; do
-
Barmar almost 11 yearspossible duplicate of Is it possible to use a variable in for syntax in bash?
-
jrm about 9 yearsFreeBSD, at least 10, does have /usr/bin/seq.
-
Charles Duffy over 3 years@whatsisname,
seq
is not POSIX-standardized. Even if it exists, it's not guaranteed to have any particular behavior. There's a reason none of the patterns discussed in wooledge.org/~greybot/meta/counting (the relevant entry in the freenode #bash channel's factoid database) depend on it.
-
-
system PAUSE over 14 yearsseq is relatively new. I only found out about it a few months ago. But you can use a 'for' loop!! The disadvantage of a 'while' is that you have to remember to increment the counter somewhere inside the loop, or else loop downwards.
-
Flow about 12 years
true $(( i++ ))
doesn't work in all cases, so most portable would betrue $((i=i+1))
. -
system PAUSE about 12 years@Flow: Hm, I just tried it on a couple of systems (Linux and BSD based) with #!/bin/sh and it worked fine. Invoked under bash and specifically under /bin/sh, still worked. Maybe the version of sh matters? Are you on some old Unix?
-
chepner over 10 yearsVery few systems have a dedicated
sh
, instead making it a link to other another shell. Ideally, such a shell invoked assh
would only support those features in the POSIX standard, but by default let some of their extra features through. The C-style for-loop is not a POSIX feature, but may be insh
mode by the actual shell. -
chepner over 10 yearsA security risk, since
eval
will evaluate anything you setmax
to. Considermax="2}; echo ha; #"
, then replaceecho ha
with something more destructive. -
logan over 10 yearssemi colon should not come in "for (( i=0; i < max; i++ ));"
-
Conrad Meyer about 10 years(S)he set max to 10. No risk.
-
miller almost 8 yearsThere is no good reason to use an external command such as
seq
to count and increment numbers in the for loop, hence it is recommend that you avoid usingseq
. This command is left for compatibility with old bash. The built-in commands are fast enough.for (( EXP1; EXP2; EXP3 )) ...
-
Wernight over 7 years@miller the
for (( ... ))
syntax isn't POSIX and that means for example that it won't work out of the box on things like Alpine Linux.seq
does. -
Franklin Yu about 5 years@Wernight Not just Alpine Linux;
#!/bin/sh
is Dash in Debian/Ubuntu.