[unix] Shell script "for" loop syntax

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?

This question is related to unix syntax shell

The answer is


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.


There's more than one way to do it.

max=10
for i in `eval "echo {2..$max}"`
do
    echo "$i"
done

Well, as I didn't have the seq command installed on my system (Mac OS X v10.6.1 (Snow Leopard)), I ended up using a while loop instead:

max=5
i=1

while [ $max -gt $i ]
do
    (stuff)
done

*Shrugs* Whatever works.


Here it worked on Mac OS X.

It includes the example of a BSD date, how to increment and decrement the date also:

for ((i=28; i>=6 ; i--));
do
    dat=`date -v-${i}d -j "+%Y%m%d"` 
    echo $dat
done

This is a way:
Bash:

max=10
for i in $(bash -c "echo {2..${max}}"); do echo $i; done

The above Bash way will work for ksh and zsh too, when bash -c is replaced with ksh -c or zsh -c respectively.

Note: for i in {2..${max}}; do echo $i; done works in zsh and ksh.


We can iterate loop like as C programming.

#!/bin/bash
for ((i=1; i<=20; i=i+1))
do 
      echo $i
done

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

Use:

max=10
for i in `eval echo {2..$max}`
do
    echo $i
done

You need the explicit 'eval' call to reevaluate the {} after variable substitution.


These all do {1..8} and should all be POSIX. They also will not break if you put a conditional continue in the loop. The canonical way:

f=
while [ $((f+=1)) -le 8 ]
do
  echo $f
done

Another way:

g=
while
  g=${g}1
  [ ${#g} -le 8 ]
do
  echo ${#g}
done

and another:

set --
while
  set $* .
  [ ${#} -le 8 ]
do
  echo ${#}
done

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.


Examples related to unix

Docker CE on RHEL - Requires: container-selinux >= 2.9 What does `set -x` do? How to find files modified in last x minutes (find -mmin does not work as expected) sudo: npm: command not found How to sort a file in-place How to read a .properties file which contains keys that have a period character using Shell script gpg decryption fails with no secret key error Loop through a comma-separated shell variable Best way to find os name and version in Unix/Linux platform Resource u'tokenizers/punkt/english.pickle' not found

Examples related to syntax

What is the 'open' keyword in Swift? Check if returned value is not null and if so assign it, in one line, with one method call Inline for loop What does %>% function mean in R? R - " missing value where TRUE/FALSE needed " Printing variables in Python 3.4 How to replace multiple patterns at once with sed? What's the meaning of "=>" (an arrow formed from equals & greater than) in JavaScript? How can I fix MySQL error #1064? What do >> and << mean in Python?

Examples related to shell

Comparing a variable with a string python not working when redirecting from bash script Get first line of a shell command's output How to run shell script file using nodejs? Run bash command on jenkins pipeline Way to create multiline comments in Bash? How to do multiline shell script in Ansible How to check if a file exists in a shell script How to check if an environment variable exists and get its value? Curl to return http status code along with the response docker entrypoint running bash script gets "permission denied"