New Document
Control Constructs

The flow of control within SH scripts is done via four main constructs; if...then...elif..else, do...while, for and case. :


This construct takes the following generic form, The parts enclosed within ([) and (]) are optional:

if list
then list 
[elif list
then list] ...
[else list]
  • When a Unix command exits it exits with what is known as an exit status, this indicates to anyone who wants to know the degree of success the command had in performing whatever task it was supposed to do, usually when a command executes without error it terminates with an exit status of zero. An exit status of some other value would indicate that some error had occurred, the details of which would be specific to the command. The commands' manual pages detail the exit status messages that they produce.
  • A list is defined in the SH as "a sequence of zero or more commands separated by newlines, semicolons, or ampersands, and optionally terminated by one of these three characters.", hence in the generic definition of the if above the list will determine which of the execution paths the script takes. For example, there is a command called test on Unix which evaluates an expression and if it evaluates to true will return zero and will return one otherwise, this is how we can test conditions in the list part(s) of the if construct because test is a command.
  • We do not actually have to type the test command directly into the list to use it, it can be implied by encasing the test case within ([) and (]) characters, as illustrated by the following (silly) example:
if [ "$1" = "1" ]
   echo "The first choice is nice"
elif [ "$1" = "2" ]
   echo "The second choice is just as nice"
elif [ "$1" = "3" ]
   echo "The third choice is excellent"
   echo "I see you were wise enough not to choose"
   echo "You win"
  • What this example does is compare the first parameter (command line argument in this case) with the strings "1", "2" and "3" using tests' (=) test which compares two strings for equality, if any of them match it prints out the corresponding message. If none of them match it prints out the final case. OK the example is silly and actually flawed (the user still wins even if they type in (4) or something) but it illustrates how the if statement works.
  • Notice that there are spaces between (if) and ([), ([) and the test and the test and (]), these spaces must be present otherwise the shell will complain. There must also be spaces between the operator and operands of the test otherwise it will not work properly. Notice how it starts with (if) and ends with (fi), also, notice how (then) is on a separate line to the test above it and that (else) does not require a (then) statement. You must construct this construct exactly like this for it to work properly.
  • It is also possible to integrate logical AND and OR into the testing, by using two tests separated by either "&&" or "||" respectively. For example we could replace the third test case in the example above with:
elif [ "$1" = "3"] || [ "$1" = "4" ]
then echo "The third choi...

The script would print out "The third choice is excellent" if the first parameter was either "3" OR "4". To illustrate the use of "&&" we could replace the third test case with:

elif [ "$1" = "3"] || [ "$2" = "4" ]
then echo "The third choi...

The script would print out "The third choice is excellent" if and only if the first parameter was "3" AND the second parameter was "4".


The Do...While takes the following generic form:

while list            
do list            

In the words of the SH manual "The two lists are executed repeatedly while the exit status of the first list is zero." there is a variation on this that uses until in place of while which executes until the exit status of the first list is zero. Here is an example use of the while statement:

while list            
count=$1                                   # Initialise count to first parameter 
while [ $count -gt 0 ]                     # while count is greater than 10 do
   echo $count seconds till supper time!
   count=$(expr $count -1)                 # decrement count by 1
   sleep 1                                 # sleep for a second using the Unix sleep command
echo Supper time!!, YEAH!!                 # were finished 

If called from the commandline with an argument of 4 this script will output

while list            
4 seconds till supper time!
3 seconds till supper time!
2 seconds till supper time!
1 seconds till supper time!
Supper time!!, YEAH!!  
For loop

The syntax of the for command is:

   for variable in word ...
            do list

The SH manual states “The words are expanded, and then the list is executed repeatedly with the variable set to each word in turn.”. A word is essentially some other variable that contains a list of values of some sort, the for construct assigns each of the values in the word to variable and then variable can be used within the body of the construct, upon completion of the body variable will be assigned the next value in word until there are no more values in word. An example should make this clearer:

fruitlist="Apple Pear Tomato Peach Grape"
for fruit in $fruitlist
   if [ "$fruit" = "Tomato" ] || [ "$fruit" = "Peach" ]
      echo "I like ${fruit}es"
      echo "I like ${fruit}s"

In this example, fruitlist is word, fruit is variable and the body of the statement outputs how much this person loves various fruits but includes an if...then..else statement to deal with the correct addition of letters to describe the plural version of the fruit, notice that the variable fruit was expressed like ${fruit} because otherwise the shell would have interpreted the preceding letter(s) as being part of the variable and echoed nothing because we have not defined the variables fruits and fruites When executed this script will output:

  I like Apples
I like Pears
I like Tomatoes 
I like Peachs
I like Grapes

Here is a simple example of loop nesting, let's add another countdown loop inside the loop that you used to count to nine:


while [ "$a" -lt 10 ]    # this is loop1
   while [ "$b" -ge 0 ]  # this is loop2
      echo -n "$b "
      b=`expr $b - 1`
   a=`expr $a + 1`
Previous                                                                                                                                                       Next

Back to Top