UNIX
© Copyright B. Brown, 1988-2000. All rights reserved. March 2000.
Previous PageIndexNext Page

Assignment 3: Shell Programming


The objective of the following exercises is to introduce you to shell programming. At the end of these exercises you will be able to

 

Shell Programming
Shell programming is using Unix commands to perform actions like sorting, editing, re-arranging, merging and formatting files. Commands are strung together to form miniature applications.

This module builds on the previous modules of [OS100] shell commands and the vi editor. During this module, you will use the shell commands to process files created with the vi editor. Handy access to the previous two modules will prove valuable in completing the various exercises scattered throughout this module.

 

Shell Commands
The shell processes user commandsaccept parametersbe executable programs which ordinary . These commands can , or text files containing shell command lines (script files).

For script files, the shell spawns another instance of itself to read the file and execute the commands in it. This is known as a shell procedure.

The shell searches the shell variable path for finding commands. The shell uses a preset method of locating the command, by searching for the command in each of the following directories (in the order specified).

 

Shell Variables
A variable is a name representing a string value. In this example, the variable 'today' is assigned the value "Wednesday".

$ today="Wednesday"

 

User Defined Shell Variables
The format for creating a shell variable is,

name=string

Consider the following example, which saves the current working directory (calculated by the command pwd) into the shell variable homedir.

$ homedir=`pwd`

To use the variable within the shell, it is preceded by a $. The following example uses the value stored in the shell variable homedir to switch directories.

$ cd $homedir

 

Predefined Shell Variables
The shell uses a number of variables. Some of these are

Variable Meaning
HOME name of users login directory
IFS internal field separators
PATH search path used for finding commands
PS1 shell prompt

The shell variables are printed out on the console screen by typing the keyword set.

Fill in the following table with your shell variable states (Hint, use the set command).

Variable Current Value
HOME  
PATH  
TERM  
PS1  

 

Change the PS1 shell variable to the text string "hello ". Enter the command you used to do this in the space provided below.

..........................................................................

What happened to the UNIX prompt symbol?

..........................................................................

Reset the PS1 shell variable back to its original value, as a text string equal to what you found in the previous exercise and filled in the table on the previous page.

 

Shell arguments and quotes
The shell supports pattern matching and recognition. The patterns supported by the shell are,

Argument Meaning
* Match all characters in a string
? Match a single character

These matching characters (called wildcard characters) are used in the same way as other operating systems like MS-DOS. When you type a command, the shell program interprets symbols like the wildcard characters according to pre-defined rules. The following example lists all files ending in .dat in the current directory.

$ ls *.dat
data1.dat
text.dat
$

What is the command to list all the files in the current directory which begin with a . (period) character. Enter the command in the space provided below.

............................................

Does it work?? YES NO. If NO… why do you think this might be so?

………………………………………………………………………………………….

………………………………………………………………………………………….

Other characters also have special meaning to the shell. These are interpreted according to special rules, and often lead to confusion, because of the way in which the shell interprets them.

< > * ? [ ]

To use these special characters as arguments to the shell, they are enclosed using single or double quotes.

For example, the following statement assigns the text string 'cp * $1' to the shell variable copyall.

$ copyall = 'cp * $1'

