Using 'break' and 'continue' to exit loops in bash

As nice as looping in Linux scripts can be, you might just want to interrupt it sometimes, and the break and continue commands can do this.

The commands for looping in bash are extremely useful. They allow you to run a series of commands as many times as needed to process a large collection of data. The break and continue commands provide another special option. They allow you to exit a loop early or skip the remaining commands in the loop and return to the beginning.

Both the break and the continue commands are meant to be used only in for, while and until loops. In fact, if you try to invoke the break command on its own, bash will tell you just that.

$ break
-bash: break: only meaningful in a `for', `while', or `until' loop

If you ask about either command using the which command, which will respond as if it doesn’t have any idea what you’re referring to. After all, neither break nor continue is implemented as an executable file, so the which command is not going to find a pathname for you. Instead, both commands are simply built into bash.

Using the break command

If you want to exit a loop before all the commands in the loop have been run and all of the loop values have been processed, this command is just what you need; it provides a way to exit a loop prematurely. Here’s a simple illustration of what happens if a particular condition is met and the break command is run:

for, while or until loop
do
  command1
  command2
  if [ condition ]; then
    break =================+
  fi                       |
  command3                 |
done                       |
command4 <=================+

The break command exits the loop and moves to whatever command follows it.

In the example below, we give the person running the script 10 tries to guess a random number generated by the shuf command. If the person guesses the correct number, the guess is confirmed and the loop exits. Otherwise, it runs through the loop the full ten times.

#!/bin/bash

# generate a single random number
random=`shuf -i 0-99 -n1`
echo "10 tries to guess my favorite 1- or 2-digit number!"

for ((try=1; try<=10; try++))
do
  echo -n "guess $try: "
  read guess
  if [ $guess == $random ]; then
    echo "You got it!"
    break
  fi
done

Run the command, and you’ll see something like this:

$ break1
10 tries to guess my favorite 1- or 2-digit number!
guess 1: 3
guess 2: 27
guess 3: 11
You got it!

Using a while loop would work the same.

#!/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!"

while [ $try -le 10 ]
do
  echo -n "guess $try: "
  read guess
  if [ $guess == $random ]; then
    echo "You got it!"
    break
  fi
  ((try=try+1))
done

This next example uses an until loop.

#!/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

The continue command

The continue command works similarly to break, but it doesn’t exit the loop unless it’s on its last pass through it. Otherwise, it skips the remaining commands in the loop and returns to the top to continue.

for, while or until loop <=+
do                         |
  command1                 |
  command2                 |
  if [ condition ]; then   |
    continue ==============+
  fi
  command3
done
command4

In the example below, the script accepts a list of arguments like “cats dogs fish” and inserts a comma between them except for the last argument.

#!/bin/bash

numargs=$#
list=""
lastarg=${!#}

if [ $numargs > 0 ]; then
  for arg in `echo $@`
  do
    if [ $arg == $lastarg ]; then
      continue
    fi
    list="$list$arg,"
  done
fi

echo $list$lastarg

Here’s an example of running it:

$ cont1 cats dogs fish
cats,dogs,fish

Using break and continue with loops inside loops

The continue command also has the ability to go back to the top of an outer loop. If you have a script which has a loop inside a loop, using continue with a numeric argument (e.g., continue 2) will take it back to the start of the outer loop rather than the current one.

In the simple script below, any time the numbers being compared in the inner loop are equal, the script moves back to the outer loop.

#!/bin/bash

for i in {1..3}
do
  for j in {1..3}
  do
    if [[ $i -eq $j ]]
    then
      echo "$i = $j"
      continue 2
    fi
    echo "$i != $j"
  done
done

Using an argument also works with the break command. Using break 2, for example, would cause the script to exit both the current loop and the outer loop. The diagram below illustrates this. Notice how the break command exits both loops.

for, while or until loop
do
  command1
  for, while or until loop
  do
    command2
    if [ condition ]; then
      break 2 =============+
      command3             |
    fi                     |
  done                     |
  command4                 |
done                       |
command5 <=================+

Wrap-Up

The break and continue commands allow you to exit loops in bash scripts or skip remaining commands and go back to the top of a loop depending on particular situations. They can be very handy when you need to skip some commands depending on the data you are processing.

Join the Network World communities on Facebook and LinkedIn to comment on topics that are top of mind.
Related:

Copyright © 2022 IDG Communications, Inc.