Mail sending with shell Scipt is not working - shell

I need to send a mail regarding deployment of an application using shell script.
For this I have just created a shell script and tested with
#!/bin/bash
TO_ADDRESS="to.person#domain.com"
FROM_ADDRESS="from.me#domain.com"
SUBJECT="Test mail"
BODY="hai friend, this mail is automated from shell script for Release automation."
echo ${BODY}| mail -s ${SUBJECT} ${TO_ADDRESS} -- -r ${FROM_ADDRESS}
But while running this script, it is printing like:
You have new mail in /var/spool/mail/jaykay
And a file named jaykay is created in /var/spool/mail/
Why this is happening?
How can I send a mail using shell script?
And the output file looks like
From jaykay Wed Aug 20 04:08:53 2014
Return-Path: <jaykay>
Received: (from jaykay#localhost)
by e7021.com (8.14.4/8.14.4/Submit) id s7K98rdu004168;
Wed, 20 Aug 2014 04:08:53 -0500
From: Jini K Johny <jaykay>
Message-Id: <201408200908.s7K98rdu004168#e7021.com>
Date: Wed, 20 Aug 2014 04:08:53 -0500
To: to.person#domain.com, -r, --, from.me#domain.com
Subject: Test mail
User-Agent: Heirloom mailx 12.4 7/29/08
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
hai friend, this mail is automated from shell script for Release automation.

Your fundamental problem is that you must use proper quoting. This is basically a duplicate of a question which gets asked here every day.
Without quotes, the second token in $SUBJECT is interpreted as the address to send to.
An email is submitted for delivery to mail (the second word in "Test mail").
The address is undeliverable, so you get a bounce message.
The bounce message is delivered to your inbox.
Your shell notifies you that your inbox has a new message.
Additionally, it seems that your version of mail does not understand the -- option, so it gets taken as just one more address to send to. (You would get a bounce message from that, I suppose.) Because the -r option is also interpreted as just another address to send to, you get one copy (like a Bcc:) of the outgoing message in the mailbox you tried to specify in the $FROM_ADDRESS.
The fix, of course, is easy:
#!/bin/bash
TO_ADDRESS="to.person#domain.com"
FROM_ADDRESS="from.me#domain.com"
SUBJECT="Test mail"
BODY="hai friend, this mail is automated from shell script for Release automation."
echo "${BODY}" | mail -s "${SUBJECT}" "${TO_ADDRESS}" # -- -r "${FROM_ADDRESS}"
(The curlies aren't really necessary here, but I kept them since you had them in your code.)
E.g. this recent answer has guidance for when and how exactly you need to quote.
The mail program is really a rather thin wrapper; you could do something like this instead;
/usr/lib/sendmail -oi -t -f "$FROM_ADDRESS" <<____HERE
From: My Name <$FROM_ADDRESS>
To: Your Name <$TO_ADDRESS>
Subject: $SUBJECT
$BODY
____HERE
... where the path to /usr/lib/sendmail is likely to be something else on many systems.
(For bonus k00lness points, add X-Mailer: Look, I can put anything I like here!)
I'm guessing here that you meant sendmail -f "$FROM_ADDRESS" which sets the envelope sender address (not -r which I cannot find documented anywhere).

Related

How to keep track of all the processes on your server and have it send emails whenever an unwanted process begins?

I have been trying to get more into scripting and programming and I am doing most of this on my Mac. I have been trying to monitor all the processes on my server and have a somewhat basic understanding of scripting with bash.
For the mailing part of the question, I know a variety of people have asked this question and there have been a variety of answers, but none of the answers seem to work for me. I have tried:
5 #!/bin/bash
6 sed <<"ENDMAIL" -e '/^From [^ ]/s/^From /From /' -e 's/^\.$/. /' | /usr/sbin/sendmail -t -f "$sender"
7 To: $receiver1, $receiver2, $receiver3
8 From: $sender
9 Subject: $subj
10 Any-Other-Standard-Optional-Headers: place headers in any order, including,
11 MIME-Version: 1.0
12 Content-Type: text/plain;
13 X-Mailer: any identity you want to give your E-mailing application
14 X-Your-Custom-Headers: X- headers can be your own private headers
15 x-Last-Header: a blank line MUST follow the last header
16
17 Your body text here
18
19 ENDMAIL-s "$subj"
I also tried using mail:
23 cat myfile.txt | mail -s " Hi My mail goes here " anemail#gmail.com
For the second part of the question, I understand the basics on how to view all the processes taking place, but I don't know how to compare all the processes at the current time to those at any other time. I have used the ps commands (like ps aux) to view all the processes, but how would I save those and then compare it at a later time.
Thanks for your time and I would appreciate any help.

Unknown characters within subject line of mail app in unix terminal

I've set up the mail app and created a shell script to FTP to a website server and then send an email to the admin. Last night it was working perfectly. I made changes to it this morning and it started sending two of the same email with different ASCII characters within the subject line.
#Send an email confirming update
cat /Users/rmdlp/Documents/Scripts/message.txt | mail -s “Website Update” myemail#myemail.ca
Here is a snippet of the email subject I receive:
Everything else works fine. The "message.txt" file is within the body of the message and it gets to my email OK.
Also in the sender's list this string is being added:
I also receive a "You have mail in /var/mail/$USER", which I did not receive before. I looked at that file and this is a portion of what it outputs:
Diagnostic-Code: X-Postfix; unknown user: "update???"
--9490A103F482.1450820767/Roys-MBP.lan
Content-Description: Undelivered Message
Content-Type: message/rfc822
Return-Path: <rmdlp#Roys-MBP.lan>
Received: by Roys-MBP.lan (Postfix, from userid 501)
id 9490A103F482; Tue, 22 Dec 2015 16:46:05 -0500 (EST)
To: rmdlp#live.ca, Update”#Roys-MBP.lan
Subject: “Website
Message-Id: <20151222214605.9490A103F482#Roys-MBP.lan>
Date: Tue, 22 Dec 2015 16:46:05 -0500 (EST)
From: rmdlp#Roys-MBP.lan (Roy Perez)
The command mail -s “Website Update” is not doing what you think it does. “ is U+201C, LEFT DOUBLE QUOTATION MARK, which is not the same thing as ". Unlike ", “ is not treated specially by the shell, and so the command gets split up at the whitespace in Website Update, resulting in a subject of “Website and an extra recipient of Update”. This extra recipient is interpreted as Update”#<YOUR HOSTNAME>, but because there is no such user, the email to it gets bounced back and ends up in your mailbox. All the "unknown characters" along the way are due to encoding issues.
This is why you use plain text editors to write code, not word processors.

mail sent by bash shell, but not received

Mail sent by bash with return code 0, but not received (I checked the
target mail box for a few hours).
The command shell is:
echo "BodyOfMail" | mutt -a 1.png -s "AttachSuccess" -- lichunyu#xiaomi.com
Nevertheless, when I change the target email to xxx#qq.com, the mail
can be received. i.e. :
echo "BodyOfMail" | mutt -a 1.png -s "AttachSuccess" -- coxfilur_2005#qq.com
The mail can be received.
I ever suspected that the png attachment may be the cause, so I removed it,
but still, I get the same result(xxx#xiaomi.com fail, xxx#qq.com OK).
In both of the cases, I tested the returned code by $?, and
both 0(which means success certainly).
Where is the problem, How can I solve it?
If there is something wrong the domain xiaomi.com, How do I know it?

Sending mail from a Bash shell script

I am writing a Bash shell script for Mac that sends an email notification by opening an automator application that sends email out with the default mail account in Mail.app. The automator application also attaches a text file that the script has written to. The problems with this solution are
It is visible in the GUI when sending
It steals focus if Mail is not the current application
It is dependent on Mail.app's account setup being valid in the future
I figure to get around those shortcomings I should send the mail directly from the script by entering SMTP settings, address to send to, etc. directly in the script. The catch is I would like to deploy this script on multiple computers (10.5 and 10.6) without enabling Postfix on the computer. Is it possible to do this in the script so it will run on a base Mac OS X install of 10.5. and 10.6?
Update: I've found the -bs option for Sendmail which seems to be what I need, but I'm at a loss of how to specify settings.
Also, to clarify, the reason I'd like to specify SMTP settings is that mails from localhost on port 25 sent out via Postfix would be blocked by most corporate firewalls, but if I specify the server and an alternate port I won't run into that problem.
Since Mac OS X includes Python, consider using a Python script instead of a Bash script. I haven't tested the sending portion, but it follows the standard example.
Python script
# Settings
SMTP_SERVER = 'mail.myisp.com'
SMTP_PORT = 25
SMTP_USERNAME = 'myusername'
SMTP_PASSWORD = '$uper$ecret'
SMTP_FROM = 'sender#example.com'
SMTP_TO = 'recipient#example.com'
TEXT_FILENAME = '/script/output/my_attachment.txt'
MESSAGE = """This is the message
to be sent to the client.
"""
# Now construct the message
import smtplib, email
from email import encoders
import os
msg = email.MIMEMultipart.MIMEMultipart()
body = email.MIMEText.MIMEText(MESSAGE)
attachment = email.MIMEBase.MIMEBase('text', 'plain')
attachment.set_payload(open(TEXT_FILENAME).read())
attachment.add_header('Content-Disposition', 'attachment', filename=os.path.basename(TEXT_FILENAME))
encoders.encode_base64(attachment)
msg.attach(body)
msg.attach(attachment)
msg.add_header('From', SMTP_FROM)
msg.add_header('To', SMTP_TO)
# Now send the message
mailer = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
# EDIT: mailer is already connected
# mailer.connect()
mailer.login(SMTP_USERNAME, SMTP_PASSWORD)
mailer.sendmail(SMTP_FROM, [SMTP_TO], msg.as_string())
mailer.close()
I hope this helps.
Actually, "mail" works just as well.
mail -s "subject line" name#address.ext < filename
works perfectly fine, as long as you have SMTP set up on your machine. I think that most Macs do, by default.
If you don't have SMTP, then the only thing you're going to be able to do is go through Mail.app. An ALTERNATIVE way to go through mail.app is via AppleScript. When you tell Mail.app to send mail via AppleScript you can tell it to not pop up any windows... (this does still require Mail.app to be configured).
Introduction to Scripting Mail has a good description of how to work with mail in AppleScript.
There is a program called Sendmail.
You probably don't want to use the -bs command unless you are sending it as raw SMTP like Martin's example. -bs is for running an SMTP server as a deamon. Sendmail will send directly to the receiving mail server (on port 25) unless you override it in the configuration file. You can specify the configuration file by the -C paramter.
In the configuration, you can specify a relay server (any mail server or sendmail running -bs on another machine)
Using a properly configured relay server is good idea because when IT manages mail servers they implement SPF and domain keys. That keeps your mail out of the junk bin.
If port 25 is blocked you are left with two options.
Use the corporate SMTP server.
Run sendmail -bd on a machine outside of
the corporate firewall that listens
on a port other than 25.
I believe you can add configuration parameters on the command line. What you want is the SMART_HOST option. So call Sendmail like sendmail -OSMART_HOST=nameofhost.com.
Probably the only way you could do this, while keeping the program self-sufficient, is if you have direct access to an SMTP server from the clients.
If you do have direct access to an SMTP server you can use the SMTP example from wikipedia and turn it into something like this:
#!/bin/bash
telnet smtp.example.org 25 <<_EOF
HELO relay.example.org
MAIL FROM:<joe#example.org>
RCPT TO:<jane#example.org>
DATA
From: Joe <joe#example.org>
To: Jane <jane#example.org>
Subject: Hello
Hello, world!
.
QUIT
_EOF
To handle errors I would redirect the output from telnet to a file and then grep that for a "success message" later. I am not sure what format the message should be, but I see something like "250 2.0.0 Ok: queued as D86A226C574" in the output from my SMTP server. This would make me grep for "^250.*queued as".
Send mail from Bash with one line:
echo "your mail body" | mail -s "your subject" yourmail#yourdomain.com -a "From: sender#senderdomain.com"
sendEmail is a script that you can use to send email from the command line using more complicated settings, including connecting to a remote smtp server:
http://caspian.dotconf.net/menu/Software/SendEmail/
On OSX it is easily installable via macports:
http://sendemail.darwinports.com/
Below is the help page for the command, take note of the -s, -xu, -xp flags:
Synopsis: sendEmail -f ADDRESS [options]
Required:
-f ADDRESS from (sender) email address
* At least one recipient required via -t, -cc, or -bcc
* Message body required via -m, STDIN, or -o message-file=FILE
Common:
-t ADDRESS [ADDR ...] to email address(es)
-u SUBJECT message subject
-m MESSAGE message body
-s SERVER[:PORT] smtp mail relay, default is localhost:25
Optional:
-a FILE [FILE ...] file attachment(s)
-cc ADDRESS [ADDR ...] cc email address(es)
-bcc ADDRESS [ADDR ...] bcc email address(es)
Paranormal:
-xu USERNAME authentication user (for SMTP authentication)
-xp PASSWORD authentication password (for SMTP authentication)
-l LOGFILE log to the specified file
-v verbosity, use multiple times for greater effect
-q be quiet (no stdout output)
-o NAME=VALUE see extended help topic "misc" for details
Help:
--help TOPIC The following extended help topics are available:
addressing explain addressing and related options
message explain message body input and related options
misc explain -xu, -xp, and others
networking explain -s, etc
output explain logging and other output options
I whipped this up for the challenge. If you remove the call to 'dig' to obtain the mail relay, it is a 100% native Bash script.
#!/bin/bash
MAIL_FROM="sfinktah#bash.spamtrak.org"
RCPT_TO="sfinktah#bash.spamtrak.org"
MESSAGE=message.txt
SMTP_PORT=25
SMTP_DOMAIN=${RCPT_TO##*#}
index=1
while read PRIORITY RELAY
do
RELAY[$index]=$RELAY
((index++))
done < <( dig +short MX $SMTP_DOMAIN )
RELAY_COUNT=${#RELAY[#]}
SMTP_COMMANDS=( "HELO $HOSTNAME" "MAIL FROM: <$MAIL_FROM>" "RCPT TO: <$RCPT_TO>" "DATA" "." "QUIT" )
SMTP_REPLY=([25]=OK [50]=FAIL [51]=FAIL [52]=FAIL [53]=FAIL [54]=FAIL [55]=FAIL [45]=WAIT [35]=DATA [22]=SENT)
for (( i = 1 ; i < RELAY_COUNT ; i++ ))
do
SMTP_HOST="${RELAY[$i]}"
echo "Trying relay [$i]: $SMTP_HOST..."
exec 5<>/dev/tcp/$SMTP_HOST/$SMTP_PORT
read HELO <&5
echo GOT: $HELO
for COMMAND_ORDER in 0 1 2 3 4 5 6 7
do
OUT=${SMTP_COMMANDS[COMMAND_ORDER]}
echo SENDING: $OUT
echo -e "$OUT\r" >&5
read -r REPLY <&5
echo REPLY: $REPLY
# CODE=($REPLY)
CODE=${REPLY:0:2}
ACTION=${SMTP_REPLY[CODE]}
case $ACTION in
WAIT ) echo Temporarily Fail
break
;;
FAIL ) echo Failed
break
;;
OK ) ;;
SENT ) exit 0
;;
DATA ) echo Sending Message: $MESSAGE
cat $MESSAGE >&5
echo -e "\r" >&5
;;
* ) echo Unknown SMTP code $CODE
exit 2
esac
done
done
Here is a simple Ruby script to do this. Ruby ships on the Mac OS X versions you mentioned.
Replace all the bits marked 'replace'. If it fails, it returns a non-zero exit code and a Ruby back trace.
require 'net/smtp'
SMTPHOST = 'replace.yoursmtpserver.example.com'
FROM = '"Your Email" <youremail#replace.example.com>'
def send(to, subject, message)
body = <<EOF
From: #{FROM}
To: #{to}
Subject: #{subject}
#{message}
EOF
Net::SMTP.start(SMTPHOST) do |smtp|
smtp.send_message body, FROM, to
end
end
send('someemail#replace.example.com', 'testing', 'This is a message!')
You can embed this in a Bash script like so:
ruby << EOF
... script here ...
EOF
For some other ways to send Ruby emails, see Stack Overflow question How do I send mail from a Ruby program?.
You can use other languages that ship with Mac OS X as well:
How do I send email with Perl?
Sending HTML email using Python
1) Why not configure postfix to handle outbound mail only and relay it via a mail gateway? Its biggest advantage is that it is already installed on OS X clients.
2) Install and configure one of the lightweight MTAs that handle only outbound mail, like nullmailer or ssmtp (available via MacPorts).
In both cases use mailx(1) (or mutt if you want to get fancy) to send the mails from a shell script.
There are several questions on Server Fault that go into the details.
sendmail and even postfix may be too big to install if all you want to do is to send a few emails from your scripts.
If you have a Gmail account for example, you can use Google's servers to send email using SMTP. If you don't want to use gGoogle's server, as long as you have access to some SMTP server, it should work.
A very lightweight program that makes it easy to do so is msmtp. They have examples of configuration files in their documentation.
The easiest way to do it would be to set up a system-wide default:
account default
host smtp.gmail.com
from john.doe#gmail.com
user john.doe#gmail.com
password XXX
port 587
msmtp should be very easy to install. In fact, there is a port for it, so it could be as easy as port install msmtp.
After installing and configuring msmtp, you can send email to john.doe#gmail.com using:
mail -s <subject> john.doe#gmail.com <<EOF
<mail text, as many lines as you want. Shell variables will be expanded>.
EOF
You can put the above in a script. See man mail for details.
Here's a modified shells script snip I've used on various UNIX systems...
(echo "${MESSAGE}" | ${uuencode} ${ATTACHMENT}$basename ${ATTACHMENT}) | ${mailx} -s "${SUBJECT}" "${TO_LIST}"
uuencode and mailx are set to the executables. The other variables are from user input parsed using getopts.
This does work but I have to admit more often than not I use a simple Java program to send console emails.
Try mtcmail. Its a fairly complete email sender, completely standalone.

