How can I use shell scripting to send email using SMTP authentication

I have a need to be able to send a text email to various recipients from a linux box, but must use SMTP authentication to send it.  I have done this countless times in Win32 using VBScript and CDO, but just can't find the right guide to show me how to get this accomplished under linux using bash scripting.
is there a simple 1-2-3 method of putting something together that will accept a username/password for sending email from a script?  it needs to be non-interactive, as this will be run from various nightly tasks on the server.
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Do you have a local smtp service running (postfix/sendmail)?
You can configure postfix/sendmail to authenticate to the smarthost.

You could look into whether the sendmail/postfix on your system looks for specific environment variables. i.e. username=user password=pass which it then checks before.

Why do you require smtp-auth on localhost?

Digital_SkreamAuthor Commented:
The linux box is a remote system, and my mail server is an exchange system at a different facility.  No local smtp services are installed or running on the linux system.
Gabriel OrozcoSolution ArchitectCommented:
you can simply use mailx

mailx can use smtp-auth. just create a .mailrc in the home directory of the user, like

# cat .mailrc
account myisp {
set verbose
set smtp-use-starttls   (Uses SSL)
set is dependant on your email provider)
set smtp-auth=login  (Authentication via login/username/password)
set smtp-auth-user=YOUREMAILADDRESS (Also tried YOUREMAILADDRESS@...)
set smtp-auth-password=MY_PASSWORD
# For standard smtp-auth (NO TLS):
account myisp {
set verbose
set smtp-auth=login  (Authentication via login/username/password)
set smtp-auth-user=YOUREMAILADDRESS (Also tried YOUREMAILADDRESS@...)
set smtp-auth-password=MY_PASSWORD

Open in new window

Protecting & Securing Your Critical Data

Considering 93 percent of companies file for bankruptcy within 12 months of a disaster that blocked access to their data for 10 days or more, planning for the worst is just smart business. Learn how Acronis Backup integrates security at every stage

Digital_SkreamAuthor Commented:
I must be missing something.
I am getting :
  ** R=nonlocal: Mailing to remote domains not supported
I used the NO TLS code snippet, and here are my files:

cat testmail
# script to send simple email
# email subject
# Email To ?
# Email text/message
echo "This is an email message test"> $EMAILMESSAGE
echo "This is email text" >>$EMAILMESSAGE
# send an email using /bin/mailx
/usr/bin/mailx -s "$SUBJECT" "$EMAIL" < $EMAILMESSAGE
cat .mailrc
# For standard smtp-auth (NO TLS):
set verbose
set smtp-auth=login
set smtp-auth-user=me
set smtp-auth-password=mypassword

Open in new window

See if there is a /usr/bin/sendmail on the system.
you could use arp-get postfix to get it installed on your remote system.
You would then configure it to send through the provider or let postfix handle the delivery.
Another option, is to allow the IP of the remote system to relay through your exchange provided the remote IP is static.  This is not the best solution but a workable one.
Another option if the mailing is destined to your email address on the exchange server, there should not be any need to authenticate the mailing should be processed as though it is being sent by anyone outside.  
Digital_SkreamAuthor Commented:
There is a need to authenticate because eventually, this script will be utilized to send email to a large number of people on various email systems in different geographical areas.  i am testing right now with only a local email address just to get most of the bugs worked out.  isn't that how you test your code?

Does mailx ONLY work if there is a local email/smpt server in place?
usually, when a script needs to email, one should use a local smtp.
If however, you still want to use a shell script, perl would be a simpler mechanism.  There is a NET::SMTP module that can be used.

You might still use your bash script and then pipe the output to the perl script which will establish the smtp connection to your exchange, authenticate and pass the data along.

You would then use the exchange with a distribution list rather than having the mailing addressed to multiple people by the script.

I think, a better solution is to add postfix to the remote system.  It does not have to accept external connections to send outgoing email.
Digital_SkreamAuthor Commented:
Ok, I installed postfix, and that took care of the problems.
One last thing... the set from="" setting in .mailrc is not working.
Everything is being sent as the current linux user rather than the email address I want to have in the reply-to.... any ideas?
Gabriel OrozcoSolution ArchitectCommented:
mailx can use a remote smtp, so no need to add a local SMTP. also it is just a matter of say

smtp user@destiny.mail.server < mailfile.txt

since the smtp-auth is already added to the ~/.mailrc

if the mail server you plan to use is indeed not in the local area network, I would go with the local mail server instead.

In general, I would try not to add another layer of complexity since you would need to also manage the local mail server if you add it.
Digital_SkreamAuthor Commented:
This is why I am trying to get a script that I can use to send notification emails.
Teh scenario is this: I have a linux server sitting at a client's location in another state.  I want the linux box to be able to send a simple "backups are done" email once a night to both the client's email address and to my email address.  I want this email to be "from" a specific notifications email address in my domain.
i am going to be rolling out dozens (or more hopefully) of these systems to future and current clients all around the country, so i **REALLY** don't want to have to manage dozens of separate email servers.
when I try to point smtp towards the remote server, it gives me a 550 error.
Gabriel OrozcoSolution ArchitectCommented:
I've just finished a test from one of my linux servers

I disabled local email system just to check.

this was the .mailrc:
set verbose
set smtp-auth=login
set smtp-auth-password=holaesteesundemo

I created a test file with
From: Gabriel
To: Gabriel
Subject: prueba
this is a SMTP-AUTH test


the command line was:

 mailx < a.txt

the only drawback was it sent me verbose to the screen all the test. it worked like a charm.

I recall there is a set that works to avoid the output to screen in .mailrc.. you just need to google for ".mailrc"
I think it can be
set terse

try FIRST to connect from your test box by hand using
telnet 25

to see if it answers correctly and there is no firewall blocking you in the middle.

hope this helps

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Digital_SkreamAuthor Commented:
When you say "disabled local email ssytem" do you mean that you disabled postfix?
when you pipe data to postfix use the | /usr/bin/sendmail -t -oi
This will force the processing of the To:, Cc: and Bcc lines if any from the data being pumped in.

(I believe the the /usr/bin/sendmail is a symbolik link to a postfix binary which will handle the same switches as sendmail.
Gabriel OrozcoSolution ArchitectCommented:
Digital_Skream: I simply took down my MTA (QMail on that server) so if the delivery was successful it was impossible my local MTA was the one doing the task ;) this was just to prove mailx does what it says
Digital_SkreamAuthor Commented:
Here's what i've done.
Starting fresh, I uninstall postfix and mailx.
I install mailx (sudo apt-get install mailx)
Then I configured the .mailrc exactly as above, and then did the same command as yourself, and it replied back:
  <= root@linux.remote U=root P=local S=483
root@linux:~# delivering 1Kq9iu-0003JD-Qy
R: nonlocal for
  ** R=nonlocal: Mailing to remote domains not supported
  <= <> R=1Kq9iu-0003JD-Qy U=Debian-exim P=local S=1384
delivering 1Kq9iv-0003JF-8i
R: system_aliases for root@linux.remote
R: system_aliases for normaluser@linux.remote
R: userforward for normaluser@linux.remote
R: procmail for normaluser@linux.remote
R: maildrop for normaluser@linux.remote
R: lowuid_aliases for normaluser@linux.remote (UID 1000)
R: local_user for normaluser@linux.remote
T: appendfile for normaluser@linux.remote
  => normaluser <root@linux.remote> R=local_user T=mail_spool

What am I doing wrong?
try the following at the bash prompt:

echo "To: youremail@address<cr>
From: theemail@address_of_sender<cr>
Subject: Test<cr>
This is a test" | /usr/bin/sendmail -t -f theemailaddress@sender -oi<cr>

You can then incorporate this mechanism in your bash script.
Digital_SkreamAuthor Commented:
Results in:
-bash: /usr/bin/sendmail: No such file or directory
Digital_SkreamAuthor Commented:
Ok, finally got things to a place that I can reproduce successful results.
Had to do a 'apt-get purge postifx' to get rid of the old shreds of testing installations.
Then, I had to do a 'apt-get install -f postfix' to force it to reinstall any dependencies.
After that, install mailx, setup the .mainrc file and away we go!
To reiterate for future generations:

To easily configure your Ubuntu linux box to send emails from a script, follow these steps:
1.) apt-get install postfix
1a) configure it to be a internet site
2.) apt-get mailx
3.) create a .mailrc in your home directory with the following:
set verbose
set smtp-auth=plain
#Change auth=login if your mailhost requires it
set smtp-auth-user=username
set smtp-auth-password=password
4.) To test, create a text file anmed msg1 (echo test > msg1)
5.) run the following command:
mailx your < msg1
6.) you should receive the email.

