12 Bash For Loop Examples for Your Linux Shell Scripting

by Ramesh Natarajan on July 11, 2011

There are two types of bash for loops available. One using the “in” keyword with list of values, another using the C programming like syntax.

This article is part of our on-going bash tutorial series.

This explains both of the bash for loop methods, and provides 12 different examples on how to use the bash for loop in your shell scripts.

Bookmark this article for future reference, as this is the only article you would ever need to refer on how to use bash for loops with examples.

Method 1: Bash For Loop using “in” and list of values

Syntax:

for varname in list
do
 command1
 command2
 ..
done

In the above syntax:

  • for, in, do and done are keywords
  • “list” contains list of values. The list can be a variable that contains several words separated by spaces. If list is missing in the for statement, then it takes the positional parameter that were passed into the shell.
  • varname is any Bash variable name.

In this form, the for statement executes the commands enclosed in a body, once for each item in the list. For example, if the list of values contains 5 items, the for loop will be executed a total of 5 times, once for each item in the list. The current item from the list will be stored in a variable “varname” each time through the loop. This “varname” can be processed in the body of the for loop.

Method 2: Bash For Loop using C like syntax

The second form of the for loop is similar to the for loop in “C” programming language, which has three expressions (initialization, condition and updation).

for (( expr1; expr2; expr3 ))
do
 command1
 command2
 ..
done

In the above bash for command syntax,

  • Before the first iteration, expr1 is evaluated. This is usually used to initialize variables for the loop.
  • All the statements between do and done are executed repeatedly until the value of expr2 is TRUE.
  • After each iteration of the loop, expr3 is evaluated. This is usually used to increment a loop counter.

The following 12 examples shows how to bash for loops in different ways.

1. Static values for the list after “in” keyword

In the following example, the list of values (Mon, Tue, Wed, Thu and Fri) are directly given after the keyword “in” in the bash for loop.

$ cat for1.sh
i=1
for day in Mon Tue Wed Thu Fri
do
 echo "Weekday $((i++)) : $day"
done

$ ./for1.sh
Weekday 1 : Mon
Weekday 2 : Tue
Weekday 3 : Wed
Weekday 4 : Thu
Weekday 5 : Fri

Caution: The list of values should not be separated by comma (Mon, Tue, Wed, Thu, Fri). The comma will be treated as part of the value. i.e Instead of “Mon”, it will use “Mon,” as value as shown in the example below.

$ cat for1-wrong1.sh
i=1
for day in Mon, Tue, Wed, Thu, Fri
do
 echo "Weekday $((i++)) : $day"
done

$ ./for1-wrong1.sh
Weekday 1 : Mon,
Weekday 2 : Tue,
Weekday 3 : Wed,
Weekday 4 : Thu,
Weekday 5 : Fri

Caution: The list of values should not be enclosed in a double quote. (“Mon Tue Wed Thu Fri”). If you enclose in double quote, it will be treated as a single value (instead of 5 different values), as shown in the example below.

$ cat for1-wrong2.sh
i=1
for day in "Mon Tue Wed Thu Fri"
do
 echo "Weekday $((i++)) : $day"
done

$ ./for1-wrong2.sh
Weekday 1 : Mon Tue Wed Thu Fri

2. Variable for the list after “in” keyword

Instead of providing the values directly in the for loop, you can store the values in a variable, and use the variable in the for loop after the “in” keyword, as shown in the following example.

$ cat for2.sh
i=1
weekdays="Mon Tue Wed Thu Fri"
for day in $weekdays
do
 echo "Weekday $((i++)) : $day"
done

$ ./for2.sh
Weekday 1 : Mon
Weekday 2 : Tue
Weekday 3 : Wed
Weekday 4 : Thu
Weekday 5 : Fri

Caution: As a best practice, you should always quote the bash variables when you are referring it. There are few exceptions to this best practice rule. This is one of them. If you double quote the variable in this for loop, the list of values will be treated as single value. Lot of people fall into this trap. Be careful and do not double quote your variable in the for loop.

$ cat for2-wrong.sh
i=1
weekdays="Mon Tue Wed Thu Fri"
for day in "$weekdays"
do
 echo "Weekday $((i++)) : $day"
done

