Shell Programming - Bourne

variables

creating and assigning variables

Unlike the C-shell, Bourne shell does not use the set and setenv commands to create and assign values to variables.  In the Bourne shell, typing the variable name, an equal sign and the value to which you would like it assigned makes an assignment.  If a variable of that name does not already exist in the current shell, this will create that variable in the current shell.  If a variable of that name does already exist in the current shell, this will change its value. 

            The method for knowing which variables are local and which are environmental is also different in the Bourne shell.  In the Bourne shell, this information is managed by the "export list".  The export list contains the list of variables that will be given to any shells started as children of the current shell.  To put a variable on the export list, type the command export with a variable name as the argument.

 

example:

name1=Jan

name2=Mike

export name1

In this example, name1 is an environmental variable while name2 is a local variable.

 

echo, read and expr

In Bourne shell, if you request the display of a variable which does not exist, there will be no error message.  Instead, it will display as if that variable has no value (is blank).  Another difference in the echo command is that the -n option in C-shell which prevents the end of line is replaced by a \c at the end of the string.  For input the Bourne shell uses the read utility which allows user input to be assigned into the variable given as the parameter.  The expr command is used to evaluate a mathematical expression.

#!/usr/bin/sh

#This script is to show how echo is different from the C-shell version

# how the read command can be used for input

# and how the expr command can be used to evaluate an expression

echo "Enter an integer: \c"

read int1

echo "Enter another integer: \c"

read int2

int3=`expr $int1 + $int2`

echo "Sum = $int3 and Difference = `expr $int1 - $int2`"

echo "That is all"

 

 

command line arguments

The items typed on the command line are put into a vector similar to the method used in the C-shell.  The name of the command used to run the script is put into the variable by the name $0 and its arguments are put into the next elements which are named $1…$9.  They are not named argv as it was in the C-shell since that is actually a characteristic of the C programming language.  The $1…$9 are actually called the "positional parameters" and you can access them the same way as you did in C-shell.  If there were more than 9 parameters given on the command line, the shift command must be used to bring them into these first 9 positions before they can be accessed. 

In Bourne shell, there is a set command, it just has a different purpose than the set command of the C-shell.  The set command here allows you to assign values into the positional parameters.  Giving the command followed by a list of values will put those values into the first positions of the positional parameters. 

 

example:

set  Jan Mike

echo $1

Jan

echo $2

Mike

This can be especially useful because it is an easy way to create an array of elements when those elements are normally only on a line separated by spaces.  For example, the output of the date command has many pieces of information separated from one another by spaces.  Assigning this into the positional parameters allows you to access each element individually.

 

example:

set  `date`

echo $1

Fri

echo $6

2002

conditionals

The structure of the if conditional is quite different from the structure in the C-shell programming language, but its purpose and parts are the same.  In both languages, the  if must have a condition to test and a group of shell commands that will be performed if and only if that expression evaluates to true.   In the Bourne shell the condition being evaluated is called a "test condition".   This is probably because it is often done with the utility named test.  But anything that returns the successful/unsuccessful result can be used.  The true (or successful) is assumed to be the value 0, and the false (or unsuccessful) is any non-zero value.

           

test

The test utility, has many formats for evaluating expressions.  For example, when given three arguments, will return the value true if the first and third argument hold the relation represented by the second argument, but it also has many options to test other properties of files, strings and integers.  The test utility can be used by stating the keyword test which is then followed by one of its many expression formats, or the test utility can simply be called  by putting the expression in square brackets.  Some of the possible expressions are:

int1  relational-operator   int2

compares the integers on either side according to the relational operator

(-lt,-gt, -eq, -ne,  -le, -ge)

string1 = string2

compares the two strings for equality

string1 != string2

compares the two strings for inequality

-z   string

true if the string is of length 0

-r   filename

true if you have read permission on the file named

 

            There are also compound expressions allowed in the test expression.  These are built by using the -a for "and" and the -o for "or".  You can also use parentheses to set the order of precedence and the exclamation point for not.   

 

if - then - fi

The structure of the if (one without an else) has the if and the expression to be tested on one line, followed with a then on a line by itself, followed by the body, and finally followed by a fi (if written backwards). 

 

if  test-expression

then

    commands

fi

 

The test expression will include everything between the keyword if and the end of that line.  Like the if in the C-shell, the commands in the body are each complete lines as they would be given on the shell command line (Bourne shell command line in this case).  The commands of the body are done in sequence as listed.

 

adding the else clause

The structure of the if with an else has the keyword if and the expression to be tested on one line, followed by the then on a line by itself, followed by the body to be done if the condition is true, followed by an else on a line by itself, followed by the body to be done if the condition is false, followed by a fi on its own line. 

 

if test-expression

then

     commands1

else

     commands2

fi

 

There is also the possibility of the else having an if (like there was in C-shell), but in Bourne shell, it is not written as two separate words.  The "else" and the "if" are combined to make an elif keyword.  The elif keyword is used just like the "else if" of the C-shell in that it takes its own condition but does not need its own end marker.

 

if test-expression1

then

     commands1

elif test-expression2

then

     commands2

else

     commands3

fi

 

example:

#!/usr/bin/sh

# To show the use of read and structured if

 

echo -n "first value: "

read val1

echo -n  "second value: "

read val2

echo -n "third value: "

read val3

 

if test $val1 = $val2 -a $val1 = $val3

then

   echo "complete match"

elif test $val1 = $val2 -o $val1 = $val3 -o $val2 = $val3

   then

       echo "only two match"

else

       echo "no matches"

fi  

loops

In Bourne shell there are several loop structures.  The two for looping structures are similar to the foreach of C-shell programming and the while and until loops are more similar to the while loop of C-shell programming.  In all of the loop structures of Bourne shell, the body of the loop is contained between a do (on a line by itself) and a done (also on a line by itself).  The commands in the body are any valid Bourne shell commands and will be performed in sequence.

 

for - in

The for-in loop structure uses a loop control variable specified after the keyword for.  The loop control variable takes on the values given in the list which is specified after the keyword in.  This structure is very similar to the foreach loop of C-shell.  The difference is the use of the word in rather than the parenthesis to separate the loop control variable from the list of values.

 

for    loop-var   in   list

do

       commands

done

 

for

The for loop is actually a for-in loop but using a default value for the list rather than specifying it explicitly.  The default value for the list is the argument vector (as it was called it C-shell) or the command line parameter list (as it is called in Bourne shell).  This is the most common use of the for statement is to be able to traverse the list of command line parameters.

 

for   loop-var

do

     commands

done

 

while

The while loop uses the same structure for the test-command as was used in the if statement.  The statements in the body of the while loop are performed completely and in sequence if the test-command evaluates to true. 

 

while    test-command

do

    commands

done

 

until

The until loop has the same structure as the while in that it is top-tested.  (Unlike the "do-while" loop of the C programming language.)  The while and the until are only different in the condition specified at the top.  The while loop will go into and perform the statements in the body of the loop if and only if that condition evaluates to true.  With the until loop, the statements are performed if and only if the expression evaluates to false.

 

 

until    test-command

do

    commands

done