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