Still no way to successfully get mailx toput a different email address in as the From or Reply To address, but I can live with that for now I guess.
Digital_SkreamAuthor Commented:
Gabriel OrozcoSolution ArchitectCommented:
Great, thanks!

Still I believe you should be able to send email *without* postfix installed, unless postfix is needed because mailx binaries are included on its package
Digital_SkreamAuthor Commented:
I agree, that it *should* be able to be done... for example, using a command line app to act as a pop/smtp mail client... but everything I saw - and I have been experimenting with a lot of stuff hte past two days, mutt, mail, mailx, postfix, esmtp, pine, etc. - is all interdependent on having an MTA installed on the linux box.  It seems that whenever a discussion starts to go where I need it to go, someone pops up with a "this isn't for spamming!" and the discussion gets shut down.
In windows, I just write a short vbscript that uses the built-in CDO of Windows, and poof, i can send an email using a remote smtp server.  in linux it seems that I have to have a local MTA installed.
Go figure.
Not sure whether you want to follow the method I outlined.  If you are willing to try, you need to find where your sendmail/postfix binary is.
Run the following at the prompt:
where sendmail or where postfix
apropo sendmail or apropo postfix.
Once you locate the path, try the mechanism outlined earlier.
Digital_SkreamAuthor Commented:
This is one of the problems in trying to get help with linux.
The simplest things (like locate sendmail to find the correct binary) are old hat and second-nature to the gurus, so it never occurs to them to tell newbies like me "do this". :)

