50

Using Raspbian and Ubunntu 16.04 LTS so need a generic Linux solution.

Requirement is simple:

I need a way to send one-line email messages from the command line.

I have set up a gmail account just for this particular Rpi3, with the address of rpi3abc@gmail.com - with no 2FA

So now I need to be able to send one-line mail messages from anywhere (including cron) without user intervention.


I also would like it to be able to send text files; basically, anything from stdin.

SDsolar
  • 1,849
  • do you want that your message come from this particular address, rpi3abc@gmail.com or is it OK for you that message comes from your_username@localhost? – John Smith Sep 10 '17 at 07:08
  • It does come from rpi3abc@gmail.com so I know my computer is communicating to me. I use it in cron jobs, mostly. – SDsolar Sep 10 '17 at 19:26
  • NOTE: from May 30, 2022 Google no longer supports the use of third-party apps or devices which ask you to sign in to your Google Account using only your username and password. See https://support.google.com/accounts/answer/6010255 – pevik Jun 08 '22 at 07:14

8 Answers8

52

The simplest answer to sending one-line messages via gmail is to use ssmtp


Install it with the following commands:

sudo apt-get update
sudo apt-get install ssmtp

Edit /etc/ssmtp/ssmtp.conf to look like this:

root=rpi3abc@gmail.com
mailhub=smtp.gmail.com:465
FromLineOverride=YES
AuthUser=rpi3abc@gmail.com
AuthPass=testing123
UseTLS=YES

Send a one-liner like so:

echo "Testing...1...2...3" | ssmtp myusername@gmail.com

or

printf "Subject: Test\n\nTesting...1...2...3" | ssmtp myusername@gmail.com

Then, true to *nix, you just get the prompt back in a few seconds.

Check your myusername@gmail.com account, and voila, it is there!


This also works well when sending a file, as so:

cat program.py | ssmtp myotherusername@yahoo.com

And the program will show up in the mailbox

If the file is a text file, it can have a first line that says Subject: xxxxxx

This can be used with various cron jobs can send me data with subject lines indicating the content.


This will work with anything that prepares a message that is piped into ssmtp via stdin.


For more details such as securing these files against other users and such, visit this article:

Send Email from Raspberry Pi Command Line


Be sure to also look down below to the answer posted by Rui about locking down the FROM: address that might be changed in formatted message files, if necessary.


Now if only I could figure out how to send SMS the same way.

terdon
  • 242,166
SDsolar
  • 1,849
  • 1
    I also use ssmtp in my VMs, very lightweight. +1 – Rui F Ribeiro May 09 '17 at 02:37
  • 1
    Why not using the sendmail API from Python and sending it directly then? – Rui F Ribeiro May 10 '17 at 15:52
  • To take this a step further, here are very simple instructions for including an image file as an attachment: https://unix.stackexchange.com/questions/381131/simplest-way-to-send-mail-with-image-attachment-from-command-line-using-gmail – SDsolar Jul 22 '17 at 15:18
  • 1
    To answer Rui's question: sendmail alone does not have the MTA - Mail Transport Agent to communicate outside the machine. By default, since Unixen are multi-user by design, sendmail will send messages to other users in the same box but not outside. ssmtp is the MTA that I think is simplest to configure for gmail. – SDsolar Mar 20 '18 at 01:22
  • The sendmail API deliver both to the individual users or to the current MTA. The problem is that the From field can only be changed by root. Not to confuse the sendmail daemon with the historically sendmail compatible API. – Rui F Ribeiro Jul 18 '18 at 09:09
  • 2
    spent forever trying to setup postix this worked! one note to anyone reading this, the conf has a typo, the root parameter should be gmail.com not gmail. – qodeninja Aug 26 '18 at 14:55
  • 4
    For Gmail, you now need UseSTARTTLS=Yes and mailhub=smtp.gmail.com:587 and hostname=localhost. Took me hours to get it right :) – MS Berends Apr 20 '19 at 13:13
  • The suggestion to send a Python file as standard input is not a good idea. It could work in some scenarios, but you could also get everything before the first empty line as headers and the rest in the body. A much more robust approach is to supply a simple set of valid headers and an empty line before the payload. This is remarkably workable as long as your payload is plain ASCII with limited line lengths, but breaks in interesting ways if you have Unicode, characters in some legacy 8-bit character set, long lines, or binary contents. Then you need MIME, which is probably a good idea anyway. – tripleee Nov 28 '19 at 15:55
  • 1
  • 1
    E: Package 'ssmtp' has no installation candidate – alper Oct 10 '20 at 10:36
  • If you are using gmail's 2FA you need to create an "App Password" – Seybsen Feb 25 '21 at 08:08
