There might arise situations, where a monitoring script is in dire need to send an e-mail. But how do you send mail when for some reason the mail system itself is dysfunctional? Bash to the rescue. Building upon my
previous post on bash networking, I put together a bash_mail function, which is capable of connecting directly to an SMTP server (without authentication or SSL) and send email message. The function respects best practices and tries not to trigger anti-spam mechanisms by dutifully awaiting SUCCESS response codes from server and aborting on server fail code. The function returns 0 when all went OK and 1 or 2 depending on the state it dropped off.
UPDATE: Taken into account ideas from a coworker, I tweaked the code to (1) run in subshell to release filedescriptor requirements, (2) use loop for DRY and (3) drop cat usage to be as much as possible self-sustained.
UPDATE 2: Script adjusted to comply to SMTP standards regarding instead of simple as pointed out by Zoot in the comments.
The function can be used as a function in other scripts. Just source it in, where needed. You can also define the arguments, without rewriting the function:
source bash_mail.sh # just send the mail with hard-coded parameters bash_mail # define important parameters bash_mail "me@example2.com2" "Still Panic"
WOW!..this code is ingenous, beautiful, simple and elegant….I love it! 🙂
LikeLike
Thank you!
If you find usage for this, I would like to hear how and where.
LikeLike
Starting with the “where?”….Amsterdam, Netherlands ! 🙂
At the moment I’m finetuning a fully automated video conversion server whitch is completely event driven and parallell processing.
I’ve written this in bash on top of a regular server distro. Why bash ?
Well, because of the challenge; maybe I wanted to prove that it could be done, and at least learn something from it 🙂
Also I always think that good code needs to be modular, elegant, and posess a kind of beauty by simplicity; now i had an opportunity to proof that also, with a complex project like this 🙂
This server is running rock-steady for almost a year now.
I toyed for a while with the idea of mailing important events to the “sysop” (like logging by email) but didn’t want a full-blown pre-installed SMTP monster.
Then a friend of mine found your script. wow! This is exactly what is needed for the job and above all: featherlight, elegant, lucid and in bash; couldn’t be better 🙂
Soon I’ll have the command-by-ftp on a more mature level together with a sort of report agent or message unit, that is the moment I would like to incorporate the SMTP-client.
Also have to clean out some rats nests from the process-controller-code, it is readable but has no beauty.
Well, I have a week off and it’s raining here so I suspect I will make some progress 😉
LikeLike
Elegant script, thanks!
However, it sends Bare LFs, which thousands of mail servers will reject:
http://smtpd.develooper.com/barelf.html
Here’s a diff file I generated, so you can patch your script to be compliant 🙂
http://pastie.org/1017368
LikeLike
Thank you!
I updated the script accordingly.
Also I uploaded it to Gist to enable easier download and modifications.
LikeLike
cool! one thing, variables within a subshell is local to the subshell. so, bash_mail function would return a 1 (since $i doesn’t exist for the parent the function returns the default of 1).
LikeLike
You are correct of course. I added the subshell in a later phase, but never tested the fail-handling again.
I updated the code accordingly.
LikeLike
[…] what i was looking for was a way to mail it to me, as i was intending to automate this for every 24 hours, now i use slitaz , sendmail is’nt available, so before trying out any other mail server, i just typed out in google bash smtp and i found this link http://blog.laaz.org/tech/2010/01/25/bash-smtp/ […]
LikeLike
Great code!
LikeLike
Really? Captcha in Estonian?!
Anyway, how hard would it be adding username/password authentication to smtp process?
I’m trying to send email from bash script via our SMTP server, but I can’t touch sendmail configuration file or anything, so your script would be ideal if it would only support authentication.
LikeLike
Sorry for the Estonian Captcha. I thought that it took the language from browser settings, but instead it took it from WP config.
The authentication itself wouldn’t be that hard to add (of course depends on the AUTH method), but the problem would be that probably the server uses some kind of TLS/SSL protection – and they would be stupid not to.
This Bash SMTP script is especially designed NOT to depend on anything besides Bash, so that it will work even if root filesystem itself has gone missing. Adding stuff for TLS layer won’t be trivial in Bash and would introduce dependencies otherwise.
You could of course set up a small Postfix (or any other SMTP server) that accepts mail only from localhost (your script) and relays it to the actual SMTP server together with AUTH and TLS. But this might not be what you are looking for.
LikeLike
Is there an easy way to send to multiple recipients?
LikeLike
As this function talks raw STMP, it does not handle multiple recipients out of the box. You have a few options:
1) if the server on the other end is a smart-host or otherwise trusts you, you can repeat the
RCPT TO
line for every recipient you have, before continuing withDATA
.2) if you are talking directly to end-servers which accept only mail for which they are the destination, you would have to repeat whole function call to every recipient’s server.
LikeLike