How to Send Email from mailx Command in Linux Using Gmail’s SMTP

The heirloom mailx command in Linux is still providing service for guys like me, especially when we need to send email automatically by script. gmail is great. Now, how to use gmail’s smtp in mailx/mail? gmail is a little special since gmail’s smtp server requires tls authorization. The good news is that mailx supports it. Let’s look at how to use it.

First, find out Firefox’s profile directory in the home directory (I believe most of the users on Linux use Firefox. If you are not using Firefox, what you need to do is try it ;) . It has a format like this:

~/.mozilla/firefox/yyyyyyyy.default

yyyyyyyy is a random string that’s different for different users. You can easily find it out by looking into the directory ~/.mozilla/firefox.

There are two ways to do this: using all-in-one command or putting configurations into profile. The all-in-one-command way needs no other configurations except the command line itself, while the way using configuration has a clearer command.

All-in-one command

This is an all-in-one command that sends email to $TO_EMAIL_ADDRESS

mailx -v -s "$EMAIL_SUBJECT" \
-S smtp-use-starttls \
-S ssl-verify=ignore \
-S smtp-auth=login \
-S smtp=smtp://smtp.gmail.com:587 \
-S from="$FROM_EMAIL_ADDRESS($FRIENDLY_NAME)" \
-S smtp-auth-user=$FROM_EMAIL_ADDRESS \
-S smtp-auth-password=$EMAIL_ACCOUNT_PASSWORD \
-S ssl-verify=ignore \
-S nss-config-dir=~/.mozilla/firefox/yyyyyyyy.default/ \
$TO_EMAIL_ADDRESS

Replace the $... above with the value that is actually used. The meaning is obvious. And remember to change yyyyyyyy to the string that’s part of the Firefox profile directory.

messages.png

This command will ask for the email content. Type in the mail content and after finishing the email, use “Ctrl+d” to tell mailx you have finished. Then this mail will be sent out through gmail’s smtp server. You can also use pipe like this:

echo "The mail content" | mail -v -s ...

Use configuration file

There are too many options in the above command? Yes… I must confess so. We can write most of them into mailx/mail’s configuration file ~/.mailrc

set smtp-use-starttls
set nss-config-dir=~/.mozilla/firefox/yyyyyyyy.default/
set ssl-verify=ignore
set smtp=smtp://smtp.gmail.com:587
set smtp-auth=login
set smtp-auth-user=$FROM_EMAIL_ADDRESS
set smtp-auth-password=$EMAIL_ACCOUNT_PASSWORD
set from="$FROM_EMAIL_ADDRESS($FRIENDLY_NAME)"

Change the $... variables and yyyyyyyy to the right value for you. When sending mails, use this command:

$ mailx -v -s "$EMAIL_SUBJECT" $TO_EMAIL_ADDRESS

Then, time to enjoy it!

Eric Z Ma

Eric is a father and systems guy. Eric is interested in building high-performance and scalable distributed systems and related technologies. The views or opinions expressed here are solely Eric’s own and do not necessarily represent those of any third parties.