11

ssmtp is just one of many Sendmail wrappers. All of these accept a message on standard input, and optionally a list of addresses as command-line arguments, and they all offer a binary named sendmail which implements (at least the basic features of) the traditional Sendmail command-line API. But properly speaking, that message needs to be well-formed RFC822 message. At minimum, it should have a Subject: header.

ssmtp address@example.com <<<$'Subject: testing 1...2...3'

(With ssmtp, sendmail is just a symlink to ssmtp. Postfix, Exim, and I believe every other MTA which Provides: mail-transport-agent has a similar arrangement, except of course sendmail where the sendmail binary is "the real thing".)

More commonly, you can piece together a simple email message with a here document.

/usr/lib/sendmail -oi -t <<____HERE
Subject: testing
To: recipient@example.net

Here we interpolate the shell variable $result
____HERE

(The Sendmail -t option says to take the recipient list from the headers of the message you receive on standard input. The precise path to Sendmail will differ between platforms.)

Another common variation is to combine the output of a few commands. Take care to have an empty line (a "neck") between the headers and the message body.

( printf "Subject: random number\n\n"
  dd if=/dev/urandom bs=4 count=1 2>/dev/null | od -D -An ) |
sendmail elsewhere@example.org

For anything beyond very simple ASCII text-only messages, you need to understand how to compose a proper MIME message, at which point it usually makes more sense to use a tool like mutt. Some platforms have a mail or mailx which knows how to send attachments and non-ASCII text, but this is not fully portable.

The challenge here is not finding a client which can take an email message and attempt to send it, it is to configure it for the specifics of Gmail, which requires the MTA to know the user name and password to use for the remote server in order to be able to use it as the outgoing smarthost.

Behind the scenes, most clients like mutt, mailx, etc typically just run sendmail behind the scenes to get the message off the system.

tripleee
  • 7,699
  • I wan't having much luck with using sendmail directly; hence turning to ssmtp. Upvote for your answer. By the way, in order to send images as attachments I found the simplest way posssible. I don't have to even think about MIME. I just use mpack, as described here: https://unix.stackexchange.com/questions/381131/simplest-way-to-send-mail-with-image-attachment-from-command-line-using-gmail – SDsolar Jul 22 '17 at 15:20
8

Adding to the OP own answer:

When configuring ssmtp, you may also forbid or allow users from defining the From, and also override the domain; you might want to do that for several reasons including the message not falling in the Spam folder.

You can add to /etc/ssmtp/ssmtp.conf:

# Where will the mail seem to come from?
rewriteDomain=my_internet_domain.uk

# Are users allowed to set their own From: address?
# YES - Allow the user to specify their own From: address
# NO - Use the system generated From: address
FromLineOverride=YES

Please note that while YES can be used in a home raspberry, it might not be advisable in a multi-user system from the security point of view.

Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232
4

I'm really partial to using mailx for this:

echo "Message body." | mailx -s "Subject line" -a /path/attachment.txt -r "Sender's Name<sender@email.com>" -c recipient2@email.com recipient1@email.com
  • 1
    Several of the options here will not be available on many non-Debian/non-BSD systems. The -a option in particular would be wonderful if it was universally supported, but just browse the mailx questions here to see that this is quite certainly not the case. – tripleee May 09 '17 at 14:34
