Overview
The statements in a script often will not need to be run one after another from top to bottom
Sometime you want to skip a certain block of code or you want to repeat a certain block
The shell has programming constructs to control the flow of execution
This module covers these programming constructs
Selection constructs
if
if else
if elif
case
Looping constructs
while
until
for in
Control constructs
break
continue
The if statement tests a condition to see whether a block of commands should run or not
Format:
if [ conditional expression ]
then
commands
fi
You can use [[ ]] or (( )) in place of [ ]
When the conditional expression evaluates to true, then the commands run
When the conditional expression evaluates to false, then the commands will not run, and execution will move to the commands after the fi
The then line needs to be on a separate line from the if line
It is recommended that you keep the indentation as shown
Example
if [ -r $file ] # if file exists and has read access
then # then
echo $file exists # print message to screen
ls –l $file # and do long listing of file
fi
The if else statement tests a condition to see which one of 2 blocks of commands should run
Format:
if [ conditional expression ]
then
commands for true block
else
commands for false block
fi
You can use [[ ]] or (( )) in place of [ ]
When the conditional expression evaluates to true, then the commands for true block run
When the conditional expression evaluates to false, then the commands for false block will run
If one block is chosen to run, then the other block will not run
It is recommended that you keep the indentation as shown
Example
if [ -r $file ] # if file exists and has read access
then # then
echo $file exists # print message
ls –l $file # and do long listing of file
else # if file does not exist or has read access
echo $file not found # print error message
fi
The if elif statement is used when there are multiple possible conditions, but only one of the conditions should be true
elif is short for else if
Format:
if [ first conditional expression ]
then
commands for first condition
elif [ second conditional expression ]
then
commands for second condition
elif [ third conditional expression ]
then
commands for third condition
else
commands for last condition
fi
You can use [[ ]] or (( )) in place of [ ]
When a particular conditional expression evaluates to true, then only the commands for that block run
There can be as many elif [ …] then commands as there are number of conditions
It is recommended that you keep the indentation as shown
Example
if [ -f $file ] # 1st condition: it’s a regular file
then
echo $file is a regular file
elif [ -d $file ] # 2nd condition: it’s a directory
then
echo $file is a directory
elif [ -h $file ] # 3rd condition: it’s a link
then
echo $file is a link
else # last condition
echo $file is a device or pipe or socket
fi
This is a good situation to use the if elif statement, because a file can only be one of several types of file
The case statement is used to test when a string matches one of multiple patterns
Logically it is similar to the if elif construct in that only one condition out of multiple conditions will be true. However, the case construct is used for matching a string to one of multiple patterns
Format:
case string in
pattern1)
commands for first pattern
;;
pattern2)
commands for second pattern
;;
pattern3)
commands for third pattern
esac
When the string matches a particular pattern, then the commands for that pattern runs, and no other command block will run
A pattern is a string and can contain wildcard characters (but is not a regular expression)
There can be as many pattern) as needed
It is recommended that you keep the indentation as shown
Example
case $file in
*.c) # first pattern
echo C file
;;
*.cpp) # second pattern
echo “C++ file”
;;
*.pl) # third pattern
echo Perl file
;;
*) # pattern matching everything else
echo some other type of file
esac
All selection statements can be nested. Within each command block that is chosen to run, there can be another selection statement
When nesting selection statements, make sure you close the if or case statement at the right location so the logic works out
Example of a nested selection construct
if [ -f $file ] # outer condition
then
echo $file is a regular file
if [ -r $file ] # inner condition
then
echo read access
elif [ -w $file ] # another inner condition
then
echo write access
else [ -x $file ] # last inner condition
echo execute access
fi # end of inner selection
else # another outer condition
echo not a regular file
fi # end outer selection
Recall that the && operator is for logical AND
When the shell evaluates an expression with &&, it uses a short cut:
If the expression on the left of && is false, the entire expression is already false. Therefore, the shell will not need to evaluate the expression on the right, and it won’t.
For example, in the command line: expr1 && expr2
if expr1 is false, then expr2 will not need to be evaluated (will not be run) because the shell already concludes that the whole command line is false
if expr1 is true, then the shell cannot conclude yet whether the entire command line is true or false, so it will need to evaluate expr2
This is effectively an if construct: if expr1 is false, expr2 will not run if expr1 is true, expr2 will run
The command line expr1 && expr2 is equivalent to:
if [ expr1 ]
then
expr2
fi
Example
users=`who | wc –l` # number of users currently logged in
[ $users -lt 10 ] && echo there are few users logged in
# - will print “there are few users logged in” if $users is less than 10
# - will not print the text if $users is greater than or equal 10