-------------------------------------- Exercise #8 for DAT2330 due October 26 -------------------------------------- -Ian! D. Allen - idallen@idallen.ca Remember - knowing how to find out an answer is more important than memorizing the answer. Learn to fish! RTFM! (Read The Fine Manual) Global weight: 2% of your total mark this term Due date: 10h00 (10am) Sunday, October 26, 2003. The deliverables for this exercise are to be submitted online using the usual submission method described in the exercise description. Late-submission date: None. After the due date, the exercise is worth zero marks; but, it must still be completed and submitted successfully to earn credit in the course. Exercises submitted by the due date will be marked online and email sent to you. A sample answer will be posted online. Exercise Synopsis: This week you will write a script to extract and compile a C++ program on the Course Linux Server. The assignment specifications are hidden in a compressed tar file. Fetch the compressed tar file. Unpack it. Find the hidden README file. Follow the directions. Submit the labweek9.sh script for marking on the Course Linux Server. References and Readings: Running Linux: Chapter 4, Chapter 7, Chapter 13, Lectures, online Notes. Where to work: Do your Unix command line work on the Course Linux Server located at SSH port 2330 on machine idallen.ca. (Backup link: alt.idallen.ca) You can find a copy of all the course Notes files on the Linux Server under directory: ~idallen/public_html/teaching/dat2330/03f/notes/ You can copy files from this directory to your own account. Exercise Details: 0. Did you read this week's notes yet? Read first; type second! 1. Under the course notes directory is a hidden compressed tar file named ".exercise08.tar.gz". (As stated above under "Where to work", a copy of the course notes directory is available on the Course Linux Server.) Your exercise description is contained in a hidden README file contained inside a hidden directory inside that compressed tar archive. Go get the README file and do what it says. --------------------------- .README.txt for Exercise #8 --------------------------- Write this executable script named "labweek9.sh". The script described below must be written to conform to the script writing checklist: script_checklist.txt and to the script style given in: script_style.txt. All user input (command line arguments or input via "read") must be fully validated before being used in expressions. Do not process null, empty, missing, or otherwise bad input! Scripts without *useful* block comments will be severely penalized. See the script_style.txt file for the expected commenting style. Failure to follow the script_checklist.txt will lose you many marks. This scripting is straightforward; build this script one piece at a time and test each piece before adding a new piece. ------------------ Syntax and Purpose ------------------ Syntax: $0 [ tarfile [ progname ] ] Example usage: ./labweek9.sh mytar.tar.gz argv The user will be prompted to enter any missing command line arguments. This script will expand a compressed (gzip) tar archive containing C++ source code and compile the C++ source code for the given program name. It will compare the size of the compiled program against a system program. Note: If the program name given by the user is "argv", the source code name that we will be looking for inside the compressed tar archive is expected to be "argv.cpp". The argument you are expected to give to the script is just the "argv" part of the name. The script will construct and use the "argv.cpp" source code name internally. -------------- Optional Input -------------- This script has optional command line arguments. Accept two or less arguments on the command line. (If there are more than two arguments, print an appropriate error and exit the script with return code 2.) If there are less than two arguments, prompt for and read the missing arguments (up to two). The first optional argument is a compressed (gzip) tar file. If the argument is missing, prompt for it and read it. The second optional argument is the compiled name of a program whose source is contained in the tar archive. If the second argument is missing, prompt for it and read it. In other words: If the user supplies two command line arguments, don't prompt for any input; transfer the two arguments to shell variables and use them as the tar file and program names. If the user supplies only one command line argument (the tar file name), transfer it to a variable and prompt for and read the missing program name argument. If the user supplies no command line arguments, prompt for and read both the tar file name and the program name. See the optional_args_*.sh.txt scripts in the Notes for examples of how to do optional arguments. Make sure your prompts for input appear on standard error, not standard output. A good user interface will echo user input (including any command line arguments given) back to the user. This is a good idea both for debugging your script and for giving the user feedback on what data the script is actually processing. Echo the user's two input names back to the user surrounded by single quotes; also construct the name of the source code file from the program name, put it in a variable, and echo that variable as well: $ ./labweek9.sh mytar.tar.gz argv Input tarfile: 'mytar.tar.gz' Program name: 'argv' Source name: 'argv.cpp' ---------------- Input Validation ---------------- If either of the two input strings is empty (null string), print an appropriate error message and exit the script with return code 2. Make sure the compressed tar file is a non-empty, plain file. (That is two things you need to test.) If the file is not readable, print a warning on stderr and then add read permissions to the file. If the program source name supplied by the user (e.g. argv.cpp) is not found in this compressed tar archive, print an appropriate error message and exit with status 3. (Hint: Generate a table of contents of the tar archive and pipe that output into a comand that can search for the program name. Use the search program return status to know if the name was found in the table of contents. You can redirect the output of the search program to /dev/null so that it does not appear on the screen.) ---------- Processing ---------- In the specifications below, the example name "argv" is just an example - the actual program name you use is the name given by the user as input. Do not hard-code the name "argv" in the script! We don't want our script to overwrite any existing program file or program source file, so we rename any existing files to have ".bak" on the end: If there is an existing pathname matching the given program source name (e.g. argv.cpp), rename that pathname by adding ".bak" to the name. In other words, rename an existing argv.cpp to be argv.cpp.bak; but, only if the source pathname argv.cpp currently exists. Extract the contents of the compressed tar archive. If this fails, print an appropriate error message and exit the script with status 4. Make sure the program source file (e.g. argv.cpp that was just extracted from the tar archive) is a non-empty, plain file. (That is two things you need to test.) If the program source file is not readable, print a warning on stderr and then add read permissions to the file. If there is an existing pathname matching the given program name file (i.e. an already existing argv file), rename that pathname by adding ".bak" to the name. In other words, rename an existing argv to be argv.bak; but, only if the program file pathname argv currently exists. Compile the given program source using the C++ compiler and name the executable output file with the given program name, e.g. compile source "argv.cpp" into an executable file named "argv". If this compile fails (bad exit status), print an appropriate error message and exit the script with status 5. Count the number of bytes (characters) in the resulting executable output file (e.g. in the output file argv). Compare that number against the number of bytes in the system file "/bin/echo" and print one of three messages on standard output in this format: Program NNNN ( XXX) is smaller than /bin/echo ( YYY) Program NNNN ( XXX) is the same size as /bin/echo Program NNNN ( XXX) is larger than /bin/echo ( YYY) - NNNN will be the name of the compiled program given by the user - the number XXX is the size (in bytes) of the compiled program - the number YYY is the size (in bytes) of /bin/echo Replace NNNN, XXX, and YYY with the correct variable contents in your script code. Do not output NNNN or XXX or YYY. The actual pathname /bin/echo should appear in only *one* place in your script - do not repeat this string constant all through your code. Define it in one place. ------------- Documentation ------------- Follow the comment and header conventions given in file script_style.txt. Follow the script writing checklist given in file script_checklist.txt. Scripts without comments are heavily penalized. ---------- Submission ---------- Use the "datsubmit" command to submit the fully commented executable labweek9.sh script file as Exercise 08 on the Linux Course Server. 1) Make sure your Exterior Assignment Submission Label is near the start of your shell script as comment lines. Use the exact 7-line (plus optional comments) format described online and in previous exercises. See the script_style.txt file for details. Did you follow the script guidelines in script_checklist.txt ? 2) Submit the script for marking as Exercise 08, using the following command line on the Linux Course Server: $ datsubmit 08 labweek9.sh This "datsubmit" program will copy the file to my Exercise 08 directory for marking. 3) Verify that you submitted everything, using this command line: $ datsubmit 08 -list You may redo this exercise and re-submit your results as many times as you like. I will mark the most recent submission that is submitted before the final hand-in cutoff date. For Exercise 08, always use "08" as the first argument to "datsubmit". ---------- Test Suite ---------- Test your script. The sample inputs and output shown below are not a complete test suite. I will try to find test cases using glob patterns and blanks that will make your scripts abort or misbehave. Sample test output follows. Do not use the prompt examples "ENTER INPUT" given in the test suite - use a better prompt (not UPPER CASE) that tells the user exactly how many things to input and what to input. The test cases below are not exhaustive - make sure your program works without error for *any* inputs of any type containing any kind of special characters or blanks. Also try adding/removing permissions on various files to check that all the error messages are working. Test Preparation: $ tar czf mytar.tar.gz argv.cpp # create a test tar archive $ rm argv* # remove existing files Test1: $ ./labweek9.sh mytar.tar.gz argv Input tarfile: 'mytar.tar.gz' Program name: 'argv' Source name: 'argv.cpp' Program argv ( 12849) is larger than /bin/echo ( 12472) Test2: $ ./labweek9.sh ENTER INPUT1: mytar.tar.gz # user enters tar file name ENTER INPUT2: argv # user enters compiled program name Input tarfile: 'mytar.tar.gz' Program name: 'argv' Source name: 'argv.cpp' ... warning message about argv.cpp existing and renaming it to argv.cpp.bak ... warning message about argv existing and renaming it to argv.bak Program argv ( 12849) is larger than /bin/echo ( 12472) Your tests? Try testing with blanks in your file names. (I will do this.)