CS246 Winter 2011 Assignment 1:



Submit.  Instructions to submit assignments (using Marmoset):


Bash.  All shell scripts you write should work on the bash shell. 

Linux.  Do assignments on UW CS Linux machines.  (Do not use Solaris/SUN.)

ASCII.  Turn in the written (non program) part of this assignment as an ASCII file.

ASCII editor.  You will need to use an ASCII editor such as vi or emacs to do this assignment.


Asgn 1a: Debugging shell scripts.  Shell scripts tend to be short and yet difficult to write.  It is recommended that you initially include lots of debugging statements (use “echo” to print out things) in your scripts.  In the final version,  you can comment out these debugging statements using “#”.  Here’s is a simple example script called tryeval (try out “eval”). This contains several illustrative debugging statements.


echo BEGIN tryeval     # Check that script gets started

echo  \$1 =  \"$1\"    # if $1 is whoami, this prints out:

                       #     $1 is "whoami"

eval $1

echo END tryeval       # Check that script finishes


Create an ASCII file called tryeval that contains the above script.  Make it executable by typing:

chmod u+x tryeval

Try executing this script using these two commands. Don’t forget the “./

./tryeval whoami    

./tryeval date



Asgn 1b: Set up a directory structure.  In your Linux file directory, create the following directory structure (the leaves are ASCII files) in your home directory. Use the commands mkdir and cd to do this. 














You are to create the contents of the above files as follows:


hello: echo HELLO

bye: echo BYE

dummy.h: DUMMY

msgHi.h: const string msg = "HI";

msgHo.h: const string msg = "HO";


Note: You can create simple files this way:

echo Stuff to go in file > fileName


Make the files called hello and bye executable and try executing them, using commands such as

chmod u+x hello



The file mainHi.cpp should contain:

#include <iostream>

#include <string>

using namespace std;

#include "msgHi.h"

int main ()


    cout << msg << "\n";


The file mainHo.C should be like the file mainHi.cpp except in the “#include” line, “msgHi.h” should be changed to “msgHo.h”.  In the directory cppsource, compile mainHi.cpp using the command

g++ mainHi.cpp

and then run the compiled program by giving the command


In a similar way, compile and run mainHo.C

The file funny.cpp should contain this script:

// This C++ program is incomplete on purpose

/* Here is an example of nasty surprise in C/C++ */

    if (i = 1)   // Should be:  if (i == 1)

        // etc etc etc  This is the last line of the script


You are to “zip” your directory structure using this command:

zip -r cs246.zip cs246

This places an encoded version of your directory structure in the file called cs246.zip.  Note that cs246 is

the top directory in your directory structure.


Asgn 1c: Create an alias and a bin command.  Create an alias for cd called chdir. Trying using your chdir command to navigate around your example directory structure.


In your bin directory (within your home directory), create a file called p (abbreviation for print).  Create p such that it is a command that has the same effect as the "more" command (implement p by calling "more").  Remember to start your script with


and remember to make it executable.  Try using your “p” command to view files in your directory structure.  Inspect the path used by the shell for finding commands such as p by typing

echo $PATH

Check to see that your bin directory is in the search path.

For both chdir and p, start up a sub-shell (by typing bash), and see if your commands (p and chdir) still work.

Logoff and login again and see if your chdir and p commands still works.


Try giving the following commands to determine the type or location of chdir, p and cd.

type chdir

type p

type cd


Asgn 1d: Search for bad equal sign.  A characteristic error when using C/C++ is to type = (equal) instead of two equal signs ==, for example

if (i = 10)   // if (i == 10) was intended

Write a shell script (and put it in your bin directory) called badeq (bad equal) which uses recursive grep to list lines containing the following pattern on a line:  Any number of blanks and tabs, then “if” then zero or more blanks, then “(“, then any characters, then “ = “ (blank, equal, blank), which can be followed by arbitrary characters on the line.  You can read the description of grep by typing

man grep   # Manual for grep

Test badeq by giving this command in your home directory.


Asgn 1e: Listing C++ files.  By convention C++ source files end with one of the suffixes .h, .C or .cpp.  Write a shell script called lscpp (list C++ files) which uses “ls” to list files in the current directory that end in one of these three suffixes.  Then write a script called lscpp2 that is like lscpp but it takes an optional initial argument of –h or –l.  If the –h occurs, then lscpp2 prints out a “usage” message, saying what lscpp2 does, and halts.  If the –l occurs, the result is like lscpp, but the long (-l) form of ls is used.  If neither –h nor –l appears, then lscpp2 works just like lscpp (and it should actually call lscpp).  Use an if statement to implement lscpp2.


Asgn 1f: Simple find.  Write a command called sfind (simple find) which is a simplification of the find command.  (See “man find” for a description of find.)  The sfind command uses find to recursively look for files whose names contain a given string, starting in the current directory.  For example

sfind main

uses “find” to locate all files recursively that have “main” in their name starting in the current directory.   Your sfind script should print a message and stop if the number of arguments is not one.


Give the command


to make sure you are on Linux (not SUN Solaris, which does not support the newest version of  “find”).


Asgn 1g: Simple grep.  Write a command called sgrep (simple grep) which is a simplification of the grep command.  (see “man grep” for a description of grep.)  Your sgrep command is to use grep to recursively locate lines in files that contains a given string, starting in  the current directory.  For example

sgrep msg

uses “grep” to locate all lines in files recursively that contains the string msg, starting in the current directory.  Test your sgrep command by giving this example command.  Beware that the Linux version (but not the SUN version) of grep support recursion (via the –r flag).


Give the command


to make sure you are on Linux (not SUN Solaris, which does not support the newest version of  “grep”).


Asgn 1h: Nuke temporaries.  Write a command called nuketmp that removes temporary directories (named tmp or temp) that occur in a given set of directories.  For example, the command

nuketmp aaa bbb

will delete any directories named tmp or temp (with recursive contents) that exist within directories aaa and bbb.  Before deleting, the command is to prompt the user to verify that the deletion is desired.  Your command should use a “for” loop inside a “for” loop, with a “find” command that searches for directories (not files) named tmp or temp.  Note that the rm command takes flags to specify recursive (transitive) removal and to specify prompting.  See Buhr’s example on slides 49-50 for ideas.


What to submit for marking.



File to submit