Lab overview
Lab 01
Lab 02
Lab 03
Lab 04
Lab 05
Lab 06
Lab 07
Lab 08
Lab 09
Lab 10
Lab 11
Lab 12
Lab 13
Review

[Course home page]

CSC 209 lab 02 exercises, week of 17 May 2022

[solutions are available (requires teach.cs authentication)]

Introduction

You will need to do these exercises in a terminal window. If you don't know where to find a terminal window or how to use it, please see lab 01, and the unix command line video.

If you are logged in on a workstation, in the terminal window, first of all run "/u/csc209h/summer/present". This records your attendance and is required for you to get the marks for the lab.

If you are logged in via ssh, please tell your account name (UTORid) to the TA and they will mark you as present. Then, please check that you are correctly marked as present by checking the web page
https://wwwcgi.teach.cs.toronto.edu/~ajr/cgi-bin/auth/present


Part 1: Some fun with tools

Please cd to the directory /u/csc209h/summer/pub/lab/02 (relevant to some but not all of the items below), and write a unix command to produce the requested output:

  1. The number of lines in /etc/passwd. (The file "/etc/passwd" lists all user accounts on the system, one per line.)
  2. The count of how many users have an 'e' in their user information somewhere (anywhere in their line in /etc/passwd).
  3. The contents of the file named: &@$%*
  4. The alphabetically-first three lines in the file "abcdef", in order (i.e. the earliest alphabetically, then the second-earliest, then the third-earliest).
  5. The output of the "stupidproverb" command, but with every 'e' character translated to a '?'.
    (You can find "stupidproverb" in /u/csc209h/summer/pub/bin/stupidproverb)
  6. All file names in the current directory which contain a 'b'.
  7. The number of people who logged in at exactly 10:45.
  8. All lines of the file "abcdef" in the current directory which contain a capital 'E'.
  9. The number of blocks used by the directory /usr/include, using "du". But the output of "du /usr/include" has lines for each subdirectory and we only want the last line, the one with the total.
  10. /u/csc209h/summer/pub/lab/02/num is a text file listing integers, one per line. Output the largest number in this file.
What is the difference between the shell "glob notation" (file pattern matching) expressions "*" and "*.*" (without the quotes)? State a file name which one of them would match and the other would not match.


Part 2: Some numeric tools

1. Write a pipeline to output the greater of the integers in the variables 'p' and 'q' without using an 'if' statement.

2. Examine the seq command. It's very like the python range() function, although the bounds are inclusive. For example, try "seq 5 10".

3. Examine the dc command. Its input is in "reverse-Polish notation". There is a command "p" for "print" which outputs the top of the stack.
Try typing input such as "3 4 + p", or "3 4 5 * * p".
Whether or not spaces are required is pretty much the same rule as you've learned to expect in programming languages; for example, the second example above could be written as "3 4 5**p".
And any whitespace is equivalent (spaces, newlines, etc).

End-of-file exits dc, or the 'q' command.

4. A deck of 52 cards can be shuffled into 52! distinct permutations (i.e. the product of the integers from 1 to 52 inclusive). What number is this? Write the smallest sh command which outputs the number.


Part 3: sed (for credit)

Recall the "sed" filter, which implements a number of editor-like commands. These questions will be about its 's' command — search and replace.

We can change the first 'o' to 'x' in each line with: sed s/o/x/
The "sed s/o/x/" can be followed by file names, or it can read from the standard input. If the standard input is the terminal, we have to press ^D as the special end-of-file-from-terminal signal; instead of doing that, in this question we will use 'echo' and a pipe, like this:

	echo Madonna Ciccone | sed s/o/x/

1. That only translates the first 'o' on each line. How do you translate them all?

2. Why aren't quotes needed around "s/o/x/" above?