$ ./for2-wrong.sh
Weekday 1 : Mon Tue Wed Thu Fri

3. Don’t specify the list; get it from the positional parameters

If you don’t specify the keyword “in” followed by any list of values in the bash for loop, it will use the positional parameters (i.e the arguments that are passed to the shell script).

$ cat for3.sh
i=1
for day
do
 echo "Weekday $((i++)) : $day"
done

$ ./for3.sh Mon Tue Wed Thu Fri
Weekday 1 : Mon
Weekday 2 : Tue
Weekday 3 : Wed
Weekday 4 : Thu
Weekday 5 : Fri

Caution: Please be careful if you use this method. You should not include the keyword “in” in the for loop. If you leave the keyword “in” without any values, it will not use the positional parameter as shown below. It will not go inside the loop. i.e for loop will never get executed as shown in the example below.

$ cat for3-wrong.sh
i=1
for day in
do
 echo "Weekday $((i++)) : $day"
done

$ ./for3-wrong.sh Mon Tue Wed Thu Fri

Note: Refer to our earlier article to understand more about bash positional parameters.

4. Unix command output as list values after “in” keyword

You can use the output of any UNIX / Linux command as list of values to the for loop by enclosing the command in back-ticks ` ` as shown below.

$ cat for4.sh
i=1
for username in `awk -F: '{print $1}' /etc/passwd`
do
 echo "Username $((i++)) : $username"
done

$ ./for4.sh
Username 1 : ramesh
Username 2 : john
Username 3 : preeti
Username 4 : jason
..

5. Loop through files and directories in a for loop

To loop through files and directories under a specific directory, just cd to that directory, and give * in the for loop as shown below.

The following example will loop through all the files and directories under your home directory.

$ cat for5.sh
i=1
cd ~
for item in *
do
 echo "Item $((i++)) : $item"
done

$ ./for5.sh
Item 1 : positional-parameters.sh
Item 2 : backup.sh
Item 3 : emp-report.awk
Item 4 : item-list.sed
Item 5 : employee.db
Item 8 : storage
Item 9 : downloads

Usage of * in the bash for loop is similar to the file globbing that we use in the linux command line when we use ls command (and other commands).

For example, the following will display all the files and directories under your home directory. This is the concept that is used in the above for5.sh example.

cd ~
ls *

The following will display all the *.conf file that begins with either a, b, or, c or d under /etc directory.

$ ls -1 /etc/[abcd]*.conf
/etc/asound.conf
/etc/autofs_ldap_auth.conf
/etc/cas.conf
/etc/cgconfig.conf
/etc/cgrules.conf
/etc/dracut.conf

The same argument that is used in the ls command above, can be used in a bash for loop, as shown in the example below.

$ cat for5-1.sh
i=1
for file in /etc/[abcd]*.conf
do
 echo "File $((i++)) : $file"
done

$ ./for5-1.sh
File 1 : /etc/asound.conf
File 2 : /etc/autofs_ldap_auth.conf
File 3 : /etc/cas.conf
File 4 : /etc/cgconfig.conf
File 5 : /etc/cgrules.conf
File 6 : /etc/dracut.conf

6. Break out of the for loop

You can break out of a for loop using ‘break’ command as shown below.

$ cat for6.sh
i=1
for day in Mon Tue Wed Thu Fri
do
 echo "Weekday $((i++)) : $day"
 if [ $i -eq 3 ]; then
   break;
 fi
done

$ ./for6.sh
Weekday 1 : Mon
Weekday 2 : Tue

7. Continue from the top of the for loop

Under certain conditions, you can ignore the rest of the commands in the for loop, and continue the loop from the top again (for the next value in the list), using the continue command as shown below.

The following example adds “(WEEKEND)” to Sat and Sun, and “(weekday)” to rest of the days.

$ cat for7.sh
i=1
for day in Mon Tue Wed Thu Fri Sat Sun
do
 echo -n "Day $((i++)) : $day"
 if [ $i -eq 7 -o $i -eq 8 ]; then
   echo " (WEEKEND)"
   continue;
 fi
 echo " (weekday)"
done