The contents are printed out by typing the command (this shows that the shell has created a new variable called copyall and set its value to the string cp * $1.

$ set
....
.…
copyall=cp * $1
ignoreeof=10
$

Without the quotes around "cp * $1", the shell will try to execute the command 'cp * $1', rather than assign it to the new shell variable copyall. This means the copy command will be invoked to copy all files (*) to the filename specified in argument one ($1).

Type the command this time without quotes!

$ copyall=cp * $1

What is printed?

………………………………………………………………………………………….

………………………………………………………………………………………….

Within double quotes, the characters $, \, ` and " retain their special meaning to the shell. If you use these characters inside double quotes, the shell interprets them according to preset rules. To over-ride this, precede these characters with a backslash (\).

To examine this, consider the following example where the text string

The man said "hello".

is assigned to a shell variable. To assign this to a shell variable called string, the user types

$ string="The man said " hello "."

and the shell interprets this as equivalent to

"The man said" + hello + "."

as the second double quote is interpreted by the shell as finishing the text string. The shell thus interprets the word "hello" as a command, and tries to run it.

To prevent the shell from interpreting the second double quote as an end of string termination, it is preceded by a backslash.

$ string="The man said \" hello \"."

Typing set to now display the value of the shell variables reveals,

$ set
.....
....
string=The man said " hello ".
$

Complete the following table (HINT: assign each of the values to a shell variable, then use the set command to display the result, as in the previous examples).

Input Shell Interprets as
'`' back quotation mark
one two the string "one two"
""  
"\""  
"`"  
'one * two"  

 

Shell standard input and output
Most Unix commands do not care where their input is derived from, or where their output is written. This feature allows commands to work with files, devices, terminals and other commands.

There are three standard devices associated with a command when it executes.

Device Name File Descriptor Normally associated with
stdin standard input 0 Keyboard
stdout standard output 1 Console
stderr standard error 2 Console

 

Standard Device Redirection Operators
In addition, the following characters have special meaning to the shell, describing the origin of stdin and stdout associated with a shell command. They are called redirection operators.

Redirection is always used with files, never with other programs. Stdin can be redirected to read commands from a file instead of the keyboard, and stdout redirected to write to a file rather than the console screen.

Symbol Meaning
> redirect stdout, create new
>> append to stdout
< redirect stdin

The following example shows an example of redirecting stdin. The program sort normally reads from stdin, but in this example is instructed to read its input from the file input.dat (don’t type the following command, it's only an example!)

$ sort < input.dat

 

Redirecting stdout
The following example creates a file called user.log that contains a list of the currently logged in users. Note that the standard output for the who command has been redirected from the terminal console to the file users.log. In other words, the file users.log holds the output of the command who, instead of the output being displayed on the console screen. If the file users.log already exists, it will be erased then created anew (Don’t type the following command, it's only an example!)

$ who > users.log

 

Redirecting stderr
Error output from Unix commands is associated with file descriptor 2, and by default goes to the console screen.

The following command redirects stderr for the executed command to a file called 'errors'. Note the use of the file descriptor preceding the redirection symbol (Don’t type the following command, it's only an example!).

$ cc test.c 2>> errors

Note that the file descriptor precedes the redirection symbol without space or tab characters. The above example runs the UNIX C compiler on the source file test.c, and writes the error output to the file errors.

 

Pipelines
Pipes are a means of interconnecting commands together. The output of one command becomes the input to another. Consider the following example using redirection, using an intermediate file temp1 (don’t type the following command, it's only an example!).

$ who > temp1
$ wc -l < temp1 > users

This example counts the number of users currently logged in, using a file called 'temp1'.

A pipe alternative is shown below. The two commands are connected via the pipe (a vertical bar, |), and this eliminates the need for the temporary file temp1 (don’t type the following command, it's only an example!).

$ who | wc -l > users

Note that the following example is wrong!

$ who > wc -l > users

because programs can only be connected together via pipes.

 

What is the command pipeline you would use to search the output of who for a user called joe (HINT: Use the commands who and grep, connected via a pipe). Enter the actual command is the space provided below.

...........................................................................

 

Command Substitution
Any command line can be placed within back quotation marks so that the output of the command replaces the quoted command line itself. This is known as command substitution.

The command or commands enclosed between the back quotation marks are first executed by the shell, then their output replaces the whole expression, back quotation marks included. This feature is most often used to assign shell variables.

$ today=`date`

In the above example, the command date returns the current date and time, which is then assigned to the shell variable today.

Consider the following examples. In the first example, the shell variable today is assigned the value date. In the second example, it is assigned the output of the program date, giving a different result.

$ today=date
$ set
today=date
$ today=`date`
$ set
today=Thursday 6th April, 1994
$

What is the command you would use to assign the output of the command pwd into the shell variable homedir. Write the actual command in the space provided below.

.................................................

 

Shell Positional Parameters
When a shell is invoked, it creates positional parameters which reflect the position of the arguments on the command line to be processed. The name of the shell command (or script) is assigned parameter $0, the next argument $1 and so on (Don’t type the following command, it's only an example!).

$ cp test1 test2 test3 test4

In this example, the command 'cp' is parameter $0, whilst 'test4' is parameter $4. There are four arguments to the program.

 

Predefined Special Shell Variables
The following variables have special meanings, and are set ONLY by the shell. They cannot be set by the user.

Variable Meaning
$# Records the number of arguments passed to the shell, not counting the first command. For example, cp a b c sets $# to 3. One of its primary uses is to check that enough arguments have been specified,
if test $# -lt 2
then echo 'two or more args required';
exit fi
$? Contains the exit status of the last command executed. Its value is a decimal string, and is usually zero for successful completion.
$$ The process number of the current process, and is unique. Often used to generate temporary filenames.
temp=/usr/tmp/$$
ls > $temp
$! The process number of the last process run in the background (using an &) and is a string of one to five digits.
$- A string consisting of names of execution flags currently turned on in the shell. See the shell options 'xv' for more information.
$* All the arguments given to the shell

 

Shell Conditional Tests
The test command evaluates the expression specified by the arguments, and if true, returns a zero status, else it returns a nonzero status.

Test Meaning
!= not equal
= equal
-eq equal
-gt greater than
-ge greater than or equal
-lt less than
-le less than or equal
! logic negation
-a logical and
-o logical or
-r file true if the file exists and is readable
-w file true if the file exists and is writable
-x file true if the file exists and is executable
-s file true if the file exists and its size > 0
-d file true if the file is a directory
-f file true if the file is an ordinary file
-t filed true if the file descriptor is associated with a terminal
-n str true if the length of str is > 0
-z str true if the length of str is zero

Consider the following shell script example.

#test to see if only one argument is passed to the shell script
if test $# != 1
then
echo "You must supply one argument"; exit
fi

What is the sequence of commands you would use to test for two or more arguments? Enter the command sequence in the space provide below.

..........................................................................

..........................................................................

..........................................................................

..........................................................................

..........................................................................

What is the sequence of commands you would use to test if argument $1 was a directory? Enter the command sequence in the space provide below.

..........................................................................

..........................................................................

..........................................................................

..........................................................................

..........................................................................

 

More Shell Test Examples

#test to see if the argument is a file
if test $# != 1
then
echo "You must supply one argument"; exit
fi
if test -f $1
then
echo "$1 is a file"
else
echo "$1 is not a file"
fi

#test to see if the argument exists, is a file or directory
if test $# != 1
then
echo "You must supply one argument"; exit
fi
if test -d $1
then
echo "$1 is a directory"
else
if test -f $1
then
echo "$1 is a file"
else
echo "$1 does not exist"
fi
fi

 

REVIEW TEST
Answer all questions below before proceeding. Place your answers in the spaces provided.

Which shell character matches a single character?

..................................................

State the three standard devices associated with shell procedures.

.............. .............. ...............

Rewrite the following command so that it executes correctly.

who | users.log ............................................

Write a command that assigns the system date to the shell variable PS1.

.................................................

 

The Shell State
The state of the shell at any given instance includes the values of positional variables, user defined variables, environment variables, modes of execution and the current working directory.

Often, the user requires to change the working directory within the shell. This can be done without affecting the original shell by enclosing the command in parenthesis.

(cd /etc; cp passwd /usr/joe/passwd)

The shell also reads the .profile file stored in the users home directory when the user first logs in. This file specifies the state of various shell variables. The next module will explain in detail the significance of this file.

 

Shell Execution Flags
The set command is used to alter the behaviour of the shell by altering two flags.

Shell Flag Effect
-v Input lines are printed as they are read by the shell. Commands are executed after the line is printed.
-x Commands and their arguments are printed as they are executed. Shell control commands (like for, while) are not printed. Displays a trace of only the commands actually executed by the shell.

The flags are turned off by typing

$ set +xv

To list the shell variables which are exported external to the shell, type

$ export

To get a list of the shell variables, type

$ printenv

or

$ env

 


Previous PageIndexNext Page
Home | Other Courses | Assessments | Notes | Tests
© Copyright Brian Brown, 1988-2000. All rights reserved.