OS X: sending mail to localhost

For testing purposes I want send mail to my localhost user account rather than my webserver. I am unsure how to do this using mail.app. Any help would be appreciated.
#Tautologistics
OSX does have a built-in MTA (SMTP server), to turn it on you can type:
sudo launchctl start org.postfix.master
then you can send mail to localhost like you desire
sample showing an SMTP server running from my machine running 10.6.1
>telnet 127.0.0.1 25
Trying 127.0.0.1...
telnet: connect to address 127.0.0.1: Connection refused
telnet: Unable to connect to remote host
>sudo launchctl start org.postfix.master
>telnet 127.0.0.1 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 machinename.example.com ESMTP Postfix
If you don't specifically want to use Mail.app, you can send mail using the mail command. Open Terminal and:
mail -s "Testing" `whoami`#`hostname`
<type something>
Ctrl-D to finish and send
Those are backticks, not single quotes. whoami returns the current user's username and hostname returns the local machine's hostname. It could also be explicit:
mail -s "Testing" john#mymac.local
EDIT: Just read your clarification. Mail.app stores it's data in ~/Mail, mostly in an SQLite database (the 'Envenlope Index' file). The tables of interest would be mailboxes and messages. The text of the email is stored in individual files in the respective mailbox/folder directories. This would probably be the way to go, if you want to access email that has been fetched by Mail.app (in realtime).
Yet another option would be to export your mail from the Mail.app using the mbox format and access it using the technique described by dbr. Depending on whether or not realtime access is desired, you might be able to script something up that automates the export.
I'm looking to login into my (local) mail server, access a mailbox, and do some parsing. So, I assume there's a mail server running locally but not sure how to access it
The local mail isn't stored in a POP3/IMAP server, but rather using a UNIX'y mbox. A file stored in /var/mail/ (the file-name is the users login)
For example..
$ mail dbr
Subject: hi
test
^d # ctrl+d (EOF)
$ cat /var/mail/dbr
From dbr#parabola.local Tue Dec 30 13:43:57 2008
Return-Path: <dbr#parabola.local>
X-Original-To: dbr
Delivered-To: dbr#parabola.local
Received: by parabola.local (Postfix, from userid 501)
id 4FEA1158E36; Tue, 30 Dec 2008 13:43:57 +1030 (CST)
To: dbr#parabola.local
Subject: hi
Message-Id: <20081230031357.4FEA1158E36#parabola.local>
Date: Tue, 30 Dec 2008 13:43:57 +1030 (CST)
From: dbr#parabola.local (dbr)
test
Not sure about Ruby (I had a search around, but couldn't find anything, although there is undoubtably a module for this), but I know Python has a maildir.mbox module, which would use in the following way:
>>> msgs = mailbox.mbox("/var/mail/dbr")
>>> for msg in msgs:
... print "Subject:", msg['subject']
...
Subject: hi
Unless you are running OSX Server, then there's no SMTP/IMAP/POP3 server running locally. You can get one up and running very easily using Post Fix Enabler or, if you don't mind the command line, use MacPorts to install postfix:
sudo port install postfix
Send mail from localhost LocalhostMail is a simple and fast solution for Mac OS X that lets you send email messages from your PHP-application (or any other, located on localhost) by Mail.app included with Mac OS X. If you use PHP, just add to MySQL database new messages, and our application will send them through a Mail application. LocalhostMail uses your mail account in Mail.app to send these messages, so you do not need a separate SMTP-server for your localhost.localhostmail.com
codelogic,
thanks, I did know about sending mail from the terminal. I think my question was not well thought out. I'm looking to login into my (local) mail server, access a mailbox, and do some parsing. So, I assume there's a mail server running locally but not sure how to access it.
I'm using ruby:
pop = Net::POP3.new 'macbook.local'
pop.start 'me', 'mypass'
but get a Timeout::Error: execution expired

Resources