3. Write the 'sed' command which translates names of the form "Madonna Ciccone" to "Ciccone, Madonna" as demonstrated in the first lecture.
Tools to use: regular expressions (the normal kind, not the "glob" notation); and backslashed-parentheses in the search string matched with backslashed digits in the replace string.
If you can't reproduce this, it's here (you'll need that to go on).
Why are quotes needed here but not in the earlier example?

4. Write a sed command which doubles the first 'x' on each line. For example, "h@x0r" would become "h@xx0r". Don't use quotes unless necessary. Put this in a file named "dblx" ("dbl" for "double").

5. Write a sed command which doubles the first digit on each line. For example, "h@x0r" would become "h@x00r". Don't use quotes unless necessary. Put this in a file named "dbld".


Part 4: Some fun with variables

1) What are the values of the variables "foo" and "bar" after executing the following commands? Suppose that the user types "bip" on the standard input.

a)

	foo=bar
	bar=baz
	read foo

b)

	foo=bar
	bar=baz
	read $foo

Figure this out in your head (or on paper) without actually trying the commands, then try the commands on computer to verify your answer.

2a) Assuming that the variable 'i' contains a well-formed positive integer, write a command to output that number of lines containing your name. For example, if i is 3, my command would output

	ajr
	ajr
	ajr
Just use standard unix software tools for now, not a loop construct.

2b) As in (a) but put them all on the same line (with a newline character at the end, and no extra spaces (including at the end of the line)).

3) Experiment with the command

	x=`expr $x + 1`
(you'll need to assign a number to 'x' first!)
Understand its behaviour, and try variants.

4) Suppose that the output from "ls -l myfile" looks like

	-rwxr-xr-x 1 ajr instrs 8304 Apr 30 16:55 myfile
with only one space between each field. Write a shell command to set the variable "month" to the month value in the output of ls -l myfile (e.g. if the above is ls's output, month would be "Apr").

5) Experiment with the command

	echo `seq 5 10`
Understand its behaviour, and try variants.
Compare this to the simpler command
	seq 5 10
When would you prefer one and when would you prefer the other?

6) We want to output the sum of x and y. The following command is needlessly complicated. What's a simpler way to write it?

	echo `expr $x + $y`


Part 5: A little shell script (for credit)

Write a shell script whose interaction looks at first like this, where prompts (output) are alternating with user input (and we first show the invocation of the shell script itself, at the '$' shell prompt):
	$ sh hello
	What is your name?
	Sally
	Are you a girl or a boy?
	girl
	How old are you?
	10
After that exciting initial interaction, your program outputs the following story:
	Once upon a time there was a little girl named Sally.
	Sally had a brother named Bill who was three years older.
	Bill was 13 years old.
Note: use this this text verbatim, as this lab will be graded automatically! (Substituting the appropriate substitutions, of course. Note the computation to get that "13" in the example.)

You do not have to do any validity checks on the input. If the user types something strange (or just presses return) for the first two prompts, your program will output strange results. If the user types something strange for the third prompt, your program will probably misbehave. All of this is fine. Since you might not have done 'if' in shell scripts yet by this point, just assume that the inputs are valid.

Testing note:

Try creating a file named "namet" (those exact five lower-case letters) in the current directory and running your program. Does it still say "name?" with the question mark? If it misbehaves, fix it.

Part 5b

There is a file /u/csc209h/summer/pub/lab/02/input containing the three lines "Sally", "girl", and "10"; and a file /u/csc209h/summer/pub/lab/02/output containing the expected output (including the prompts from the initial interaction).

Formulate a command-line to run your shell script with /u/csc209h/summer/pub/lab/02/input on the standard input, and diff its output with /u/csc209h/summer/pub/lab/02/output to make sure you got it right. For full marks for this lab, you must have no differences at all, not even spaces. Again, this is an exercise in having full control of the tools you are using (rather than being any sort of assertion that my choice of spacing is superior).

Note: You do not modify your shell script to read from the file /u/csc209h/summer/pub/lab/02/input; you just use the '<' operator in the shell to redirect the input to your shell script. Your shell script can still be used interactively (and probably usually would be). And of course your shell script must still work for other correct inputs (not just those in the sample input file).