$ ./for7.sh
Day 1 : Mon (weekday)
Day 2 : Tue (weekday)
Day 3 : Wed (weekday)
Day 4 : Thu (weekday)
Day 5 : Fri (weekday)
Day 6 : Sat (WEEKEND)
Day 7 : Sun (WEEKEND)

8. Bash for loop using C program syntax

This example uses the 2nd method of bash for loop, which is similar to the C for loop syntax. The following example generates 5 random number using the bash C-style for loop.

$ cat for8.sh
for (( i=1; i <= 5; i++ ))
do
 echo "Random number $i: $RANDOM"
done

$ ./for8.sh
Random number 1: 23320
Random number 2: 5070
Random number 3: 15202
Random number 4: 23861
Random number 5: 23435

9. Infinite Bash for loop

When you don’t provide the start, condition, and increment in the bash C-style for loop, it will become infinite loop. You need to press Ctrl-C to stop the loop.

$ cat for9.sh
i=1;
for (( ; ; ))
do
   sleep $i
   echo "Number: $((i++))"
done

Like we said above, press Ctrl-C to break out of this bash infinite for loop example.

$ ./for9.sh
Number: 1
Number: 2
Number: 3

10. Using comma in the bash C-style for loop

In the bash c-style loop, apart from increment the value that is used in the condition, you can also increment some other value as shown below.

In the initialize section, and the increment section of the bash C-style for loop, you can have multiple value by separating with comma as shown below.

The following for loop is executed a total of 5 times, using the variable i. However the variable j start with 5, and getting increment by 5 every time the loop gets executed.

$ cat for10.sh
for ((i=1, j=10; i <= 5 ; i++, j=j+5))
do
 echo "Number $i: $j"
done

$ ./for10.sh
Number 1: 10
Number 2: 15
Number 3: 20
Number 4: 25
Number 5: 30

11. Range of numbers after “in” keyword

You can loop through using range of numbers in the for loop “in” using brace expansion.

The following example loops through 10 times using the values 1 through 10.

$ cat for11.sh
for num in {1..10}
do
 echo "Number: $num"
done

$ ./for11.sh
Number: 1
Number: 2
Number: 3
Number: 4
Number: 5
...

12. Range of numbers with increments after “in” keyword

The following example loops through 5 times using the values 1 through 10, with an increment of 2. i.e It starts with 1, and keeps incrementing by 2, until it reaches 10.

$ cat for12.sh
for num in {1..10..2}
do
 echo "Number: $num"
done

$ ./for12.sh
Number: 1
Number: 3
Number: 5
Number: 7
Number: 9

PS: Don’t forget to bookmark this article for your future reference.


Linux Sysadmin Course Linux provides several powerful administrative tools and utilities which will help you to manage your systems effectively. If you don’t know what these tools are and how to use them, you could be spending lot of time trying to perform even the basic administrative tasks. The focus of this course is to help you understand system administration tools, which will help you to become an effective Linux system administrator.
Get the Linux Sysadmin Course Now!

If you enjoyed this article, you might also like..

  1. 50 Linux Sysadmin Tutorials
  2. 50 Most Frequently Used Linux Commands (With Examples)
  3. Top 25 Best Linux Performance Monitoring and Debugging Tools
  4. Mommy, I found it! – 15 Practical Linux Find Command Examples
  5. Linux 101 Hacks 2nd Edition eBook Linux 101 Hacks Book

Bash 101 Hacks Book Sed and Awk 101 Hacks Book Nagios Core 3 Book Vim 101 Hacks Book

{ 45 comments… read them below or add one }

1 jalal hajigholamali July 11, 2011 at 2:30 am

Hi,

Really, very nice article
Thanks a lot…

2 Joseph John July 11, 2011 at 4:16 am

when I run for8.sh
I get error
“for8.sh: 3: Syntax error: Bad for loop variable”
I use Ubunutu 11.04
I did cut and paste the code , did not modify anything

3 shark巨菜 July 11, 2011 at 5:33 am

such many way
( ⊙ o ⊙ )!

4 Marija July 11, 2011 at 7:10 am

@Joseph John . . .for8.sh works for me….using bash shell

5 Júlio Hoffimann Mendes July 11, 2011 at 9:19 am

Thanks Ramesh!

I knew all bash loops you showed, is great to see them joined in one page. This helps so much whom is learning this useful language. :-)

