CP367: Lab 07 - Winter 2026 - Shell Programming I

Due 11:59 PM, Friday, March 6, 2026

Shell Scripts

A shell script is a file including a list of executable commands that the UNIX shell executes one by one. (We've seen something similar in the last lab with sed scripts - sed commands that are stored in a file and executed one by one by sed.)

To execute a script, the script must have execute permission turned on. You can do this with the chmod command:

chmod u+rx scriptfile

Now that the script has the proper permssions, call it by giving its directory and name. If the script file is in the current directory, you must provide that information by putting ./ in front of the script name:

./scriptfile

A shell script may contain multiple commands. Commands are generally listed one to a line. Longer commands may be extended by ending the line with a backslash ( \ ), as in sed scripts. Commands may include just about anything that you can type at the commend prompt.

The who command displays information about who is currently logged into the system:

who Sample Output
/home/dbrown/CP367> who
root       console      Feb 24 16:05    (:0)
choang     pts/2        Feb 28 09:21    (tipa.wlu.ca)
dbrown     pts/3        Mar  1 10:33    (dbrown.wlu.ca)
mieh8930   pts/6        Mar  1 10:04    (172.21.29.83)
mieh8930   pts/7        Mar  1 10:07    (172.21.29.83)
root       pts/5        Feb 24 16:06    (:0.0)
root       pts/8        Feb 24 16:16    (:0.0)
choang     pts/9        Mar  1 10:50    (216.249.63.201)
klem5550   pts/10       Mar  1 10:47    (cpe00222d181f0d-cm00222d181f09.cpe.net.cable.rogers.com)
kimx1990   pts/11       Feb 28 09:34    (tipa.wlu.ca)
kimx1990   pts/12       Feb 28 09:35    (tipa.wlu.ca)
eric8260   pts/13       Mar  1 11:04    (cpe0026f30d50f1-cm0026f30d50ed.cpe.net.cable.rogers.com)
mieh8930   pts/17       Mar  1 10:04    (172.21.29.83)
wang6470   pts/18       Feb 28 09:59    (tipa.wlu.ca)

The script newwho modifies and formats the output of the who command:

Script
#!/bin/sh
echo "WLU Connections"
who | grep wlu.ca
echo "------------------------------------------------"
echo "Non-WLU Connections"
who | grep -v wlu.ca
exit 0

and when executed, produces:

Script Sample Output
/home/dbrown/CP367> ./newwho
WLU Connections
choang     pts/2        Feb 28 09:21    (tipa.wlu.ca)
dbrown     pts/3        Mar  1 10:33    (dbrown.wlu.ca)
kimx1990   pts/11       Feb 28 09:34    (tipa.wlu.ca)
kimx1990   pts/12       Feb 28 09:35    (tipa.wlu.ca)
wang6470   pts/18       Feb 28 09:59    (tipa.wlu.ca)
------------------------------------------------
Non-WLU Connections
root       console      Feb 24 16:05    (:0)
mieh8930   pts/6        Mar  1 10:04    (172.21.29.83)
mieh8930   pts/7        Mar  1 10:07    (172.21.29.83)
root       pts/5        Feb 24 16:06    (:0.0)
root       pts/8        Feb 24 16:16    (:0.0)
choang     pts/9        Mar  1 10:50    (216.249.63.201)
klem5550   pts/10       Mar  1 10:47    (cpe00222d181f0d-cm00222d181f09.cpe.net.cable.rogers.com)
eric8260   pts/13       Mar  1 11:04    (cpe0026f30d50f1-cm0026f30d50ed.cpe.net.cable.rogers.com)
mieh8930   pts/17       Mar  1 10:04    (172.21.29.83)

Shell Standards

There are many different shells available, such as sh , ksh , csh , and of course, bash . The first line of a script should identify the shell the script should run under. The shell sh is the original, 'base' shell, and any script that runs under sh meets the POSIX standard. Such scripts are portable to most unix or Linux systems. Such a script starts with the #!/bin/sh she-bang. (she from sharp ( # ) and bang from and bang ( ! ) character). You may refer to other shells if you intend to use those shell's capabilities, but the resulting scripts will not be as portable. Note that the # character identifies this first line as a comment.

Scripts should end with the exit command. This command is generally followed by a number that indicates whether the script was successful or not. A 0 indicates the script ended with no errors, whereas any other number should indicate the kind of error that occurred. Simple scripts that cannot cause an error under normal circumstances should always end in exit 0 . This exit status value can be checked by other scripts.


Shell I/O

echo string|$variable
displays the value of either a string or a variable to the console.
read variable
gets input from the console into a variable.

The getstring script:

Script
#!/bin/sh
echo "String: "
read string
echo "The entered string was: $string"
exit 0

and its execution:

Script Sample Output
/home/dbrown/CP367> ./getstring
String:
Hey there!
The entered string was: Hey there!

When are there actual differences between shells? getstring2 starts with #!/bin/bash rather than #!/bin/sh . bash supports the -n option for echo (i.e. do not add a new line), sh does not:

Script
#!/bin/bash
echo -n "String: "
read string
echo "The entered string was: $string"
exit 0

when executed:

Script Sample Output
/home/dbrown/CP367> ./getstring2
String: Look at this!
The entered string was: Look at this!

Shell Variables

Shell variables are similar to variables in most programming languages that you are familiar with. You may assign values to variables, perform simple calculations on them, use them in control structures (ifs and loops), and display their values. There are a number of predefined and special variables available.

Variable Naming

Variable names must start with a letter. Variable names that start with a number are special argument variables that are assigned by the system.

Assigning Variables

Values are assigned to 'naked' variable names - i.e. the variable name does not have a $ in front. Values are assigned with the = character. Do not put spaces between the variable name, the = , and the value. Values that contain spaces must be enclosed in double quotes. Examples:

var1=5
var2="Some String"
var3 = 6    # Invalid assignment

You may assign the output of a command to a variable by putting the command within single back quotes ( ` ). This executes the command and puts the result into the variable, as in this example:

Commands
/home/dbrown/CP367> HOST=`hostname`
/home/dbrown/CP367> echo $HOST
hopper

Using Variables

Variables can be used within scripts and strings, but may have to be escaped in certain circumstances. If a variable is used within spaces, then nothing special needs to be done to display it:

Script
/home/dbrown/CP367> echo "The machine is $HOST"
The machine is hopper

Without spaces, the variable must be enclosed within brace brackets ( {} ), as in the creation of the FULLNAME variable in the following script hostinfo :

Script
#!/bin/sh
# Ask the user for the Internet domain.
echo "Enter domain:"
read DOMAIN
# Get the name of the machine from the system.
HOST=`hostname`
# Generate the full name.
FULLNAME=${HOST}.${DOMAIN}
echo "Machine name is $FULLNAME"
# Test the full name with 'ping'.
PINGRESULT=`ping $FULLNAME`
echo $PINGRESULT
exit 0

When executed:

Script Sample Output
/home/dbrown/CP367> ./hostinfo
Enter domain:
wlu.ca
Machine name is hopper.wlu.ca
hopper.wlu.ca is alive

Note that variables can be defined both at the command line and inside scripts. Variables defined at the command line remain in existence for the rest of the session. Variables defined inside a script only exist as long as the script is running. Scripts can refer to command line variables, but will have an error if the command line variable does not exist. Use the set command to list all variables defined or pre-defined from the command line.

Pre-Defined Variables

There are a number of typical pre-defined variables available on a given system. One such variable is $HOME , which identifies the home directory of the current user. It can be displayed or used in commands:

Commands
/home/dbrown/CP367> echo $HOME
/home/dbrown
/home/dbrown/CP367> ls $HOME
a1.zip        example.txt   newwrap.sed   old.txt       public_html   stuff.txt     wraphtml.sed
CP367         fix.sed       noblank.sed   out.txt       script.sed    test.txt
error.txt     good.txt      noblank.sh    p.sed         sed           text2html.sh

Arguments

You can pass arguments to scripts. You may then determine the number and values of these arguments with system-defined variables:

$0
The name of the script being executed.
$#
The number of arguments passed to the script.
$@
The arguments passed to the script in a single space-delimited string.
$1 .. $n
Each argument in turn numbered from 1 to n, where n = $# .

These argument variables are particularly useful when you know the number of arguments to expect, or intend to loop through the arguments and process them.

Example

The script file vars1 demonstrates a number of the variable handling mentioned:

Script
#!/bin/sh
# Get the name of the script.
echo "The name of the script is in \$0"
echo "Name of script: $0"
echo
# Get the number of arguments to the script.
echo "The number of arguments passed is in \$#"
echo "Number of arguments: $#"
echo
echo "The arguments are in \$1 through \$$#"
echo
echo "The arguments are stored in \$@"
echo "$@"
echo
echo "The arguments are stored in \$*"
echo "$*"
echo
# Call a system command and send the result to a variable.
arch=`uname -m`
echo "System architecture: $arch"
echo
# Set a variable to a numeric value.
n=5
echo "\$n = $n"
echo
# Miss-set a variable.
m = 9
echo "\$m = $m"
exit 0

Executing vars1 without arguments:

Script Sample Output
/home/dbrown/CP367> ./vars1
./vars1: Get: not found
The name of the script is in $0
Name of script: ./vars1

The number of arguments passed is in $#
Number of arguments: 0

The arguments are in $1 through $0

The arguments are stored in $@


System architecture: i86pc

$n = 5

./vars1: m: not found
$m =

Executing vars1 with arguments:

Script Sample Output
/home/dbrown/CP367> ./vars1 stuff and nonsense
./vars1: Get: not found
The name of the script is in $0
Name of script: ./vars1

The number of arguments passed is in $#
Number of arguments: 3

The arguments are in $1 through $3

The arguments are stored in $@
stuff and nonsense

System architecture: i86pc

$n = 5

./vars1: m: not found
$m =
  1. Create a shell script doing the following (call it task1 ):

    • Greets the user (display the user's login)
    • Ask the user to enter a command
    • Execute the command and redirect the output to the file output.txt file and errors to the file errors.txt.
    • Prints out the content of the output file and the error file specifying which one is output and which one is error.

  2. Create a shell script for submitting your homework (call it submit ):

    • Give submit two arguments:
      • the first argument is the name of the submission directory (use /tmp)
      • the second is the name of the file you are submitting
    • Change to the submission directory
    • Create a directory with your username as its name
    • Copy the submission file from your home directory into the directory you just created
    • Print out the list of the files in the directory you just created.