Americas

  • United States
sandra_henrystocker
Unix Dweeb

Examining the many ways to run loops on Linux

How-To
Sep 27, 20246 mins
Linux

The looping options provided by bash include for loops, while loops and until loops. They can help you get a lot done without too much effort.

Olympic rings in front of Eiffel Tower
Credit: Luca Dugaro / Unsplash

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.

[ Find more time-saving tips in Network World’s bash command cheat sheet ]

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.

sandra_henrystocker
Unix Dweeb

Sandra Henry-Stocker has been administering Unix systems for more than 30 years. She describes herself as "USL" (Unix as a second language) but remembers enough English to write books and buy groceries. She lives in the mountains in Virginia where, when not working with or writing about Unix, she's chasing the bears away from her bird feeders.

The opinions expressed in this blog are those of Sandra Henry-Stocker and do not necessarily represent those of IDG Communications, Inc., its parent, subsidiary or affiliated companies.

More from this author