Regards,
Júlio.

6 Joseph John July 11, 2011 at 10:09 pm

@Marija , I tried using bash “for8.sh” and it is working
thanks

7 Bilal Bhat July 11, 2011 at 10:52 pm

Good one…will use most of examples in practical….

8 Kamal Kishore July 12, 2011 at 6:51 am

cat for12.sh
for num in {1..10..2}
do
echo “Number: $num”
done

Above example is not working….
Output is comming as follows…..
for num in {1..10..2}

9 robin July 12, 2011 at 9:50 am

quote” Kamal Kishore”

cat for12.sh
for num in {1..10..2}
do
echo “Number: $num”
done

Above example is not working….
Output is comming as follows…..
for num in {1..10..2}

10 Pier July 12, 2011 at 2:05 pm

thanks Ramesh,

I knew the “classic” bash syntax (but it is always good to pop up some old knowledge) but i totally discovered the “C” style syntax!

I won’t bookmark this page as i already bookmarked your site!

11 jalal hajigholamali July 12, 2011 at 8:07 pm

for num in {1..10..2}
do
echo “Number: $num”
done

under bash is working
output is:
“Number: 1”
“Number: 3”
“Number: 5”
“Number: 7”
“Number: 9”

12 Andrius Bentkus July 14, 2011 at 6:48 am

I always disliked bash, but at least it has some good bits.
Though I doubt it that it will be the next javascript (a language which was very much disliked by everyone in the early days but gains some popularity now).

13 Ken Butcher July 16, 2011 at 6:58 am

A simpler variation of the infinite for loop:
$ cat for9-a.sh
i=1;
for :
do
sleep $i
echo “Number: $((i++))”
done

14 EmcySquare July 18, 2011 at 3:11 am

About the ” Syntax error: Bad for loop variable”
Be sure to use BASH and not SH as interpreter

15 Ken Butcher July 18, 2011 at 11:08 am

Correction to my earlier post. The alternate infinite for loop using the : (nop) operator must be while, not for. i.e.
while :
do
sleep $i
echo “Number: $((i++))”
done

16 Ken Butcher July 18, 2011 at 11:16 am

For those using Ubuntu, be aware that Dash is the symbolic link for sh instead of the traditional Bash. For other distros, you can test this using
ls -l `which sh`
and if it is dash, you can change it back to bash with
cd /bin
sudo rm sh
sudo ln -s bash sh

17 anon March 5, 2012 at 4:37 am

You’re the best :D

18 Deepak April 24, 2012 at 11:22 am

Gr8 Article f :)

19 Glenn May 7, 2012 at 3:23 pm

One thing you left off was the one line format:

$ for foo in a b c ; do echo $foo; done

Note the added semi-colons indicating the end of each statement.

20 Varun May 29, 2012 at 11:51 pm

Hi Friends,

I tried for loop as below.

for i in {“$start”..”$end”}

where start and end are user input variable. Its throwing error as:
syntax error: operand expected (error token is “{2..5}”)