Now I just have to figure out how to get it to use the smtp-auth.
It sends perfectly to my gmail account, but since it doesn't authenticate properly, it bounces off my exchance server.
The only time SMTP authentication is needed is to relay through a server.  When a message is destined to a recipient that your servers handles, there should not be a requirement for authentication.  If all mail servers were setup the same way you have configured your exchange server, no one will ever get any emails.
You should at least allow the remote server the ability to connect and transmit the message without the need to authenticate.  Do not add the remote server to the allow relay rule set.
Digital_SkreamAuthor Commented:
Just to clarify, because you seem to think that I made a mistake in configuring my exchange server ...
I do NOT require authentication to RECEIVE email to my domain.
I DO require authentication if a mail client (pegasus, eudora, outlook, thunderbird, etc.) wants to send an email to someone that is NOT in my domain FROM my mail server.  For example:
A user named Joe lives in California.  He has a POP/SMTP account on my domain/server.
He points his email client to for the POP and SMTP servers.
He also sets up authentication, so that the mail server allows him to send an email to someone else in another part of the world on another domain.  Otherwise, he would only be able to send email to local recipients (other people
I also do not allow incoming emails that are sourced at residential IP's, as these are usually zombie PCs sending out spam as mini-SMTP servers.

If all mail servers were setup the way my exchange server is, there'd be less spam.

The whole point of this question was to setup a method in a script that would allow me to have a commandline mail client sending mail from my mail server, but while simple to accomplish with other operating systems, it apparently isn't trivial with linux.  that's ok, though.  I learned a lot.  lost a bunch of money/time/sleep, but I can write that off as an investment. :)
Thanks for your help.
If your server is configured as you outlined, the mailing from the remote linux box should reach your server without the need for SMTP auth.
Check the postfix log to see what happened when a connection to your Exchange server was attempted.  The issue could very well be that the IP your remote system has is being blocked by the residential IP restriction mechanism you use.

Can you telnet your_exchange_server_ip 25?
Gabriel OrozcoSolution ArchitectCommented:
when Digital_skream set this

mailx ceased using the local MTA.

this should be apparent if you check the maillog, where nothing should be logged, while the email should be logged in the remote mail log file.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.