Bash - Loops¶
Objectives: In this chapter you will learn how to:
use loops;
linux, script, bash, loops
Knowledge:
Complexity:
Reading time: 20 minutes
The bash shell allows for the use of loops. These structures allow for the execution of a block of commands several times (from 0 to infinity) according to a statically defined value, dynamically or on condition:
while
until
for
select
Whatever the loop used, the commands to be repeated are placed between the words do
and done
.
The while conditional loop structure¶
The while
/ do
/ done
structure evaluates the command placed after while
.
If this command is true ($? = 0
), the commands placed between do
and done
are executed. The script then returns to the beginning to evaluate the command again.
When the evaluated command is false ($? != 0
), the shell resumes the execution of the script at the first command after done.
Syntax of the conditional loop structure while
:
while command
do
command if $? = 0
done
Example using the while
conditional structure:
while [[ -e /etc/passwd ]]
do
echo "The file exists"
done
If the evaluated command does not vary, the loop will be infinite and the shell will never execute the commands placed after the script. This can be intentional, but it can also be an error. So you have to be very careful with the commands that manage the loop and find a way to get out of it.
To get out of a while
loop, you have to make sure that the command being evaluated is no longer true, which is not always possible.
There are commands that allow you to change the behavior of a loop:
exit
break
continue
The exit command¶
The exit
command ends the execution of the script.
Syntax of the exit
command :
exit [n]
Example using the exit
command :
bash # to avoid being disconnected after the "exit 1
exit 1
echo $?
1
The exit
command ends the script immediately. It is possible to specify the return code of the script by giving it as an argument (from 0
to 255
).
If no argument is given, the return code of the last command of the script will be passed to the $?
variable.
The break
/ continue
commands¶
The break
command allows you to interrupt the loop by going to the first command after done
.
The continue
command allows you to restart the loop by going back to the first command after done
.
while [[ -d / ]] INT ✘ 17s
do
echo "Do you want to continue? (yes/no)"
read ans
[[ $ans = "yes" ]] && continue
[[ $ans = "no" ]] && break
done
The true
/ false
commands¶
The true
command always returns true
while the false
command always returns false
.
true
echo $?
0
false
echo $?
1
Used as a condition of a loop, they allow for either an execution of an infinite loop or the deactivation of this loop.
Example:
while true
do
echo "Do you want to continue? (yes/no)"
read ans
[[ $ans = "yes" ]] && continue
[[ $ans = "no" ]] && break
done
The until
conditional loop structure¶
The until
/ do
/ done
structure evaluates the command placed after until
.
If this command is false ($? != 0
), the commands placed between do
and done
are executed. The script then returns to the beginning to evaluate the command again.
When the evaluated command is true ($? = 0
), the shell resumes the execution of the script at the first command after done
.
Syntax of the conditional loop structure until
:
until command
do
command if $? != 0
done
Example of the use of the conditional structure until
:
until [[ -e test_until ]]
do
echo "The file does not exist"
touch test_until
done
The alternative choice structure select
¶
The structure select
/ do
/ done
allows for the display of a menu with several choices and an input request.
Each item in the list has a numbered choice. When you enter a choice, the value chosen is assigned to the variable placed after select
(created for this purpose).
It then executes the commands placed between do
and done
with this value.
- The variable
PS3
contains the invitation to enter the choice; - The variable
REPLY
will return the number of the choice.
A break
command is needed to exit the loop.
Note
The select
structure is very useful for small and simple menus. To customize a more complete display, the echo
and read
commands must be used in a while
loop.
Syntax of the conditional loop structure select
:
PS3="Your choice:"
select variable in var1 var2 var3
do
commands
done
Example of the use of the conditional structure select
:
PS3="Your choice: "
select choice in coffee tea chocolate
do
echo "You have chosen the $REPLY: $choice"
done
If this script is run, it shows something like this:
1) Coffee
2) Tea
3) Chocolate
Your choice : 2
You have chosen choice 2: Tea
Your choice:
The loop structure on a list of values for
¶
The for
/ do
/ done
structure assigns the first element of the list to the variable placed after for
(created on this occasion). It then executes the commands placed between do
and done
with this value. The script then returns to the beginning to assign the next element of the list to the working variable. When the last element has been used, the shell resumes execution at the first command after done
.
Syntax of the loop structure on list of values for
:
for variable in list
do
commands
done
Example of using the conditional structure for
:
for file in /home /etc/passwd /root/fic.txt
do
file $file
done
Any command producing a list of values can be placed after the in
using a sub-execution.
- With the variable
IFS
containing$' \t\n'
, thefor
loop will take each word of the result of this command as a list of elements to loop on. - With the
IFS
variable containing$'\t\n'
(i.e. without spaces), thefor
loop will take each line of the result of this command.
This can be the files in a directory. In this case, the variable will take as a value each of the words of the file names present:
for file in $(ls -d /tmp/*)
do
echo $file
done
It can be a file. In this case, the variable will take as a value each word contained in the file browsed, from the beginning to the end:
cat my_file.txt
first line
second line
third line
for LINE in $(cat my_file.txt); do echo $LINE; done
first
line
second
line
third line
line
To read a file line by line, you must modify the value of the IFS
environment variable.
IFS=$'\t\n'
for LINE in $(cat my_file.txt); do echo $LINE; done
first line
second line
third line
Author: Antoine Le Morvan
Contributors: Steven Spencer, Ganna Zhyrnova