Please help me where I have to give this operand ‘(‘.

Looking for your reply.
Thanks
Varun S

21 Ken B May 30, 2012 at 2:58 pm

eval for i in {$start..$end}\;do echo \$i\;done

22 Rajesh Kumar V July 18, 2012 at 7:46 am

Hi ramesh/team,

how to use multiple variable in single “for” loop .if not possible pls give alternate solution .

i am trying
for file in $(cat 2) && for ID in $(cat 3)
do
echo “Modifying file : $file and $ID ”
echo “” >> $file.tmp
cat $file >> $file.tmp
mv $file.tmp $file
done

But Not working .
please help me on this.

thanks in advance
Rajesh /JDHP

23 sharan August 15, 2012 at 2:09 pm

@Ken Butcher Thanks a lot for your comment … i had a project deadline .. and was struck doing the benchmarks with the error bad loop variable … after doing the change you have given , I got it solved.. again thanks a lot…

@Ramesh clean and simple… great article

24 Venadan September 4, 2012 at 6:50 am

Awsome examples…and use almost every day..great job !!!

25 E September 25, 2012 at 8:39 am

What about for adding numbers to the end of a file if it is already detected while being copied?
ex. copy file 1
ok
copy file 1 again
file one renamed as file 1(2)
ect..

26 Ken B September 25, 2012 at 6:57 pm

google bash backup version control

27 shweta October 14, 2012 at 12:18 am

for i in {$start..$end}
do
echo ” i m $i”
done
where start and end are user input variable,
Above example is not working……
output is – i m 2..7
as 2 and 7 are the user inputs…………
Pls help me ……….

28 Maine_guy October 16, 2012 at 2:11 pm

shweta,
Bash doesn’t work that way. you can use {2..7} but not {$a..$b}
A work around is
for (( i=$start; i<=$end; i++ ))
do
echo ” i m $i”
done

29 shweta October 16, 2012 at 11:28 pm

@ MAine_guy thanks………. it solved my confusions………

30 Maine_Guy November 1, 2012 at 10:57 am

Another way:

for i in $(seq $start $end); do
echo “i m $i”
done

31 udayakanta November 12, 2012 at 4:50 am

all info abt for loop…….i got it……..thanks….

32 Nic December 25, 2012 at 10:48 am

I’ve never been able to get bracket expansion to work in a loop…

somaddict@terrordome ~/sandbox
$ for i in [abcd] ; do echo $i;done
[abcd]

somaddict@terrordome ~/sandbox
$ for i in {a..d}; do echo $i;done
a
b
c
d

33 shilpa n chinnannavar March 6, 2013 at 11:20 am

i want shell script programs from simple to complex..
if u guys help me it will be useful for me..
very thanks in advance

34 mathison April 15, 2013 at 12:59 pm

Im trying to run each comand then the next one in a loop. im getting an error?

/etc/init.d/FMtx.sh: 3: /etc/init.d/FMtx.sh: Syntax error: Bad for loop variable

???
—————————
#!/bin/sh

for ((i=0;i<6;i++))
do
sudo /home/pi/pifm botID.wav 90.3
sudo /home/pi/pifm nightlife_01.wav 90.3
sudo /home/pi/pifm -
sudo /home/pi/pifm wwrob2.wav 90.3
sudo /home/pi/pifm -
sudo /home/pi/pifm mae.wav 90.3

echo $i
done
—————————–

35 Maine_Guy April 15, 2013 at 3:19 pm

Mathisin, Change #!/bin/sh to #!/bin/bash and your script will run without error.
/bin/sh used to be a symbolic link to /bin/bash but now it is a symbolic link to /bin/dash

36 Nagendra November 19, 2013 at 9:28 am

Hi I need to use like this
for i in $list j in $list1
do
done
may i know is there any chance like this

37 Narayan January 29, 2014 at 7:18 am

thank you

38 bill February 3, 2014 at 10:45 am

in solaris 10
for i in {1..254}; do ping 172.20.140.$i 1 |grep alive;done

39 Debashis March 25, 2014 at 12:14 am

Many thanks for the help. From this page I got all the information I was searching for my script.

40 Amadou Coulibaly June 10, 2014 at 7:18 am

I really found these examples very helpful for those who are beginners in Shell Scripting using both bash and sh. Personnaly, it has helped me to better understand For Loops in Shell Scripts.

Thank you very must for posting those kinds of knowlege online.

41 Aashish June 16, 2014 at 4:40 pm

Below code executed successfull but output will be not generated.. even its not print echo $var also. Where is it wrong. Similar as your example Number 4. Please help..

for var in `ps –help|grep Try|cut -d’>psoption
done

42 sahil June 26, 2014 at 6:19 am

Can anyone tell me ..i am using for loop in ksh …but i want to use without seq
for (( i=$start; i<=$end; i++ ))
do
echo ” i m $i”
done

bt not working

43 Maine_Guy June 26, 2014 at 1:28 pm

sahil: see my comment above about bash vs. sh. Your code works in bash but not in sh

44 ash July 7, 2014 at 6:36 am

nice articles, do you have any other posting for other loops like while and arithmetic operations, file handling etc.

45 Ravi Tyagi October 15, 2014 at 4:40 am

@@@@ Sahil

for (( i=1; i<=10 ;i++ )) ; do echo "i m $i" ;done

Leave a Comment

Previous post:

Next post: