[cs615asa] HW3 revisited

Jan Schaumann jschauma at stevens.edu
Sat Mar 21 17:00:03 EDT 2015


Hello,

I've just finished grading HW3 and will send out grades in a little bit.
As before, here are a few comments that apply to many of you:

--

In order to be able to run the command, it needs to have a valid 'hash
bang'.  That is, the first characters of the file are '#!' followed by
an optional space followed by the path to the executable to be used to
interpret the contents of the file.  (Most Unix versions will default to
/bin/sh if no hash bang is given at all.)

If you make a typo here, the program will fail.  If you add an
executable here that doesn't exist, then your program will fail.

Since your program needs to run on a number of different Unix versions,
you need to take this into consideration.  For example, some systems do
not have '/bin/bash'.  (Reminder: "bash" is not the same as "/bin/sh"
aka "the bourne shell".  The latter is a POSIX requirement; the former
is a shell that provides a superset of /bin/sh functionality.  If you
write bash code, it may lead to errors when attempted to be interpreted
using /bin/sh, while the opposite is no problem: bash can correctly
handle /bin/sh compliant code.)

If you used '#!/bin/bash' as your hash bang, then I can immediately tell
that you did not test your program on all the platforms specified in the
assignment.  And yes, when I explicitly note in the assignment that your
tool has to work on a given set of platforms, then I do expect you to
test your code there.

Understanding the subtle differences of the tools across the different
versions of Unix is an important lesson.

--

Your tool is supposed to read data from stdin.  Since all unix tools you
are invoking to extract the information we're looking for do this
already, there is no need for you to buffer the input in any way.

Many of you used this pattern:

while read line; do
	echo $line | grep something
done

This entire while loop is useless.  Your program would work just as well
if you had simply written

grep something

Looping over the lines here slows down your program.

Writing input to a temporary file and then process that file is another
approach with many undesirable consequences.  Securely creating and
handling temporary files is not trivial, as you need to account for
atomic and unique file creation and ensure removal after you are done
(including when you abort unexpectedly) and generally requires the use
of an exit handler triggered by certain signals, not to mention dealing
with the various error conditions involved (what do you do if the
filesystem is full?).

Don't create temporary files unless you absolutely and positively cannot
avoid it.

--

Several of you decided that the program as described to you was not
complete and chose to extend it by adding additional flags.  I seem to
recall having told you very explicitly to not add additional features.
Adding a new flag means that now the program does not match its manual
page.  It adds code that can (and in at least one submission did) have
bugs.  In some of your submissions it also introduced inconsistencies in
the user interface, since you chose to use "--help" when all the other
flags are single-dash flags.

--

Several of you seem to have spent a great deal of time looking or and
then copy and pasting from Stackoverflow a regular expression that
supposedly matches IPv6 addresses.  In class, we explained that trying
to do that is a Bad Idea and, in most cases, complete overkill.  On the
mailing list, we also noted that you can assume that things that kinda
look like IP addresses in your input are ok.

By adding what Somebody Somewhere On The Internet claimed to be a valid
IPv6 matching regex, you needlessly made the program overly complex,
harder to read, and more error prone:  now you needed a grep(1) that can
parse this regular expression.  Not all Unix versions ship a grep(1)
that does this.  As a result, many of your submissions failed miserably
when run on OmniOS.

Some of you also were inconsistent in being rigorous about the use of
regular expressions (or simply didn't find a convenient Stackoverflow
post with an IPv4 regex) and used a 'good enough' match for IPv4, but
then used the 660 character long IPv6 regex...

--

Finally, here's a little script I used to test each of your submissions
on each of the platforms.  This is just to give you an idea of how
everything can be automated:


#! /bin/sh

# These instances are no longer running.  You'd have to create your own
# instances and add them here to reproduce.
fedora="fedora at ec2-54-167-158-146.compute-1.amazonaws.com"
freebsd="ec2-user at ec2-54-145-144-246.compute-1.amazonaws.com"
netbsd="root at ec2-184-73-57-144.compute-1.amazonaws.com"
omnios="root at ec2-54-166-243-133.compute-1.amazonaws.com"

# All your submissions are available under the current working directory
# in subdirectories named after your usernames, as required in the
# assignment.

for user in *; do
	echo "=> $user"
	for host in ${fedora} ${freebsd} ${netbsd} ${omnios}; do
		echo "==> ${host}"
		scp ./${user}/ifcfg-data ${host}:
		ssh ${host} "echo | ./ifcfg-data"
		if [ $? = 127 ]; then
			echo "Unable to execute script"
			continue
		fi
		for flag in i m n; do
			echo "===> -${flag}"
			ssh ${host} "/sbin/ifconfig -a | ./ifcfg-data -${flag}"
		done
	done
done

--

Most of you got most of the things right, but please do revisit how your
program runs (or doesn't) on the different platforms.

-Jan


More information about the cs615asa mailing list