Home‎ > ‎CIS 98‎ > ‎

Conditionals

A characteristic of programming languages is the ability to branch or skip over lines of code when certain conditions are present. The Bourne shell uses these statements to implement decision control flow:

  • if / then / fi
  • if / then / else / fi
  • if / then / elif /fi
  • case / esac
  1. Objectives
    • Define the conventional successful and unsuccessful error codes
    • Use the exit command to terminate or abort a shell script
    • Use the test command
    • Use the if statement to conditionally execute command lines
    • Use the case statement to conditionally execute command lines
    • Use special shell constructs for conditional command execution
  2. Exit Codes
    • A communication mechanism
    • Conventional exit codes
      • 0 is the exit code for successful termination of a program
      • [1-255] exit codes for unsuccessful termination of a program
    • The exit command
    • Exercise 1
    • Specialize commands with constant exit codes:
      1. The null command (:) - a shell built-in returns 0
      2. The true command - does nothing except return 0
      3. The false command - does nothing except return with a non-zero exit status
  3. The test Command
    The test command is a shell built-in, but has a binary counterpart which may be invoked with the symbollic link: [
    1. Testing File Status
      test option file or [ string1 option string2 ]
      • -r True if the file exists and is readable
      • -w True if the file exists and is writable
      • -x True if the file exists and is executable
      • -f True if the file exists and is a regular file
      • -d True if the file exists and is a directory
      • -L True if the file exists and is a symbolic link
      • -c True if the file exists and is a character special device file
      • -b True if the file exists and is a block special device file
      • -s True if the file exists and has a size greater than zero
      • -t n True if open file descriptor n is attached to a terminal device
    2. Testing Character Strings
      test string1 option string2 or [ string1 option string2 ]
      test option string1
       or [ option string1 ]
      • = True if string1 and string2 are identical
      • != True if string1 and string2 are not identical
      • -z True if the length of string1 is zero
      • -n True if the length of string1 is not zero (-n is optional)
    3. Testing Integer Expressions
      test string1 option string2 or
      [ string1 option string2 ]
      • -eq True if string1 is algebraically equal to string2
      • -ne True if string1 is algebraically not equal to string2
      • -lt True if string1 is algebraically less than string2
      • -le True if string1 is algebraically less than or equal to string2
      • -gt True if string1 is algebraically greater than string2
      • -ge True if string1 is algebraically greater than or equal to string2
    4. Testing Logical Operations
      expression operator expression or
      operator expression
      • ! Logical NOT operator
      • -a Logical AND operator
      • -o Logical OR operator
      You may use () parentheses to associate nested boolean expressions, but the shell requires that you escape the symbols ( and )
  4. The if Statement
    1. Syntax
    2. Execution
    3. The else statement
    4. The elif statement
    5. Nested if statements
    6. Exercise 3
  5. The case Statement
    1. Syntax
    2. Execution
    3. Exercise 4
  6. Special Constructs
    The shell also has the && and || decision constructs which are shorthand notations for the if construct discussed earlier.
    Do not confuse these logical operators with the -a and -o operators of the test command.
     
    command1 && command2
    is euivalent to:
    if command1
    then
    	command2
    fi
    command1 || command2
    is equivalent to:
    if command1
    then
    	: # do nothing
    else
    	command2
    fi

Exercise 1: Viewing and exit status

Use the echo command to determine the exit status of these commands:
grep root /etc/passwd
grep route /etc/passwd
grep root /etc/password

Exercise 2: Using the test command

Indicate the test command for these conditions:
  • Is $FILE a directory with both read and search permissions?
     
  • Is $DEVICE a character special file with either read or write permission?
     
  • Has the standard input been redirected?
     
  • Did a user answer a prompt with a "no" response? (Allow for any permutation in the capitalization of the word "No".)
     
  • Is the current number of positional parameters not greater than 12?

Exercise 3: Nested if Statements

Modify the program fragment below to add this functionality:
  • Allow the user to enter upper or lower case one-character responses.
  • Respond to input that may be neither y or n with the message, "Unknown Response", and then exit.
  • Modify the code so that the message, "Installation cannot proceed" is displayed whenever the user chooses to bail out.
=============================================================
echo -n "Do you want to format the disk now? [y/n] "
read REPLY1 DUMMY
if [ "$REPLY1" = y ]
then
	echo -n "Are you sure? [y/n] "
	read REPLY2 DUMMY
	if [ "$REPLY2" = y ]
	then
		echo -n "Last chance. Are you really really sure? [y/n] "
		read REPLY3 DUMMY
		if [ "$REPLY3" = y ]
		then
			echo Formatting ...
			/sbin/mkfs "$DISK"
		fi
	fi
else
	echo "Installation cannot proceed at this time.  Please backup the date
		on the disk and try again later."
	exit 1
fi

Exercise 4: The case Statements

  • Simplify each of these case statement patterns with ones that use wildcards:
    NO|no|No|nO)
    
    s|S)
    
    21|22|23|24|25|26|29)
    
  • What pattern matches any three character string that begins with either "y" or "Y"?
     
  • What pattern matches any string that does not begin with an "n" or "N"?

Exercise 5: The && and || Constructs

Rewrite each of the following command lines using the if construct:
  • [ -r report -a -w report ] && vi report
  • mkdir /tmp/dir$$ && cd /tmp/dir$$ && PS1="`pwd` "
  • mkdir /tmp/dir$$ || echo "Cannot create /tmp/dir$$" >&2
  • write jeff < message || mail -s 'Read this' jef < message
Comments