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 wordsdo and done.
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:
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 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 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 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', the for 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), the for 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