CT320 HW6: Eternal Vigilance!
In the previous assignment, we kept track of which files were
appearing and disappearing. That was great, but it’s not enough. In
the system administration business, you have to keep track of a lot of
- Are the disks still mounted?
- Is the network up?
- Is the web server running?
- Have any users been added?
- Is Galactus approaching our solar system?
If only there were a program to help you keep track of things.
One that could … guard … against unexpected changes!
For this assignment, you will write a program called “
which helps you keep track of things. It can be a
bash script, a
perl script, or a
python script, but nothing else. This program is
useful for system monitoring. You run it with arguments,
from any directory, like this (
% is my prompt):
% ./guard id
That says to run the
id command, and note its output.
Then, later, if you run
guard id again, it will run the
command again, and inform you if anything has changed.
guard date will probably change every time,
unless you’re quick. However, we don’t expect
guard id to change
There are three cases:
- This particular command (and arguments) has never been executed before.
Say so, and display the output of the command.
- This command (and arguments) produced the same output as before.
Display nothing, because nothing changed.
This is the normal, happy, case.
- This command (and arguments) produced different output than before.
Say so, and show the difference between the old and new outputs using
diff. Also, update the saved output with the new, changed, output.
guard would typically be executed from
cron, where the output
gets mailed to you. Ensure that the output is sufficiently labeled so
that it makes sense, even out of context. Of course,
knows nothing about email—
guard simply produces output or not.
cron handles emailing the output to you.
guard takes a number of arguments, which will form a shell command.
All of these should work. Remember that
% is my prompt, yours
will be different.
% ./guard id
% ./guard date +%c
% ./guard cat /etc/passwd
% ./guard "sed 's/:.*//' /etc/passwd | sort"
% ./guard gcc --version
% ./guard 'cd ~info; ls -ld m*'
% ./guard echo a/b/c
% ./guard echo abc
% ./guard echo a b c
If the option
--trace is given before the command, then
will add debug output. It’s your choice for what that means, but it
must at least mention the full path where the output is stored.
If the option
--all is given, with no other arguments,
guard will list the commands in the database.
The commands listed must be the same as they were entered—mangled
versions are not acceptable.
guard has to store the commands and results somewhere. For that
purpose, it will use the directory
~/.guard, which your program
must create as needed. How it actually stores the data under
~/.guard is up to you. You could have one big file under
~/.guard, a number of files, an entire hierarchical directory
structure, etc. You have to create
Note that the command given to
guard can contain all sort of
special characters: spaces, stars, quotes, slashes, etc.
Sample Use from
Here are some examples of use from
cron. If no changes occur,
guard produces no output. However, if changes do occur,
guard proudces output, which
cron then mails to you.
# Ensure web server is working:
*/5 * * * * guard wget -qO- https://www.cs.colostate.edu/~applin/alphabet
# Do my directories have proper permissions?
# Use \% because cron interprets % specially.
@hourly guard stat -c '\%A \%n' ~ ~/public_html ~/public_html/pmwiki
# Compiler updates?
@daily guard g++ --version
@daily guard python3 --version
# General paranoia
@daily guard id
@daily guard pwd
@daily guard host $HOSTNAME
@daily guard cat /etc/system-release
@daily guard uname -r
If you encounter “STACK FRAME LINK OVERFLOW”, then try this:
- “Command” generally includes the arguments. For example,
echo a and
echo b are two different commands.
- On the other hand, the same command executed in two different
directories is considered to be the same command.
pwd is only one
command, even though it gives different results in different
directories, so it’s a poor candidate for use with
- Error messages go to stderr.
- All error messages must include
$0 (or its equivalent).
- Provide a usage message and stop for no arguments,
or for bad arguments (for example,
- Capture both stdout & stderr of the command.
Use web checkin, or:
~ct320/bin/checkin HW6 guard
How to receive negative points:
Turn in someone else’s work.