The bash shell provides numerous ways to loop through data to make your work – especially scripting challenges – easier.
You can loop through a pile of data so you can get a lot done just by running a single script, and you can generate and loop through different sequences of values. Whether you’re looping through a large group of numeric values, days of the week, usernames, words, file names or something else entirely, bash has an option that can make it easier for you.
The looping options provided by bash include for loops, while loops and until loops. This post includes examples of each of these options, ranging from simple to fairly complicated.
Using for loops
Probably the simplest loop is a for loop like the one below. It loops as many times as there are pieces of text listed as arguments (in this case 1, 2, 3 and 4). We could just as easily loop through the words “cats are very smart” as the numbers 1, 2, 3 and 4.
#!/bin/bash for num in 1 2 3 4 do echo $num done
As suggested above, loops like these are not restricted to numeric variables. You can also loop through other types of variables – strings like colors, states, planets or the days of the week. Here’s an example:
$ for day in Sun Mon Tue Wed Thu Fri Sat > do > echo -n "Plans for $day> " > read plan > echo $day $plan >> week > done Plans for Sun> sleep until noon Plans for Mon> go to the park Plans for Tue> write letters Plans for Wed> think over problems Plans for Thu> shop Plans for Fri> clean up Plans for Sat> party
After you run this script and provide your plans, the “week” file will remind you about how you intend to spend each day of your week.
You could use a loop like those shown below to run through the letters of the alphabet or a sequence of numbers.
$ for x in {a..z} do echo $x done $ for x in {1..11}; do echo $x; done
The for command below would display calendars for the last three months of the current year.
$ year=`date +%Y`; for month in {10..12}; do cal $month $year; done
The script below loops through all the months of the year.
$ for month in `locale mon | sed 's/;/ /g'`; do echo $month; done January February March April May June July August September October November December
Using while loops
While loops keep looping as long as the condition that they’re set up to monitor is true. Here’s an example:
#!/bin/bash n=1 while [ $n -le 4 ] do echo $n ((n++)) done
The script above increments and displays the value of $n as long as it’s less than or equal to 4. You can get a while loop to run forever (i.e., until the system crashes, you log out, or someone kills your script) using “while true” as shown below. The sleep command ensures that it doesn’t run thousands of times before you have a chance to stop it.
#!/bin/bash while true do echo -n "Still running at " date sleep 10 done
The script below will run as long as the user who it’s waiting for has not yet logged into the system. This can be helpful when you’re waiting for a co-worker to address a problem before you can move ahead with your task. It checks once a minute to see if the user has logged in yet.
#!/bin/bash echo -n "user to wait for> " read user while [ `who | grep $user | wc -l` == 0 ] do echo waiting sleep 60 done echo $user is online
Using until loops
Until loops keep running until the condition that they’re waiting for is true. To accomplish the same thing as the previous script, we could use one with an until command like this that runs until the count of the user being waited for is greater than 0.
#!/bin/bash until [ `who | grep $user | wc -l` -gt 0 ] do echo waiting sleep 60 done
Looping inside loops
There’s also nothing stopping you from using a looping command inside another loop. In this example, we’re using a for loop inside a while loop.
#!/bin/bash n=1 while [ $n -lt 6 ] do for l in {a..d} do echo $n$l done ((n++)) done
This script will run through the letters a, b, c and d for the numbers 1 through 5.
The break and continue commands
The break and continue commands can be used to influence how bash loops work. The break command will exit the loop skipping over any remaining commands in the loop while the continue command will skip the remaining commands within the loop and return to the start of the loop. In the script below, the break command is run and the loop terminated when the user guesses a randomly selected 1- or 2-digit number.
#!/bin/bash # generate a single random number random=`shuf -i 0-99 -n1` try=1 echo "10 tries to guess my favorite 1- or 2-digit number" until [ $try -gt 10 ] do echo -n "guess $try: " read guess if [ $guess == $random ] then echo "You got it!" break fi ((try=try+1)) done
Wrap-up
The for, while and until loops can help you get a lot done without too much effort and offer a wide range of options for how you set up the range of values that they will loop through.
Source:: Network World