B09 Lab week 3

This lab consists of two questions.

Windows Text Files (WTF) (2 marks)

I have two shell scripts that are “the same” (just you wait), but I created them on different platforms: hello-unix was created on Linux, hello-windows was created on Windows. When I test both on Mathlab, hello-windows has a problem, and it doesn't matter how I run it (by calling sh, by calling bash, as an executable):

$ sh hello-windows
hello-windows: 5: Syntax error: end of file unexpected (expecting "then")

$ bash hello-windows
hello-windows: line 5: syntax error: unexpected end of file

$ ./hello-windows
-bash: ./hello-windows: /bin/sh^M: bad interpreter: No such file or directory

hello-unix does not have a problem:

$ sh hello-unix
hello

$ bash hello-unix
hello

$ ./hello-unix
hello

WHYYYYY???!!!

Both files are on Mathlab in /courses/courses/cscb09s24/laialber/l03 so you can (and should) see for yourself.

Some ways to start investigating:

What to hand in: wtf.txt containing your short answer for how Windows and Unix differ in text files. (If you just answer the 3rd bullet point above, that will suffice.)

P.S. Now that you know, you have no excuse for handing in a shell script that breaks on Mathlab!

Shell Script Argument Processing (6 marks)

This question practices shell scripting, argument processing, and keeping states with variables.

The shell script you will write will be called “check.sh”. Its job, in short, is to check existence and/or directory-ness of user-provided pathnames. In detail:

The arguments are normally taken to be pathnames (but there is a twist below). For each pathname p, in the given order, check whether p exists (regardless of type) or not, and outputs one of the following messages accordingly:

p exists
p does not exist

However! If a pathname is preceded by one or more occurrences of “-d” (as a separate argument, not as part of a pathname, see example below), then instead check whether the pathname is an existing directory or not (i.e., the “[ -d p ]” test), and the possible messages are instead:

p is a directory
p is not a directory

Note that the negative case applies to both non-existing pathnames and existing but non-directory pathnames, as per the meaning of the “[ -d p ]” test. (So this part keeps your job simple! ☺)

Example:

sh check.sh 'my path' ../p2 -d ../p2 ../p2 -d -d 'my path'

This means the following checks, in order:

  1. Does my path exist? Note that this pathname contains a space.
  2. Does ../p2 exist?
  3. Is ../p2 a directory?
  4. Does ../p2 exist? (Yes just do it again, don't bother remembering the past, if the user is being redundant, let them!)
  5. Is my path a directory? Note that two consecutive occurrences of -d does no harm.

Hint: Use a variable to remember “the previous argument was/wasn't -d”.

One last example:

sh check.sh /usr/bin -d /usr/bin /usr/bin/date -d /usr/bin/date /dne -d /dne /dev/null

The expected output is provided as sample-output.txt. Tell the computer to compare for you so it catches typos humans don't see, e.g.:

sh check.sh /usr/bin -d /usr/bin /usr/bin/date -d /usr/bin/date /dne -d /dne /dev/null > actual.txt
diff -u sample-output.txt actual.txt

diff finds and prints line-by-line differences between two text files. If there is no difference, it outputs nothing, and the exit code is 0.