Home Bash scripting Bash Scripting – While And Until Loop Explained With Examples

Bash Scripting – While And Until Loop Explained With Examples

By Karthick
1,433 Views

This is a continuation article in bash loop wherein the previous article we have explained about for loop. In this article, we will take a look at two more bash loops namely, while and until loop.

The while loop is mostly used when you have to read the contents of the file and further process it. Reading and writing to a file are common operations when you write bash scripts. We will see how to read files using a while loop.

We already have a very detailed article on how to write to a file using redirection operators.

The functionality of the while loop is similar to for loop. The for loop iterates over a list of items and runs the block of code N a number of times. Here in the while loop, the condition is evaluated first, and if the condition is true, the block of code will be executed until the condition is evaluated to false.

1. While loop

Below is the while loop syntax. The loop starts with the "while" keyword followed by a condition that should be evaluated to be true. Between do and done block is where your codes will be placed that will be iterated N number of times.

while [[ condition ]]
do
  Command 1
  Command 2
  ....
  Command 3
done

EXAMPLE 1 - Evaluate and iterate

Take a look at the below example. Here I have created a variable "NUM=5" and my condition ($NUM -ne 0) is, the loop will execute if the variable NUM is not equal to zero.

$ NUM=5
while [[ $NUM -ne 0 ]]
do
  printf "Value of NUM = $NUM \n"
  ((--NUM))
done
Evaluate and iterate
Evaluate and iterate

You should use counters to increment or decrement values stored in variables when working with while loops. If not, it will become an infinite loop and NUM will always be set to five. Here I am decrementing the value of NUM in every iteration by running ((--NUM)), so when my variable NUM is set to zero, the loop exit.

((++NUM))  → Increment NUM variable by 1, similar to running NUM=$(( $NUM + 1 ))
((--NUM))  → Decrement NUM variable by 1, similar to running NUM=$(( $NUM - 1 ))

EXAMPLE 2 - Infinite loops

An infinite loop is where your condition is always evaluated to true and the loop will never exit.

To create infinite loops, you can use the bash-builtin true keyword. Also, use the "sleep" command when testing infinite loops which will give you control in stopping the script else your screen will be flooded with fast scrolling outputs.

$ NUM=0
while true
do
  printf "Value of NUM = $NUM \n"
  ((++NUM))
  sleep 2
done
Infinite while loop
Infinite while loop

EXAMPLE 3 - Internal field separator (IFS)

IFS is a special shell variable that decides how your word boundaries are handled. By default, IFS is set to space, tab, and a newline character. Open the terminal and run the following commands:

$ var1="foo:bar foo bar"
$ for val in $var1
do
  echo $val
done 
Default IFS
Default IFS

Take a look at the output. The for loop is iterating over a string and it is IFS which decides the word boundaries and considers space as a field separator.

Now run the below code again. Here IFS is set to the colon.

$ var1="foo:bar foo bar"
$ IFS=":"
$ for val in $var1
do
  echo $val
done
Custom IFS
Custom IFS

From the above output, you can see that the custom field separator colon is used as a word boundary. You can set the IFS back to the default state by running the unset command.

$ unset IFS

EXAMPLE 4 - Read file using while loop

The while loop is recommended when you want to read a file line by line and process it.

Create a new file called test.txt using the following content. There is an empty line after line 2 to show the behavior of how empty lines are handled.

14:00 Brighton v Leicester
14:00 West Ham v Man Utd

16:30 Spurs v Chelsea

We will use the read command which accepts input from redirection and store it in a variable along with an input redirection operator where the file name will be redirected to the while loop. The read command will use the default IFS to set the word split boundary.

$ while read line
do
  echo $line
done < test.txt
Read file using while loop
Read file using while loop

In the above example, test.txt file is redirected to the while loop and read command reads line by line and stores it in the variable "line" and it is further processed within the loop. Empty lines are not skipped when you follow this method and this is not the behavior you might want. So you have to explicitly make empty lines to be skipped.

There are multiple options to trim out empty lines from the input file. You can use sed, awk, and conditional statements, etc. I prefer using both awk and sed to clean up the empty lines before looping them using a while loop.

# USING SED
$ sed -i '/^[[:space:]]*$/d' test.txt
14:00 Brighton v Leicester
14:00 West Ham v Man Utd
16:30 Spurs v Chelsea
# USING AWK
$ awk 'NF' test.txt
Remove empty lines using sed and awk
Remove empty lines using sed and awk

As seen in previous examples, you can modify IFS depending upon how you want to read your file. For example, if you are handling a CSV file then the delimiter can be set to a comma. I have modified the same input file to be in CSV format.

14:00,Brighton,Leicester
14:00,West Ham,Man Utd
16:30,Spurs,Chelsea

In the below example, IFS is set to comma (IFS=",") and each field will be stored in a separate variable (time, team1, team2).

while IFS="," read time team1 team2
do
   echo "$team1 is playing against $team2 at $time"
done < test.txt
Reading CSV files
Reading CSV files

EXAMPLE 5 - Loop flow control with Break and Continue

If you have read our bash for loop article, you might know what is break and continue used for. Both break and continue are bash builtin keywords that will help you to control the flow of your loop.

The "break" keyword will completely exit the loop and pass control to the next command in the script. In the below example. When the NUM is equal to three, the loop will be exited by the break command.

$ NUM=5
while [[ $NUM -ne 0 ]]
do
  printf "Value of NUM = $NUM \n"
  if [[ $NUM -eq 3 ]]
  then
    break
  fi   
((--NUM))
done
While loop with break statement
While loop with break statement

The "continue" keyword will skip the current iteration and give the control back to the while loop and start the next iteration.

$ NUM=0
while [[ $NUM -lt 5 ]]
do
 ((++NUM))
 if [[ $NUM -eq 3 ]]
 then
   continue
 fi
 printf "Value of NUM = $NUM \n"  
done
While loop with continue statement
While loop with continue statement

2. Until Loop

The until loop is the exact opposite of the while loop. The while loop evaluates the condition to be true to execute the block of code and the until loop evaluates the condition to be false for the loop to be executed.

The syntax is the same as the while loop but instead of the keyword while, until will be used.

until [[ condition ]]
do
  Command 1
  Command 2
  ....
  Command 3
done

From the below example, you can see until loop evaluates the variable NUM to be greater than equal to five. It is false since NUM is set to zero and will increment in subsequent iterations using ((++NUM)). So when NUM is equal to five the condition is evaluated to be true and until loop will stop executing.

$ NUM=0
$ until [[ $NUM -ge 5 ]]
do
  echo $NUM
  ((++NUM))
done
Until loop
Until loop

To create infinite loops, you can use the keyword "false".

$ NUM=0
$ until false
do
  echo $NUM
  ((++NUM))
done

To control the loop flow, you can use the break and continue keywords like as shown in the while loop section above.

Conclusion

In this article, we have seen how to use while loop and until loop in bash scripts. Until loop is least frequently used compared to for and while loops but that is to decide on your script and what types of the loop are required. Be comfortable in using all three loops.

If you've any questions or feedback, feel free to let us know via the comment section below.

You May Also Like

Leave a Comment

* By using this form you agree with the storage and handling of your data by this website.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More