Shell Scripting

Here is the contents of a shell script called summary:
#!/bin/csh

if ($#argv != 1) then
    echo "Wrong number of arguments"
else 
    if (-d $1) then
        cd $1
        echo "---- Start of directory $1"
        foreach Name (*)
            if (-d $Name) then
                summary $Name
            else
                wc $Name # >> lst.sum
                endif
            end
        echo "---- End of directory $1"
    else 
        echo "Invalid directory name: $1"
        endif
    endif
# END
Tasks:
  1. Explain what shell scripts are.
    Special text files which contain sequences of commands.
    Instead of issuing commands one after the other at the
    command prompt, a script allows you to group them together
    and execute them using a single invocation. The C-Shell script
    is syntactically similar to C code, for example there are similar
    control statements (if, for, case). Special routines and variables
    exist ($$, $*, $#, test, ...) to help control the execution of a
    shell script.
    
  2. Explain how the shell script can be executed. (Hint: there are 3 ways)
    By issuing the command
    
    
    source summary directory
    csh summary directory
    where directory is a valid directory name (which you have read an write access to). Also, if you do chmod u+x summary then you only need to type
    ./summary directory
  3. create a new directory under your cp1300 directory, called "test". Inside "test" create two sub-directories "sub1" and "sub2". Place some text files inside "test", "sub1", and "sub2".
    cd
    cd cp1300
    mkdir test
    cd test
    mkdir sub1
    mkdir sub2
    ... then just add some text files into test, sub1, sub2
    
  4. change into ~/cp1300/test/ and make a copy of summary inside "test" (You can make it executable if you wish).
  5. Once you get it working, analyse the shell script summary (try and use it like this: summary ./), and describe what it is doing. (Hint: Apply summary with no arguments, 1 argument (the current directory, which should be ~/cp1300/test), and many arguments)
    With no arguments it gives an error message.
    More than one argument also gives an error message.
    
    With one argument, summary trys to treat it as a directory name.
    If its not a directory, then an error message appears. Else
    summary does the following:
    
    	changes into the directory
    	displays the files/sub-directories
    	if the directory is not empty then
    		for each entry in the directory (call it name)
    			if name is a sub-directory then
    				apply summary recursively on name
    			else
    				apply wc to name, and append the
    				results to lst.sum
    			endif
    		endfor
    	endif
    

    Note: As it is written above, summary will not work properly. What is causing the problem? And what can be done about it?

    The problem is that summary is stored in a
    particular directory. For the shell script
    to call itself (recursively) it must be able
    to access the particular directory. As it is
    written, the shell script assumes that summary
    is in the current directory and EVERY
    sub-directory below that. 
    
    Solution: 1) set the path variable to include the
    	   absolute pathname for summary
    
    	   This can be achieved using HOME
    
    
    The OSF1 section of .cshrc should look something like:
    
    set path=($HOME/sbin /usr/local/bin /usr/sbin\
    	/usr/bin /usr/bin/X11 /usr/local/bin/X11\
    	/usr/local/freeware/bin /usr/local/qi/bin)
    
    
    It needs to have $HOME/cp1300/test added to the end:
    
    set path=($HOME/sbin /usr/local/bin /usr/sbin\
    	/usr/bin /usr/bin/X11 /usr/local/bin/X11\
    	/usr/local/freeware/bin /usr/local/qi/bin $HOME/cp1300/test)
    
    To activate the changes, you can:
    	a) logout, and log back in again
    
    	b) use source .cshrc
    
    
    
    
    Solution: 2) Use a local variable to store the absolute
    	     pathname to where summary is stored.
    
    Here is what summary would become:
    
    #!/bin/csh
    
    set Summary = /home/geoff/tmp/test/summary
    
    if ($#argv != 1) then
        echo "Wrong number of arguments"
    else 
        if (-d $1) then
            cd $1
            echo "---- Start of directory $1"
            foreach Name (*)
                if (-d $Name) then
                    $Summary $Name
                else
                    wc $Name # >> lst.sum
                    endif
                end
            echo "---- End of directory $1"
        else 
            echo "Invalid directory name: $1"
            endif
        endif
    # END
    
  6. construct your own shell script, call it unsummary which takes a single argument (a directory name) and proceeds to display the contents of the lst.sum files that were created.

    #!/bin/csh
    
    set Unsummary = /home/geoff/tmp/test/unsummary
    
    if ($#argv != 1) then
        echo "Wrong number of arguments"
    else 
        if (-d $1) then
            cd $1
            echo "---- Start of directory $1"
            if (-e lst.sum) then
                echo "---- Here's lst.sum"
                cat lst.sum
                endif
            foreach Name (*)
                if (-d $Name) then
                    $Unsummary $Name
                    endif
                end
            echo "---- End of directory $1"
        else 
            echo "Invalid directory name: $1"
            endif
        endif
    
  7. modify your unsummary script so that all of the lst.sum files are removed instead of them being displayed.

    Note: be VERY careful using the rm command. Because once something is removed, it is not trivial to restore it! Don't try this question until you complete the previous version of unsummary.

    #!/bin/csh
    
    set Unsummary = /home/geoff/tmp/test/unsummary
    
    if ($#argv != 1) then
        echo "Wrong number of arguments"
    else 
        if (-d $1) then
            cd $1
            echo "---- Start of directory $1"
            if (-e lst.sum) then
                echo "---- Deleting lst.sum"
                rm lst.sum
                endif
            foreach Name (*)
                if (-d $Name) then
                    $Unsummary $Name
                    endif
                end
            echo "---- End of directory $1"
        else 
            echo "Invalid directory name: $1"
            endif
        endif
    

Copyright © 1998, Jason Holdsworth. All rights reserved.