Part 6

1) Recall the introduction of the sh 'if' statement in lecture: The 'if' keyword is followed by any arbitrary command, but a common useful one is the "test" command. One format for command-line arguments to "test" is to have three arguments, where the middle one is an operator which is one of: So, making use also of variable interpolation, to output "foo" if the value of variable 'x' is less than three, we could write:
	if test $x -lt 3
	then
	    echo foo
	fi
There is also an 'else'.

2) Using seq, output the numbers from $x to $y inclusive, starting with $x and ending with $y.
But you can't just say "seq $x $y" because y might be less than x, in which case you need to say "seq $x -1 $y".

3) If you aren't familiar with the Towers of Hanoi problem, then (assuming that you're not in the lab any more) please watch a video at https://www.youtube.com/watch?v=TwLDf1Dv1M0

The recursive solution in code looks like this:

	procedure hanoi(ndisks, from, to, scratch):
	    if ndisks > 0:
		hanoi(ndisks - 1, from, scratch, to)
		print 'move disk', ndisks, 'from', from, 'to', to
		hanoi(ndisks - 1, scratch, to, from)

Write it as a shell script. It does recursion by running itself, assuming that it is in the current directory. You will invoke it (and it will recursively invoke itself) like this:

	sh hanoi 5 A B C
which means to transfer five disks from pile 'A' to pile 'B', using 'C' as scratch space.

Within your shell script, you can access the first parameter (the number of disks) as $1, the second parameter (the 'from' pile) as $2, and so on.


Part 7: software tools principles (bonus)

Suppose that you write a program to convert from joules to calories. Your program reads the joules value on the standard input and writes the calories value on the standard output, and nothing else. Your friend's program prints a prompt, reads the joules value, then outputs "[whatever] joules is [whatever] calories."

What software tools principle does your friend's program violate? And give an example of a use for this tool for which your version is easier to use.

For bonus marks of about 10% of the lab value, answer this question in a short text file named "lab02p7". Your answer must be short and clear to receive the marks.


To submit

First of all, during the lab time, on the console of a lab workstation, you must run "/u/csc209h/summer/present", or get the TA to mark you as present.

Then, by midnight at the end of Friday May 20, you must submit solutions to part 3 exercises #4 and #5, part 5, and optionally the part 7 question, as follows.

First, put the solutions in separate files named dblx (part 3 question 4), dbld (part 3 question 5), hello (part 5), and optionally lab02p7 (part 7). You can test your part 3 solutions with commands such as

echo xylo6h0ne | sh dbld
as well as
sh dbld <file
(for some file named "file").

Make sure that your lab02p7 solution is a plain text file by typing "cat lab02p7".

Secondly, submit with the command

	submit -c csc209h -a lab02 dblx dbld hello lab02p7

Note in this command that the "lab02" is the "assignment" name you are submitting under, and the "dblx", "dbld", "hello", and "lab02p7" are the files to submit. You can submit them simultaneously as above, or at different times.
You may still change your files and resubmit them any time up to the due time.
You can resubmit a file by using the −f option, e.g.

	submit -c csc209h -a lab02 -f dbld
As well, you can check that your files have been submitted with the command
	submit -c csc209h -a lab02 -l
(that's minus 'l' for "list", not a 'one')

If there are any problems with this, please ask by e-mail. Problems running the 'submit' command will not generally be accepted as a reason for lateness.

Important academic offence note!

Your work in this course which is submitted for course credit must be your own. Representing someone else's creative work as your own is an academic offence.

The lab work in this course is individual. You can discuss the items which are not for course credit with anyone, but the items which are submitted for course credit must represent your own work. It is also an offence to assist others in committing an academic offence (e.g. by providing your solution to them).

If you have questions about work to be submitted for course credit, ask a TA or the instructor (perhaps by e-mail). More information at the end of the course information sheet.