CT320 HW6: Eternal Vigilance!
Motivation
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
things:
                
- 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!
                
Summary
For this assignment, you will write a program called “guard
”,
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 id
command again, and inform you if anything has changed.
                
For example, guard date
will probably change every time,
unless you’re quick. However, we don’t expect guard id
to change
too often.
                
Output
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, guard
itself
knows nothing about email—guard
simply produces output or not.
cron
handles emailing the output to you.
                
Arguments
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
Options
If the option --trace
is given before the command, then guard
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,
then guard
will list the commands in the database.
The commands listed must be the same as they were entered—mangled
versions are not acceptable.
                
Database
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 ~/.guard
.
                
Note that the command given to guard
can contain all sort of
special characters: spaces, stars, quotes, slashes, etc.
                
Sample Use from cron
:
Here are some examples of use from cron
. If no changes occur,
then guard
produces no output. However, if changes do occur,
then guard
proudces output, which cron
then mails to you.
                
SHELL=/bin/bash
PATH=/bin:/usr/bin:~/bin
# 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
Debugging
If you encounter “STACK FRAME LINK OVERFLOW”, then try this:
export STACK_FRAME_LINK_OVERRIDE=ffff-ad921d60486366258809553a3db49a4a
Requirements
- “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 guard
.
- 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,
-Z
or --zulu
).
- Capture both stdout & stderr of the command.
Submission
Use web checkin, or:
                
~ct320/bin/checkin HW6 guard
How to receive negative points:
                
Turn in someone else’s work.