University of Bridgeport Operating Systems CPE408/CS503 UNIX Lab Assignment #1 – Shell Archives Summary Unix Lab 1 is a shell programming assignment that uses Bourne shell and most of its built-in constructs such as variables, loops, conditional statements and input redirection. Additionally, basic knowledge of sed is required for a certain part of it. Familiarity with a UNIX system from the user’s perspective or at least being comfortable using the command prompt and being able to navigate through the directory hierarchy of either Windows NT or UNIX operating systems is required. Use of text editor, such as pico, vi, joe or emacs is also required in order to program the assignment. Introduction In this assignment you are to create a program, or tool, that will automate creating shell archives. Shell archive is an essentially a shell-script that when run, creates files that it contains internally. In most cases, files, it contains and creates during execution are ASCII, even though one could store binary files in an archive by pre/post processing them with uuencode and uudecode respectively. Thus, one can look at a shell archive as a big script that holds together a sum of files and when it is executed those files are copied one by one to their respective filenames. Shell archive does not compress the original file, but it just puts them all together into one file making it easier from the distribution point of view. Similar concept is used by the tar program and its corresponding archives (that can and in most cases do contain binary files). Specifics Your “shell-archive-creating” automated tool should be run from the command line in the UNIX environment. It should be implemented using the Bourne shell, which is the default shell at the University of Bridgeport UNIX workstations as well as in many other academic institutions and corporations. Archive tool is to accept one parameter, namely, the name of the resulting shell archive. For example: cpe$ archive_tool myShellArchive.sha In the above example, it is assumed that the user is logged in at the cpe.bridgeport.edu and its tool name is archive_tool. myShellArchive.sha is the output filename. Obviously, your tool should not archive itself or the shell archive it is creating, since, by very least, an infinite recursion may occur. For simplicity sake, the tool should only archive the current directory it was being executed from and the first next level and its corresponding files. Note: during reconstruction, the whole directory hierarchy (obviously, only one-level deep) should be reconstructed as well. For example, consider the following directory structure and its corresponding files: /home/user1/ /home/user1/data/ /home/user1/code/ /home/user1/code/backup/ file1.html file2.html In the scenario above, assuming the script is run from the /home/user1 directory files in the following directories are going to be archived: /home/user1 /home/user1/data /home/user1/code And /data and /code sub-directories will be re-created in the directory the shell archive was ran. So for example, if the shell archive was executed at some later date in the directory /home/superuser1, then 2 subdirectories are going to be created code/ and data/ and the files will be de-archived that belonged to those 3 directories during archiving. Bonus You will notice that when you try to archive files that contain a number of back quotes, which are a special “execute” character for the Bourne shell, problems arise when such a shell-archive is executed in order to de-archive the files. When the shell comes to the first back quote in the archived file, it will assume it is a special character and will try to behave like it is, but obviously this was not intended. One solution is to replace the back quote by something else, like some cryptic string using sed and then replace it again after de-archiving by using sed again. Resources For this assignment, you can refer to the various on-line resources concerning UNIX shell programming in general and Bourne shell in particular. You can also consult USENET newsgroups, which are easily accessible by using http://groups.google.com/ website where you can find tons of articles, references and sample codes developed by your peers, professionals, etc. You can refer to the CS435 – C&UNIX Programing course web site at: http://www.bridgeport.edu/sed/courses/cs435/ (or more specifically: http://www.bridgeport.edu/sed/courses/cs435/lectures.htm - there will be a Shell drop-down box in the upper-left corner with many PPT files). A nice web-site which is a collection of links to other UNIX programming web sites is: “Davin's collection of UNIX programming links” http://www.cs.buffalo.edu/~milun/unix.programming.html Lastly, you can also refer to the textbook for this assignment, which was given in the syllabus: Stephen G. Kochan, Patrick H. Wood, UNIX Shell programming, Revised Edition, Hayden Books-SAMS, 1989. ISBN: 0-672-48448-X and UNIX manual pages, referred to as man. Sample code All of the sample codes can be run on our UNIX systems. Copy the file starting from the line: #!/bin/sh which denotes the start of the shell script until the end. Make the shell script executable by using chmod command. For example: chmod 755 <script_name>. You can find out more about the chmod command or any other UNIX command (which are used in the shell scripts! So, its an excellent resource as well) by using man command. Namely, man <name_of_command> and the documentation will be displayed. 1 – Shell and parameters #!/bin/sh # CPE408/CS503 # Unix Lab 1 - sample code # (C) Fran Jarnjak # # This sample code demonstrates how to pass a single parameter to the # Script and be able to use it. You can modify the program # To be able to use more parameters by changing the if statement # since we are checking if a shell variable $# that stores the number # parameters is not equal to 1, which means more or less than one was # passed. Parameters are referenced by $0, $1,$2...,$9, where $0 means the # script name (actually its filename by which it was executed) if [ "$#" -ne 1 ] # Total parameter number needs to be EQUAL to one then echo "Usage: script_name <parameter>" exit 1 fi parameter_passed=$1 echo "Given param=$parameter_passed" echo "Exiting..." 2 – Determining the files and their type in the current directory #!/bin/sh # # # # # # CPE408/CS503 Unix Lab 1 - sample code (C) Fran Jarnjak Script that examines current directory and prints out What is a file and what is a directory with its appropriate name The script skips printing out itself # NOTE: Note the syntax of the "if" statements and especially the spacing # of square brackets - space is needed. ####################################################################### ## # Store our name in the variable (no spaces, otherwise it fails my_own_name=$0 # Go throught the directory for level_1 in * do if [ -f "$level_1" -a "$level_1" != $my_own_name ] then echo "$level_1" is a file. fi if [ -d "$level_1" ] then echo "$level_1" is a directory. fi done 3 - An example of a Shell Archive #!/bin/sh # CPE408/CS503 # UNIX Lab 1 - sample code # (C) Fran Jarnjak # # This program demonstrates how by using the here document <<, one can # write a script that is essentially a shell archive. When this script # is run, two files in the current directory will be created, test.txt # and test2.txt. They will contain certain text. In case of real # shell archives they can cointain anything, as long as it is ASCII, for # example other shell scripts - in which case, care needs to be taken # to convert backslashes to something else ant then convert it back during # reconstruction, so that the shell interperter during reconstruction # is not confused and will not report errors. cat > test.txt <<THE_END_OF_DATA This can be anything. It is going to be reconstructed and put into test.txt THE_END_OF_DATA cat > test2.txt <<THE_END_OF_DATA This can also be anything. It is also going to be reconstructed and put into another file THE_END_OF_DATA