04. Selection and Looping (Part 1)
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
if
- 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
if else
- 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
if elif
- 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
case
- 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
Nested Selection
- 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
Selection with &&
- 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