4

What's wrong with "mail"?

echo "Hi there" | mail -s "Important mail" user@example.com

"mail" being /etc/alternative link to /usr/bin/bsd-mailx from bsd-mailx package. I believe it's there by default. Great utility for sending mail from cron scripts, for example.

Works on Ubuntu and FreeBSD as well.

Edheldil
  • 1,185
  • 6
  • 5
  • 4
    mailx is just a front end. It requires some MTA to be configured to actually get the message off the local system. There are multiple incompatible versions in common use, though if your target platform is Debian only, you can rely on reasonably recent BSD behavior. – tripleee May 09 '17 at 14:32
  • 1
    Gmail will block this. This message does not have authentication information or fails to pass 421-4.7.0 authentication – Michael Rogers May 22 '21 at 10:58
  • How can you fix this @MichaelRogers – user129393192 May 07 '23 at 19:27
2

I use sendEmail to send simple automated e-mails via an external provider's SMTP server:

sendEmail -q -f "me@mail.com" -u "mySubject" -t "someone@mail.org" -s "my.smtp.com" -o tls=yes -xu "mySmtpUser" -xp "mySmtpPw" -m "myMessage"

I pass everything on one line, so doing this on a command line would likely show all parameters (including smtp password) to all users, if they run a ps -ef while I am running the command. I use it within a shell script.

  • 1
    This is not a standard install, and there are multiple clients with this name. I guess you are referring to https://en.wikipedia.org/wiki/SendEmail. Is it available as a Debian package? – tripleee May 10 '17 at 03:37
  • Good thinking about the shell script, like on a multi-user system. I like that my password is in a file deep in the guts of the machine. I only wish I could store a hashed password instead of clear text. – SDsolar May 11 '17 at 08:05
  • I was refering to this package: https://packages.debian.org/search?keywords=sendemail – user684790 May 12 '17 at 07:58
  • 1
    I don't see this answer demonstrating that it works with gmail as specified in the original question. – SDsolar Mar 21 '18 at 15:52
  • This does work with gmail, ex: -s smtp.gmail.com -o tls=yes -xp your_gmail_password -s smtp.gmail.com:587 – rogerdpack Nov 13 '19 at 07:16
2

My server is CEntOS 7, and has sendmail but not mailx etc. Rather than install a new program I tested using sendmail directly, and found that this works:

echo -e "From: you@whatever\nTo: you@gmail.com\nSubject: this is the subject\n\nThis is the body,\nwith multiple lines." | sendmail -t

For me this seems to be the simplest way to send a short email, as it does not require running or configuring a server or daemon, and can be done in a single command line.

The idea is that a message will simply alert me that a certain program threw an error, without revealing any potentially confidential info, and then I'll SSH to the server to inspect its logs. This way there's no need to bother with complications like attaching files or encrypting the transport.

Notes:

  • -e tells echo to interpret '\n' and other escapes.
  • -t tells sendmail to get recipient addresses from 'To:' in the message header.
  • If the mail does not arrive, use tail /var/log/maillogto see error messages.
  • If sending to your gmail address, make a filter at gmail to keep them out of the junk folder.
  • This sendmail is actually 'sendmail.postfix' (which might be normal); there's a man page here
j77h
  • 21
  • 1
    Your system must have a MTA installed that is working with sendmail - but I don't see this answer demonstrating that it works with gmail as specified in the original question... – SDsolar Mar 21 '18 at 15:48
  • @SDsolar You're right. Postfix is running on my server, and I didn't know. Seems like it's standard with a Centos install; maybe DigitalOcean configured it. It's not listening on a public port. As for sending through gmail, my point is that you don't need to, you can send direct from your own server, if you're sending only to yourself. (I might ask my own question and move this answer over, if it doesn't fit here.) – j77h Mar 23 '18 at 00:57
0

Try https://batsign.me which a very simple service that avoids email server & client setup.