The joy of code: Command-line email
As I’ve written before, one of the wonderful things about work on the command line on a *nix [1] system is that you can easily string commands together to achieve more powerful results. As an example, suppose I have a text file containing lines of the form
username Assignment Grade
For example, my grade on homework 5 might be recorded as
rebelsky hw05 88
If I wanted to see all the grades on the first exam, I can write an expression something like the following.
$ grep exam01 grades rebelsky exam01 77 smith123 exam01 95 jones123 exam01 40 ...
As this example suggests, the grep
command searches for text.
If, in contrast, I want the grades on exam1, sorted in decreasing order, I can write an expression like the following [2].
$ grep exam01 grades | sort -k3 -n -r smithabc exam01 100 jonesqrs exam01 99 skyrebel exam01 99 skyrebel2 exam01 98 smith123 exam01 97 ...
In this case, the sort
command puts things in order. The -k3
means
to use column 3 [3]. The n
means to sort numerically. And the -r
means to sort in reverse order (from largest to smallest rather than
smallest to largest).
What if I just want the names of top five exam scorers? I can
use the cut
command to select just that column, and the head
command to take the first five rows..
$ grep exam01 grades | sort -k3 -n -r | cut -f 1 | head -5 smithabc jonesqrs skyrebel skyrebel2 smith123
Whoops! That was a longer digression than I’d planned. Anyway,
as the examples suggest, I tend to store my grades in a protected
file of the form above. I use commands like the above when I need
some quick pieces of information and more complex scripts when
I need more sophisticated calculations. For example, here’s the
output of my makereport
script.
$ makereport "Skyreb, Elizabeth" skyrebel Estimated Grade Report for Skyreb, Elizabeth [skyrebel] This is an experimental grade report and is not guaranteed to be accurate. Estimated grades are based on current status in the course. Final grades may therefore be much different. SUMMARY REPORT -------------- Homework ......... (15.0%): 89 (3.4 on a 4-point scale) Labs ............. (10.0%): 100 (10/11; up to 2 missing labs permitted) Quizzes .......... (10.0%): 95.0 (69.5-4-8.5)/6) [dropped two lowest] Project .......... (10.0%): [Not available] Exams ............ (40.0%): 81.0 (on 2 exams) Final ....................: [Not available] Best individual .. (10.0%): 95.0 Participation .... ( 5.0%): [Not available] Extra Credit .............: 5 units Estimated numeric grade: 74.8/85 = 88.0 Estimated numeric grade with 5 units of extra credit: 89.2 DETAILED INFORMATION -------------------- Homework: 89 hw01 check hw02 check hw05 check hw06 check+ Labs: 100 (10/11) lab05 1 lab06 1 lab07 1 lab09 1 Wrote helper in 6a lab10 1 did in Klinge's class lab11 1 strange answer lab12 1 particularly nice answer lab15 0 did not submit lab16 1 particularly nice answer lab17 1 no examples lab18 1 particularly nice answer, w/ documentation Quizzes: 95.0 (69.5-4-8.5))/6) [dropped two lowest] quiz01 10 quiz02 10 quiz03 4 quiz04 9 quiz05 10 quiz06 9 quiz07 9 quiz08 8.5 Exams: 81.0 exam01 77 006008 exam02 85 242000,pro Absences skyrebel absent 0.5 2017-02-01 (alarm clock failure) skyrebel absent 0 2017-03-01 (alarm clock failure) skyrebel absent 1 2017-03-07 Extra: 5 1 academic,2017-02-09,Convo 1 academic,2017-02-27,Standing Rock 1 peer,2017-02-18,Orchestra 1 peer,2017-02-04,Swimming 1 academic,2017-01-31,CS Table
Now, once I’ve generated one of these reports, it would be nice to send
it to the student. Conveniently, our Unix systems provide a simple
interface to mail called, not surprisingly mail
. This command takes
a variety of command-line flags, such as the subject, people to carbon copy,
and, obviously, the recipient. That means I can type commands like
the following.
$ makereport "Skyreb, Elizabeth" skyrebel | \ mail -s "[CSC 151] Estimated Grades for E. SkyReb" \ -c rebelsky@grinnell.edu \ skyrebel@grinnell.edu
Of course, I have a script to generate commands and run like that, taking the userid/name combinations from another file. That means I can easily generate and send grades whenever I need or want to [4].
At times in the past, I’ve also used chron
to schedule useful scripts
to run regularly (say, once each day) and to send me results. When I
was an annoying undergraduate [6], I used that capability to send a
regular reminder to my boss to give me a promised raise [7].
When I speak to non-*nix people (e.g., Microsoft aficionados), I find
that we have a very different sense of email. I get questions like Why
would you want a command-line email option? [9]
and Can’t you just do
that with Outlook? [10]
I miss the days before spammers took over the Internet mail system, and it was easy to just telnet to port 25 to send mail. Oh well; at least I have outgoing email capabilities from my College *nix box [11].
[1] Unix, Linux, FreeBSD, MacOS, etc.
[2] My son who uses R find that he writes similar expressions in R.
[3] It appears that the designers of sort
failed to understand
0-based indexing. Alternately, they may have assumed that their
users would prefer 1-based indexing.
[4] It turns out the workflow is really useful when a student asks
me What happens if I get X [5] on the final?
[5] No, they don’t ask about a grade of X
. Rather, they ask questions
like What happens if I get a B on the final?
[6] Is that redundant?
[7] Yes, I waited a reasonable amount of time [8] before starting the reminder emails.
[8] I know that you were thinking Sam probably waited an hour or so
,
but I actually waited about a month before sending the autospam.
[9] See above for some answers.
[10] Not in my experience.
[11] Admittedly, today I discovered that ITS accidentally broke those capabilities [12]. This musing is part of my attempt to document why I so value the ability to send mail from the command line.
[12] I will say that whoever is stuck helping me with the problem is working really hard on it. It can’t be fun, and I appreciate their hard work [14,15].
[14] Believe it or not, but those comments were completely serious. I know that figuring out what’s going on with mail systems can be hard, and I think we have a relatively new postmaster.
[15] It appears that they were up until one am fixing the relay. I really appreciate their hard work.
Version 1.0.1 of 2017-04-05.