bash SMTP

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:

# just send the mail with hard-coded parameters

# define important parameters
bash_mail "me@example2.com2" "Still Panic"

13 thoughts on “bash SMTP

  1. 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 😉


  2. 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).


    • 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.


  3. 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.


    • 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.


    • 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 with DATA.

      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.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s