我正在为Mac编写一个Bash shell脚本,通过打开一个自动发送应用程序发送电子邮件通知,该应用程序使用Mail.app中的默认邮件帐户发送电子邮件。 automator应用程序还附加脚本已写入的文本文件。这个解决方案的问题是
我想通过直接在脚本中输入SMTP设置,发送地址等来直接从脚本发送邮件来解决这些缺点。问题是我想在多台计算机(10.5和10.6)上部署此脚本而不在计算机上启用Postfix。是否可以在脚本中执行此操作,以便它将在10.5的基本Mac OS X安装上运行。和10.6?
更新:我找到了Sendmail的-bs
选项,这似乎是我需要的,但我不知道如何指定设置。
此外,澄清一下,我想指定SMTP设置的原因是,通过Postfix发送的端口25上的localhost邮件将被大多数企业防火墙阻止,但如果我指定服务器和备用端口我赢了遇到这个问题。
答案 0 :(得分:52)
由于Mac OS X包含Python,因此请考虑使用Python脚本而不是Bash脚本。我没有测试发送部分,但它遵循standard example。
# 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()
我希望这会有所帮助。
答案 1 :(得分:37)
实际上,“邮件”的效果也一样。
mail -s "subject line" name@address.ext < filename
只要您在计算机上设置了SMTP,就可以正常工作。我认为大多数Mac都是默认的。
如果您没有SMTP,那么您唯一能做的就是通过Mail.app。通过mail.app的替代方法是通过AppleScript。当你告诉Mail.app通过AppleScript发送邮件时,你可以告诉它不要弹出任何窗口...(这仍然需要配置Mail.app)。
Introduction to Scripting Mail 很好地描述了如何使用AppleScript处理邮件。
答案 2 :(得分:15)
有一个名为Sendmail的程序。
您可能不想使用-bs
命令,除非您将其作为原始SMTP发送,如Martin的示例。 -bs
用于将SMTP服务器作为deamon运行。 Sendmail将直接发送到接收邮件服务器(在端口25上),除非您在配置文件中覆盖它。您可以通过-C
参数指定配置文件。
在配置中,您可以指定中继服务器(在另一台计算机上运行-bs
的任何邮件服务器或sendmail)
使用正确配置的中继服务器是个好主意,因为当IT管理邮件服务器时,他们会实施SPF和domain keys。这可以让你的邮件远离垃圾箱。
如果端口25被阻止,则剩下两个选项。
sendmail -bd
听取的企业防火墙
在25以外的港口。我相信您可以在命令行中添加配置参数。你想要的是SMART_HOST选项。所以请像sendmail -OSMART_HOST=nameofhost.com
一样调用Sendmail。
答案 3 :(得分:10)
如果您可以从客户端直接访问SMTP服务器,那么在保持程序自给自足的同时,唯一可以做到这一点的方法就是。
如果您可以直接访问SMTP服务器,可以使用维基百科中的SMTP example并将其转换为以下内容:
#!/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
为了处理错误,我会将输出从telnet重定向到一个文件,然后再将grep用于“成功消息”。我不确定消息的格式应该是什么,但我在SMTP服务器的输出中看到类似“250 2.0.0 Ok:排队为D86A226C574”的内容。这会让我对“^ 250. *排队为”感兴趣。
答案 4 :(得分:6)
sendEmail是一个脚本,您可以使用该脚本使用更复杂的设置从命令行发送电子邮件,包括连接到远程smtp服务器: http://caspian.dotconf.net/menu/Software/SendEmail/
在OSX上,它可以通过macport轻松安装: http://sendemail.darwinports.com/
以下是该命令的帮助页面,请注意-s,-xu,-xp标志:
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
答案 5 :(得分:5)
用一行发送来自Bash的邮件:
echo "your mail body" | mail -s "your subject" yourmail@yourdomain.com -a "From: sender@senderdomain.com"
答案 6 :(得分:4)
这是一个简单的Ruby脚本来执行此操作。 Ruby提供了你提到的Mac OS X版本。
替换所有标记为'replace'的位。如果失败,则返回非零退出代码和Ruby返回跟踪。
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!')
您可以将其嵌入到Bash脚本中,如下所示:
ruby << EOF
... script here ...
EOF
有关发送Ruby电子邮件的其他一些方法,请参阅Stack Overflow问题 How do I send mail from a Ruby program? 。
您也可以使用Mac OS X附带的其他语言:
答案 7 :(得分:4)
我为挑战而鞭打了这个。如果您删除“dig”调用以获取邮件中继,则它是100%本机Bash脚本。
#!/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
答案 8 :(得分:3)
1)为什么不配置postfix
来处理出站邮件并通过邮件网关进行中继?它的最大优点是它已经安装在OS X客户端上。
2)安装并配置一个仅处理出站邮件的轻量级MTA,例如nullmailer
或ssmtp
(可通过MacPorts获取)。
在这两种情况下,使用mailx(1)
(或mutt
,如果你想获得幻想)从shell脚本发送邮件。
有关服务器故障的几个问题,请参阅详细信息。
答案 9 :(得分:3)
sendmail
甚至postfix
可能太大而无法安装,如果你想要做的就是从你的脚本发送一些电子邮件。
例如,如果您拥有Gmail帐户,则可以使用Google的服务器使用SMTP发送电子邮件。如果您不想使用gGoogle的服务器,只要您有权访问某些SMTP服务器,它就应该可以使用。
一个非常轻量级的程序,可以很容易地执行此操作msmtp。他们的examples of configuration files中有documentation。
最简单的方法是设置系统范围的默认值:
account default
host smtp.gmail.com
from john.doe@gmail.com
user john.doe@gmail.com
password XXX
port 587
msmtp
应该非常容易安装。事实上,它有a port,所以它可以像port install msmtp
一样简单。
安装和配置msmtp
后,您可以使用以下方式向john.doe@gmail.com
发送电子邮件:
mail -s <subject> john.doe@gmail.com <<EOF
<mail text, as many lines as you want. Shell variables will be expanded>.
EOF
您可以将上述内容放入脚本中。有关详细信息,请参阅man mail
。
答案 10 :(得分:0)
这是我在各种UNIX系统上使用的修改过的shell脚本片段......
(echo "${MESSAGE}" | ${uuencode} ${ATTACHMENT}
$ basename $ {ATTACHMENT} ) | ${mailx} -s "${SUBJECT}" "${TO_LIST}"
uuencode和mailx设置为可执行文件。其他变量来自使用getopts解析的用户输入。
这确实有效但我不得不承认我使用简单的Java程序来发送控制台电子邮件。
答案 11 :(得分:0)
尝试使用mtcmail。它是一个相当完整的电子邮件发件人,完全独立。