CS32, Fall 2017

Lab05:
Shell scripts


Goals for this lab

By the time you have completed this lab, you should be able to

Step by Step Instructions

Step 0: Choose initial pair programming roles, and log on

Let the person who was not the first pilot last week be the pilot first this time. Switch roles after awhile, before the pilot gets tired, and before the navigator gets bored or distracted.

If your regular partner is more than 5 minutes late, ask the TA to pair you with someone else for this week.

Step 1: Create a directory for this lab in the pilot's account

This lab's pilot should log in. You will (both) work in this account for the rest of the lab.

Create a ~/cs32/lab05 directory and make it your current directory:

mkdir ~/cs32/lab05
cd ~/cs32/lab05

Step 2: Practice creating and running a simple script

Recall (from lectures/readings) that a script is a collection of shell commands and control structures. In fact a script is like a program written in the language of a particular shell. The shell interprets the script, and executes the commands in the order prescribed by the program. Any sequence of shell commands that are stored in a file can (basically) qualify as a script.

Use an editor (e.g., emacs) to create a file named rootcontents.sh - then type just the following two lines in it, and save the file:

cd /
ls
Now tell an appropriate shell to execute it, like sh for instance (user input is bold):

bash-4.3$ sh rootcontents.sh 
bin   dev      etc   lib    lost+found	opt   run   sys  usr
boot  develop  fs    lib64  media	proc  sbin  tmp  var
cs    ece      home  local  mnt		root  srv   u01

To repeat: "you must tell an appropriate shell to execute it." The point is that the shell is the executing program, and the script is just the specific instructions that program is asked to execute. The default shell will run it if you don't specify:

bash-4.3$ ./rootcontents.sh
bash: ./rootcontents.sh: Permission denied

Oops, first we must change the permissions of the script file to make it executable. Then bash, our default shell, will execute it:

bash-4.3$ chmod 755 rootcontents.sh 
bash-4.3$ ./rootcontents.sh
bin   cs   ece	fs    lib    local	 media	opt   root  sbin  sys  usr
boot  dev  etc	home  lib64  lost+found  mnt	proc  run   srv   tmp  var
bash-4.3$ pwd
/cs/class/cs32/labs/lab05

NOTICE TWO IMPORTANT THINGS:

  1. After the last run we typed pwd and found out our current directory was still local to our account, and not the root (/) as specified by `cd /` in the script.
    Do you know why? Think about it, then click here for the answer.
  2. This script was very simple, using commands standard to all shells and with no special options or syntax. So any shell can execute it without errors. Most scripts use syntax that can vary between shells though, so script-writers usually include a shebang as the first line of the script.

Fix the script now (as per important thing #2) by typing the following at the very start of rootcontents.sh:

#!/bin/sh

Then run the script again to verify it still works. The shebang must be the very first line of the script, and it must not even have any spaces before it.

Normally you would follow the shebang with a comment. In keeping with this convention, add the following comment (begins with '#') right after the shebang as shown - substituting your actual name(s), of course:

#!/bin/sh
# Very simple script to display the root's contents
# YOUR NAME(S), 11/7/2017

Step 3: Learn (or hopefully review) more sh scripting syntax

Sufficient sh scripting techniques were presented in lecture to handle the Step 4 work below. In case you missed it, here is a link to the demo scripts presented in lecture. Additional techniques might be required for Step 5 though, so here is a short sh script primer, and here is a link to a nice shell scripting tutorial.

Peruse/review these materials now, and then refer back to them as necessary to complete the rest of the lab work.

Also remember that shell scripts just contain shell commands, and that these commands can be tested interactively at the shell prompt. In other words, don't be afraid to try stuff before including it in your script. To split long commands (or control structures), use the continuation character, '\', at the ends incomplete lines.

Step 4: Write an sh script to list writable items in a directory

SWITCH ROLES WITH YOUR PARTNER now if you have not already done that. Please remember to do so frequently in every lab, and we promise to stop pestering you about it. Thanks!

Step 4 begins a fairly useful script, that you will complete in Step 5. We expect you to finish this step during the lab today - it is not too hard or too long.

Write a script named lw (most scripts don't have extensions like .sh; and that's an ell, not a one before the w) to list the writable items in the directory specified by the user at the command line. For example, assuming that lw has its permissions set to execute, then the following command would print the names of just the writable items in the directory named myfiles:

./lw myfiles

Here are two sample runs, one for the current directory ('.'), and one for the root:

bash-4.3$ ./lw .
writable files in .:
lw
rootcontents.sh
bash-4.3$ ./lw /
writable files in /:
tmp
Be sure your results exactly match these samples, including the header message ("writable files in " directory name).

Do not consider any error checking for this step. That is, for example, if the user does not specify a command line argument, or if the argument is not a readable directory name, then the script's behavior may be unpredictable. That's okay for now.

Be sure to include the shebang line at the beginning of the script.

Also include a comment with your name(s) and the current date. Please do this for every file you create in CS 32 labs in the future too. Thanks.

Make the file executable - type 'chmod 755 lw' - then test it a few times until you are sure it is working properly before continuing to the next step.

Step 5: Enhance the script to check for user errors, and fully test it

Add the following error-checking features to the lw script, and make sure your results exactly match the sample results below, including the exact error messages and the specified exit return codes:

  1. Add usage instructions to display if the user does not enter any command line arguments. Also exit in this case by signaling 1 (error value) to the operating system (`exit 1`). Results must match the following:
    -bash-4.3$ ./lw
    usage: ./lw directory
    -bash-4.3$ echo $?
    1
    By the way, use $0 to print the script name properly and completely in the usage message.
  2. Verify the directory exists. Match this error message and exit code:
    -bash-4.3$ ./lw nonsense
    there is no directory named nonsense
    -bash-4.3$ echo $?
    2
  3. Verify the directory is readable by the user. Match this message and exit code:
    -bash-4.3$ ./lw /root
    you do not have permission to read /root
    -bash-4.3$ echo $?
    3
  4. Verify the file is a directory. Match this message and exit code:
    -bash-4.3$ ./lw rootcontents.sh 
    rootcontents.sh is not a directory
    -bash-4.3$ echo $?
    4

Fully test all required features of the script before turning it in. It is especially important that your results exactly match the results of our solution, as we will use grading procedures that depend on exact matches.

Step 6: Turn in lw with turnin at CSIL

You MUST have both your name and your partner's name in the file for both of you to receive credit. Remember that the original pilot needs to do this step, since that is whose account you have been using in the lab.

Bring up a terminal window on CSIL, and cd into the original pilot's cs32 directory, and cd again into the lab05 directory. Then type the following to turn in your version of lw:

turnin lab05@cs32 lw

Respond "yes" when the program asks if you want to turn in (be sure to read the list of files you are turning in), and then wait for the message indicating success.


Evaluation and Grading

Each pair of students must accomplish the following to earn full credit [50 points] for this lab: