I've been technically assisting my father on a project where he needs to send an email to a few hundred people.
Previously, he was going it from the Gmail GUI 75 people at a time, copy-paste into bcc in the compose window, but now that I have SMTP infra, why not a for loop? 🧵
Relatively simple problem once you have the email infrastructure up, right?
cat mailinglist | while read EMAILADDR; do cat ./emailbody.txt | mail -s "Subject" -a "From: me@example" $EMAILADDR; done
So I was helping him understand the headers and how best to invoke the mail cmd
Quick and easy bash one-liner when we were ready to launch though, right?
Wrong. My father came back today with his 250 line bash script he wrote for sending this bulk email blast.
And *chef kiss* a work of art it is.
First, you've got your file header with canonical location, purpose, copyright notice, and revision history.
Then you start getting into the functional blocks of the code, each titled with a visual block so it's easy to find section breaks while scrolling
Setup: This script functionally depends on the system environment it's running on.
Namely that it's specifically on the host with the postfix server configured...
So we check that we're on the host we expect to be running on and print an error and quit if not.
Function definitions: Just in case you forget the exact command syntax for this shell script, we have a function that prints the usage instructions for it, for when you run it with -h!
Next we're into the main functional part of the script, where we start by parsing the command line arguments.
Set them all to a default "", then loop through getopts to parse the arguments given by the user from the CLI
You notice how he has all this strange \e[1;31 line noise sprinkled in his echo statements?
Colors. They're ANSI/VT100 color commands.
The error messages for this script print in color.
Notable lines in the case statement include...
h) call the usage function, and exit 0, to indicate that the script completely successfully
\?) Puke on unparsable options, print usage, and exit 1 to indicate failure
:) Puke on options which require arguments, print usage, and exit
But we're not just going to trust the user. We absolutely need a minimum set of the arguments to run, so we're going to loop through them and check to make sure they're not the empty "" we set them to earlier.
And we're not just going to trust that the user gave us a correct filename for the distribution list. We're going to use the if -r flag to check to see that we're able to READ this file the user so dutifully provided us the name for.
But what if the user gave us a readable file, but it doth not contain email addresses?
Well then you can go exit 1 to hell too. We aren't going to tolerate that shit around here.
The English language has this annoying property where it uses different words for one or many of something.
And users have this annoying habit of speaking English or something, so we... better figure out how many emails we're sending here in "send_bulk_email.sh" 😐
And this isn't for the actual bulk mailing. This is literally just so the interactive prompts and status messages while this script runs are syntactically correct.
Wouldn't want it asking if you wanted to actually launch these "emails" when there's only one email being sent!
I will admit... This is kind of at most the dozen lines of bash code I was actually planning on us writing for this project...
while read loop, send email.
He even checks the exit code from mail with the $? built-in so if it starts erroring half way through the loop it exits.
And you wouldn't want to leave your TMP files laying around. Who knows how many times you might run this script before you run out of disk space...
And that, ladies and gentlemen, is the 250 lines of robust industrial grade bash code my father wrote to send a few hundred emails.
And a look into what it was like growing up in my childhood, if we're really being honest here...
Expecting *everything* to go wrong.
• • •
Missing some Tweet in this thread? You can try to
force a refresh
Are you a flooring installer and you can't be assed to get all your panels of 79¢ laminate to seat right?
It kind of looks like wood, so why not use wood putty to fill the gaps?
And yes, the astute will notice that this laminate is installed wrong anyways because you're supposed to stagger the seams much further apart than that.
Did you drop one of the boxes of panels on its end and badly damage them all?
Those panels are expen... not free! Use them anyways!
One of my nice friends at @henet gave me a dead 100G-LR4 optic to tear apart for your entertainment, so... let's get entertained! 🧵
100G-LR4 is a QSFP28 optic that runs over a duplex pair of single mode fiber, so it takes 4 lanes of 25G from the switch, modulates 4 different colors of light, and combines them together over a single strand to the other end up to 10km away.
Me: "Huh... I wonder why this Ubuntu 20.04 image is still using the SysV networking service..."
Me, two hours later: *The internal screaming intensifies*
In case you can't figure it out, this is a really stupid trick I've seen on IPv4 to save address space where you assign a /32 to the public interface, then point default via a static on-link route to the router on any other address you want.
I have never seen this trick on v6.
"If it's stupid and it works..." does NOT fucking apply here.
Through a long series of unfortunate events, for our smallest Thanksgiving ever, my dad has ended up cooking a 19lb turkey.
Granted, we also usually do two turkeys and a ham, so I guess just a single turkey of any size is more reasonable.
It's important to remember that a mind boggling number of people are food insecure today, and that's a truly terrifying sensation that's hard to imagine.