50 comments:

  1. Fedora 13 has a system directory for the network security services (NSS) files.
    nss-config-dir=/etc/pki/nssdb/

    Ubuntu 10.4 doesn’t seem to have a system directory for NSS files.

  2. Hi Adam,

    Yes. Some systems do not have the /etc/pki/nssdb/ directory. As far as I now, the nss files in Fedora do not work well with gmail.

    So we use Firefox’s version of these nss files which supports gmail quite well.

  3. This was very helpful but why the requirement of the ‘set nss-config-dir=~/.mozilla/firefox/xxxxxxxx.default/’ variable. What is it’s purpose, it seems to work perfectly without it.

    Jim!

  4. @Jim!
    In my Linux box (Fedora 12, mailx -V: 12.4 7/29/08). mailx doesn’t work without ‘set nss-config-dir=…’. I think it depends on the default mailx configuration file (/etc/mail.rc) which may different on different Linux distros. I look into the mail.rc file in my system, there is no ‘nss-config-dir’ configuration. So I need to set it in ~/.mailrc

    In my system, there is a directory /etc/pki/nssdb which can also be used as ‘nss-config-dir’. It works while we get a error message every time:
    Error in certificate: Peer’s certificate issuer is not recognized.

    Only firefox’s directory works perfectly from my experiment. As I have pointed out, it may also work without setting it.

  5. Hey there, I’m sending from a sidux (debian sid) laptop and edited the /etc/nail.rc file (mailx formerly called nail) then symlinked to /etc/mail.rc. File didn’t exist but that may be due to my ensuring sendmail/postfix/etc. were purged from my system.

    Once I my server back up and working (Fedora 12/Amahi)‘set nss-config-dir=~/.mozilla/firefox/xxxxxxxx.default/’ may be of use.

    BTW you’re original article is concise and to the point unlike others I came across so thank you.

    Jim!

  6. I could not find the firefox’s profile directory.. I would be really grateful if someone would help me out…

    1. It is usually under ~/.mozilla/firefox with a name xxxxxxxx.default .

      If you never run Firefox before, this directory may not exist. You can install it and run it once, then the directory should be there.

  7. I am having some problems. The following message comes on the terminal.
    Anyone knows what can be the problem. Does this “mail” command use system proxy settings on its own or i need to set it. Thanks in advance.

    Connecting to 173.194.79.108:587 . . .Connecting to 173.194.79.109:587 . . .could not connect: Connection timed out
    “/home/agam/dead.letter” 12/357
    . . . message not sent.

    1. Some command line tools accept proxy setting via environmental variables:

      export http_proxy=http://IP:PORT

      and

      proxy_username=USERNAME
      proxy_password=PASSWORD

      if username:password is needed.

      I am not sure mailx accepts these variables. But it may worth a try.

  8. Thanks, this is great stuff.
    Having done your setup with putting settings in ~/.mailrc on RHEL5.8, I’m trying this:
    #cat ~/mailbody.txt | sendmail -s “SUBJECT” -fmail@domain.com mail@domain.com
    I’m using sendmail as I can change the ctladdr/from-address to something else instead of USER@LOCALHOST which allows recipients to reply to the mail.
    I had this working for a short time, but now sendmail seems to parse the command arguments incorrectly. If I add -s “SUBJECT” sendmail will treat SUBJECT, -fmail@domain.com and mail@domain.com as recipients all… If I leave out -s “SUBJECT” it will parse the remaining arguments correctly, but with no subject mails are treated as spam.
    Any ideas?
    Thanks

    1. Hi TAG,

      From: http://www.sendmail.org/~ca/email/man/sendmail.html

      Sendmail is not intended as a user interface routine; other programs pro-
      vide user-friendly front ends; sendmail is used only to deliver pre-for-
      matted messages.

      I am not sure the `sendmail` command you are using will read the configuration from ‘~/.mailrc’.

      I suggest using `mailx` directly. The manual:

      http://www.pkill.info/linux/man/1-Mail/.

      For your command, the `mailx` version may be:

      mailx -s “SUBJECT” -r mail@domain.com mail@domain.com

      1. Thanks for your reply.

        Well, if I pass -r I get mailx: invalid option — r

        I already looked into man mailx to see if mailx would do this, and found that it didn’t. That’s why I tried sendmail. Using sendmail works – I can send mails this way – it’s just that when using -s it does as descirbed in previous post.

        rpm -qa | grep mailx
        mailx-8.1.1-44.2.2

        rpm -qa |grep sendmail
        sendmail-8.13.8.8.el5

        Maybe I need a different version of mailx? This is the one out-of-the-box on RHEL5.8.

        Thanks.

        1. Ah.. my fault. You are using an older version of `mailx`. On my box, the mailx is:

          mailx-12.5-6.fc17.x86_64

          If updating mailx is possible, after installing a newer version of it, you should be able to use ‘-r’.

          1. Well, you couldn’t what version I had running… Thanks, but 8.1.1-44.2.2 seems to be it for RHEL5… RHEL6 has mailx-12 ootb, but I’m stuck with RHEL5 on the box in question for now.
            Might have to let the script run on some other machine with mailx-12, then, and have it ssh into the other box for the non-mail-stuff it needs to do there… Just seems a little foolish to have to build and extra machine for that purpose alone…

          2. Thanks, but I don’t know anything about building. Just tested on a FC14 box. Works like a charm, except for a certificate issuer warning even though I specified nss location as the sending users firefox xxxxxx.default file… The prompt sort of hangs after that, so that might be an issue when scripting. I haven’t started on the actual script yet, as I wanted to get mailing to work first. Did not give warning on RHEL5.8…

  9. Nice tip; working great for me. Thank you! Wish I’d found this 2 years ago when I first tried it; the guide I used did not mention the nss-config-dir parameter, and leaving that out causes authentication errors (think it was MX validation stuff). I believe it worked without that at one time, but not for several years now.

  10. I got a PHP Mail Sender but I want it to use random proxy for sending emails.

    I have API for the proxy

    Change mail.php:

    (TESTEMAIL@HOTMAIL-YOU-CAN-ADD-YOUR-OWN-TEST-EMAIL-HERE.COM)

    To email you want to receive test emails.

  11. Notice that mailx has different alternatives. For me this works when using heirloom-mailx but mail.mailutils fails, it does not know the -v switch.

  12. I ‘m having difficulty sending mail.
    My mail.rc is below account gmail {
    set smtp-use-starttls
    set ssl-verify=ignore
    set smtp-auth=login
    set smtp=smtp://smtp.gmail.com:587
    set from=”email@gmail.com”
    set smtp-auth-user=uname
    set smtp-auth-password=***********
    set ssl-verify=ignore
    set nss-config-dir=/etc/pki/nssdb/
    }

    But I’m getting error
    [root@localhost ~]# echo -e “Mail body text” | mailx -A gmail -s “Mail subject” uname.example.com
    [root@localhost ~]# Error in certificate: Peer’s certificate issuer is not recognized.
    smtp-server: 534-5.7.14 Please log in via your web browser and
    smtp-server: 534-5.7.14 then try again.
    smtp-server: 534-5.7.14 Learn more at
    smtp-server: 534 5.7.14 https://support.google.com/mail/answer/78754 205sm11220769pfy.32 – gsmtp
    “/root/dead.letter” 11/337
    . . . message not sent.

    I think I’m having a certificate issue. I used the firefox certificates also. Still same issue.

    I’m using RHEL7 .

    Could you please help me

  13. I ‘m having difficulty sending mail.
    My mail.rc file is below

    account gmail {
    set smtp-use-starttls
    set ssl-verify=ignore
    set smtp-auth=login
    set smtp=smtp://smtp.gmail.com:587
    set from=”email@gmail.com”
    set smtp-auth-user=uname
    set smtp-auth-password=***********
    set ssl-verify=ignore
    set nss-config-dir=/etc/pki/nssdb/
    }

    But I’m getting error
    [root@localhost ~]# echo -e “Mail body text” | mailx -A gmail -s “Mail subject” uname.example.com
    [root@localhost ~]# Error in certificate: Peer’s certificate issuer is not recognized.
    smtp-server: 534-5.7.14 Please log in via your web browser and
    smtp-server: 534-5.7.14 then try again.
    smtp-server: 534-5.7.14 Learn more at
    smtp-server: 534 5.7.14 https://support.google.com/mail/answer/78754 205sm11220769pfy.32 – gsmtp
    “/root/dead.letter” 11/337
    . . . message not sent.

    I think I’m having a certificate issue. I used the firefox certificates also. Still same issue.

    I’m using RHEL7 .

    Could you please help me

    1. The link in the gmail smtp’s message provides some information:

      – Visit http://www.google.com/accounts/DisplayUnlockCaptcha and sign in with your Gmail username and password. If asked, enter the letters in the distorted picture.
      – Your app might not support the latest security standards. Try changing a few settings to allow less secure apps access to your account https://support.google.com/accounts/answer/6010255 .

      You may try these steps and try again.

  14. I’ve done all this (heirloom mailx on mac OS X) and everything works fine — except that on issuing the mailx command i’m still asked for my gmail password every time, even though password is specified with “set smtp-auth-password” in the .mailrc file as above. it would be really nice to make this automatic. any idea what i might need to fix?

    1. I haven’t a mac OS X by hand and can’t try. But some potential problems to check:

      – does your password contain some special characters like ‘@’, ‘$’? You may try use a password with only plain characters.
      – I am not sure whether the heirloom mailx version you are using disabled the smtp-auth-password or not. You may check the release doc of that build for mac OS X.

      You may also print the STDOUT content so that others can check whether there are some clues.

  15. Thanks! The problem persists even when I get rid of special characters. I couldn’t find any documentation of disabled smtp-auth-password. The heirloom version I’m using is the Mac OS X port for which there’s a link (now dead) on http://heirloom.sourceforge.net/. Here’s verbose output:

    Resolving host imap.gmail.com . . . done.
    Connecting to 173.194.66.109:993 . . . connected.
    * OK Gimap ready for requests from 173.68.122.183 [characters[
    >>> T1 CAPABILITY
    * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XO\
    AUTH2 AUTH=PLAIN AUTH=PLAIN-CLIENTTOKEN AUTH=OAUTHBEARER AUTH=XOAUTH
    T1 OK Thats all she wrote! [characters]
    Password:
    >>> T2 LOGIN “username” “password” [this one always reflects the entered password]
    * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 UIDPLUS COMPRESS=DEFL\
    ATE ENABLE MOVE CONDSTORE ESEARCH UTF8=ACCEPT LIST-EXTENDED LIST-STATUS LITERAL- SPECIAL-USE APPENDLIMI\
    T=35651584
    T2 OK username authenticated (Success)
    >>> T3 SELECT “INBOX”
    * FLAGS (\Answered \Flagged \Draft \Deleted \Seen $NotPhishing $Phishing)
    * OK [PERMANENTFLAGS (\Answered \Flagged \Draft \Deleted \Seen $NotPhishing $Phishing \*)] Flags permit\
    ted.
    * OK [UIDVALIDITY 649428526] UIDs valid.
    * 93 EXISTS
    * 0 RECENT
    * OK [UIDNEXT 78858] Predicted next UID.
    * OK [HIGHESTMODSEQ 9846256]
    T3 OK [READ-WRITE] INBOX selected. (Success)
    >>> T4 FETCH 1:93 (FLAGS UID)
    * 1 FETCH (UID 22587 FLAGS (\Seen))

    1. > Resolving host imap.gmail.com . . . done.
      > Connecting to 173.194.66.109:993 . . . connected.
      > * OK Gimap ready for requests from 173.68.122.183

      It seems you are using imap. The example in the post is about smtp.

      FYI, a SMTP connection’s output will be like this:

      Resolving host smtp.gmail.com . . . done.
      Connecting to 74.125.204.108:587 . . . connected.
      220 smtp.gmail.com ESMTP ...... - gsmtp

      Are you trying to receiving emails or sending emails? If your purpose is to use imap with `mailx`, you may check whether the `password-user@host` setting of `mailx` ( https://www.systutorials.com/docs/linux/man/1-mailx/ ) can work for you to set the imap account password (I didn’t test it).

      1. I’m both receiving using imap and sending using smtp, with code like the above for both imap and smtp in my .mailrc. I take your point that the password at issue is the imap password, not the smtp password (in fact I can send mail without being prompted for a password). Imap password is currently set with both “set imap-auth-password=” and with “set-password-user@host=” in .mailrc, but mailx still prompts for a password.

          1. Here’s the relevant part, with username and password changed to “username” and “passwd”. N.B. My main account is a google apps account. I’ve used a gmail account here for simplicity, since it displays the same behavior (though possibly some of the below is redundant for gmail).

            set folder=imaps://username@gmail.com@imap.gmail.com
            set MAIL=imaps://username@gmail.com@imap.gmail.com:993/INBOX
            set password-username@gmail.com@imap.gmail.com=passwd
            set-imap-use-starttls
            set imap-auth=login
            set imap-auth-user=username@gmail.com
            set imap-auth-password=passwd
            set imap-auth-password-username@gmail.com=passwd
            set imap-cache=~/imap
            
            set smtp-use-starttls
            set smtp=smtp://smtp.gmail.com:587
            set smtp-auth=login
            set smtp-auth-user="username@gmail.com"
            set smtp-auth-password="passwd"
            set smtp-auth-password-username@gmail.com="passwd"
            set from="username@gmail.com (Name)"
            set ssl-verify=ignore
  16. Hi Dave,

    Your mailrc config is almost correct. Here is a working one for your reference.

    set ssl-verify=ignore
    set nss-config-dir=~/.mozilla/firefox/YOUR_FIREFOX_DIR
    
    set folder=imaps://USERNAME@gmail.com@imap.gmail.com
    set MAIL=imaps://USERNAME@gmail.com@imap.gmail.com:993/INBOX
    set-imap-use-starttls
    set imap-auth=login
    set imap-auth-user=USERNAME@gmail.com
    set password-USERNAME@gmail.com@imap.gmail.com="PASSWORD"
    set imap-cache=~/imap
    
    set smtp-use-starttls
    set smtp=smtp://smtp.gmail.com:587
    set smtp-auth=login
    set smtp-auth-user="USERNAME@gmail.com"
    set smtp-auth-password="PASSWORD"
    set smtp-auth-password-USERNAME@gmail.com@gmail.com="PASSWORD"
    set from="USERNAME@gmail.com (Name)"
    

    The key is the variable:

    set password-USERNAME@gmail.com@imap.gmail.com="PASSWORD"
    1. Thanks! That looks essentially like what I have, including the key variable line. Are there any mistakes in my version that could have generated the password prompting? Changing to your version had the same result — unless I missed a change that I should be making.

      1. That’s quite strange and I have no idea what’s wrong any more. The version I gave is exactly the one I used for gmail with only the USERNAME, PASSWORD and YOUR_FIREFOX_DIR changed.

        You might try setting `nss-config-dir` as I noticed that you did not use it.

        1. OK, I’ve located the problem. Using your simple .mailrc without the rest of my (complicated) .mailrc worked without password prompt. I tested everything in the rest of my .mailrc and it turns out that deleting the following line removed the problem: set additionalfields=”. I don’t know why that is, but at least the practical problem is solved. Many thanks for your help, Eric!

          1. Actually, on closer look, the problem was generated by a second use of ‘set folder=’ later in .mailrc, used to specify a folder I can save messages to with the “+” method. Is there any way to set a folder for that purpose in addition to setting an imap folder on gmail?

Leave a Reply

Your email address will not be published. Required fields are marked *