For CS 354, grades are stored in ~cs354/grades/$USER as text files that get
updated when your grades are changed. Thus there are no automatic notifications
like with Brightspace or Gradescope.
To solve this, you can create the following shell script and Systemd service to monitor for grade changes. It will email you when any grade file is written to.
Place this somewhere like ~/.local/bin/monitor_cs354_grades.sh.
#!/bin/bash
set -e -u -o pipefail
GRADE_DIR=~cs354/grades/"$USER"
inotifywait -m --includei '\.rpt$' -e close_write "$GRADE_DIR" \
| while read -r dir events file; do
echo "$file updated" >&2
printf 'Subject: CS 354 %s grade updated\n\n' "${file%.rpt}" \
| cat - "${dir}${file}" \
| sendmail -bm -i "$USER"
echo "Email sent" >&2
done
Here is a brief explanation of what this does:
inotifywait is a tool that uses Linux’s inotify(7) interface to watch
for file I/O events.inotifywait to monitor for events where a file opened in write mode
is closed on files ending with .rpt in the grade directory.sendmail.sendmail is provided by Postfix, the mail server installed on the CS
servers, and is used to send email.To run the shell script in the background constantly, we can use Systemd.
Run the following command to create a new service file. You can replace the name with whatever you like.
$ systemctl --user edit --full monitor-cs354-grades.service
This will open the new file in a text editor. Give it the following contents.
[Unit]
Description=Monitors CS 354 grades and emails upon updates
[Service]
Type=exec
ExecStart=%h/.local/bin/monitor_cs354_grades.sh
Restart=always
[Install]
WantedBy=default.target
First, enable “linger,” i.e. allow services to run even after you log out.
(See loginctl(1) for details.)
$ loginctl enable-linger
Then enable and start the service.
$ systemctl --user enable --now monitor-cs354-grades.service
Some useful systemctl commands:
systemctl <action> <unit>.systemctl status <unit>.journalctl --user -eu <unit>.systemctl edit --full <unit>.
To apply these commands to your user-scoped Systemd instance instead of the
system-level one, insert the --user option as the first argument to the
commands.