从Linux shell脚本发送邮件

138
我想从Linux Shell脚本发送电子邮件。标准命令是什么,我需要设置任何特殊的服务器名称吗?
答:使用mailx命令可以从Linux Shell脚本发送电子邮件。您需要设置邮件服务器的名称,并确保您具有该服务器的访问权限。

8
试着在Superuser [http://superuser.com/]上提问,或者更好的选择是Unix和Linux SE [http://unix.stackexchange.com/]。 - Dan Moulding
3
可能是Shell脚本发送电子邮件的重复问题 - Ciro Santilli OurBigBook.com
11个回答

129

如果服务器配置良好,例如已经安装并运行了MTA(邮件传输代理),你可以直接使用mail命令。

例如,要发送一个文件的内容,可以这样做:

$ cat /path/to/file | mail -s "your subject" your@email.com

man mail 了解更多详情。


11
这里的'mta'是什么意思?有全名或链接吗?作为初学者,这就是我想知道的。由于缺乏经验,我无法做到这一点。 - Zen
6
MTA代表邮件传输代理。postfix、sendmail、qmail等皆为MTA。 - Francesco Laurita
@Zen 大多数情况下,您可以将 MTA 视为 SMTP 或 IMAP 服务器。 - user151841
2
如果您不确定如何安装/配置,并且您使用的是Ubuntu:sudo apt-get install mailutils,然后选择“Internet site: Mail is sent and received directly using SMTP”。 - user1717828

94

如果你想在bash中采用简洁的方式,而且不想使用catecho等命令,最简单的方法如下:

mail -s "subject here" email@address.com <<< "message"

"<<<被用于重定向标准输入。它已经是bash的一部分很长一段时间了。"

6
echo -e "Some\nMultiline and tab\t msg"|mail -s "subject" your@email.com将上述命令翻译为中文:将文本"Some\nMultiline and tab\t msg"作为正文,发送到电子邮箱"your@email.com",邮件主题为"subject"。其中"\n"表示换行,"\t"表示制表符。 - Pipo
cat << END ... END | mail -s "subject" test@example.com - ulidtko
嘿,这对我非常有效,谢谢!我该如何指定多个地址进行交付? - E.Owen
1
@E.Owen 你可以使用 -t 选项将邮件发送到多个地址,地址之间用空格分隔。 - Jon

29
如果同时运行exim和ssmtp,可能会遇到问题。因此,如果您只想运行简单的MTA,并且只需要一个简单的smtp客户端来发送电子邮件通知,请首先清除可能预安装的MTA(如exim或postfix),然后重新安装ssmtp。
然后,只需配置两个文件(revaliases和ssmtp.conf)-请参见ssmtp文档-并在bash或bourne脚本中使用,如下所示:
#!/bin/sh  
SUBJECT=$1  
RECEIVER=$2  
TEXT=$3  

SERVER_NAME=$HOSTNAME  
SENDER=$(whoami)  
USER="noreply"

[[ -z $1 ]] && SUBJECT="Notification from $SENDER on server $SERVER_NAME"  
[[ -z $2 ]] && RECEIVER="another_configured_email_address"   
[[ -z $3 ]] && TEXT="no text content"  

MAIL_TXT="Subject: $SUBJECT\nFrom: $SENDER\nTo: $RECEIVER\n\n$TEXT"  
echo -e $MAIL_TXT | sendmail -t  
exit $?  

显然,不要忘记打开防火墙的输出SMTP端口(25)。

在这个脚本中我可以在哪里更改端口号?在我的服务器上,SMTP端口使用8181。 - manix
我不会在这个shell中这样做,否则你迟早会被卡住。你可以在配置文件中这样做:请参见http://unix.stackexchange.com/a/132731。 - hornetbzz
1
如果我只是简单地使用echo $MAIL_TXT,为什么换行符会被忽略? - KernelPanic
1
@Marko:请查看使用-e选项的man echo命令:启用反斜杠转义的解释。 - hornetbzz
抱歉,您错过了“-e”参数。 - KernelPanic

10

在bash脚本中的另一个选项:

mailbody="Testmail via bash script"
echo "From: info@myserver.test" > /tmp/mailtest
echo "To: john@mywebsite.test" >> /tmp/mailtest
echo "Subject: Mailtest subject" >> /tmp/mailtest
echo "" >> /tmp/mailtest
echo $mailbody >> /tmp/mailtest
cat /tmp/mailtest | /usr/sbin/sendmail -t
  • 每次使用此脚本时,文件/tmp/mailtest都会被覆盖。
  • sendmail的位置可能因系统而异。
  • 在cron脚本中使用时,必须为sendmail命令使用绝对路径。

2
因为多个进程可以同时调用脚本,所以被投票降低。这可能会导致临时文件损坏/不正确。此外,/tmp文件每次使用时不会被覆盖-它实际上会随着包含所有先前电子邮件的每个电子邮件而增长。不好。 - Taterhead
1
第一次写入 /tmp/mailtest 是覆盖,因此它将删除先前存在的任何内容。尽管如此,出于您所描述的其他原因,这种方法并不理想。 - Simon

9
通常情况下,您需要使用mail命令来使用本地MTA发送消息(该命令将使用SMTP将其传递到目的地,或者只是将其转发到某个更强大的SMTP服务器,例如您的ISP)。如果您没有本地MTA(尽管UNIX类系统省略它有点不寻常),则可以使用一些极简的MTA,如ssmtpssmtp非常容易配置。基本上,您只需要指定您提供商的SMTP服务器在哪里即可:
# The place where the mail goes. The actual machine name is required
# no MX records are consulted. Commonly mailhosts are named mail.domain.com
# The example will fit if you are in domain.com and you mailhub is so named.
mailhub=mail

另一个选择是使用数不清的脚本之一,直接连接到SMTP服务器并尝试在那里发布消息,例如Smtp-Auth-Email-Script, smtp-cli, SendEmail等。

"ssmtp" 已安装在机器上,所以我无法尝试它,但还是谢谢。 - yazzapps.com

9

从Linux向Gmail发送邮件

使用Postfix

1:安装软件

Debian和Ubuntu:

apt-get update && apt-get install postfix mailutils

OpenSUSE:

zypper update && zypper install postfix mailx cyrus-sasl

Fedora:

dnf update && dnf install postfix mailx

CentOS:

yum update && yum install postfix mailx cyrus-sasl cyrus-sasl-plain

Arch Linux:

pacman -Sy postfix mailutils

FreeBSD:

portsnap fetch extract update

cd /usr/ports/mail/postfix

make config

在配置中选择SASL支持

make install clean

pkg install mailx

2. 配置Gmail

/etc/postfix。创建或编辑密码文件:

vim /etc/postfix/sasl_passwd

我使用 Vim,你可以使用任何文件编辑器,如 nano、cat 等。
Ubuntu、Fedora、CentOS、Debian、OpenSUSE、Arch Linux:
添加以下内容:
其中,user 替换为你的邮箱名称,password 是你的 Gmail 密码。
[smtp.gmail.com]:587    user@gmail.com:password

保存并关闭文件,并使其仅由root用户访问:因为它包含敏感内容,例如您的密码。

chmod 600 /usr/local/etc/postfix/sasl_passwd

>FreeBSD:

目录 /usr/local/etc/postfix。

vim /usr/local/etc/postfix/sasl_passwd

添加以下代码:

[smtp.gmail.com]:587    user@gmail.com:password

保存并仅由root访问:

chmod 600 /usr/local/etc/postfix/sasl_passwd

3. Postfix配置

配置文件main.cf

我们必须在Postfix中设置6个参数

Ubuntu、Arch Linux、Debian:

编辑

 vim /etc/postfix/main.cf

修改以下数值:

relayhost = [smtp.gmail.com]:587
smtp_use_tls = yes
smtp_sasl_auth_enable = yes
smtp_sasl_security_options =
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt

smtp_sasl_security_options指配置文件中设置为空白,以确保不使用Gmail不兼容的安全选项

保存并关闭。

如同对于OpenSUSE:

vim /etc/postfix/main.cf

修改

relayhost = [smtp.gmail.com]:587
smtp_use_tls = yes
smtp_sasl_auth_enable = yes
smtp_sasl_security_options =
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_tls_CAfile = /etc/ssl/ca-bundle.pem

这还需要对文件 master.cf 进行配置。

修改:

vim /etc/postfix/master.cf

通过取消这行的注释(删除#),可以实现以下操作:
#tlsmgr unix - - n 1000? 1 tlsmg

保存并关闭 Fedora,CentOS:
vim /etc/postfix/main.cf

修改

relayhost = [smtp.gmail.com]:587
smtp_use_tls = yes
smtp_sasl_auth_enable = yes
smtp_sasl_security_options =
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_tls_CAfile = /etc/ssl/certs/ca-bundle.crt

自由BSD:

vim /usr/local/etc/postfix/main.cf

修改:

relayhost = [smtp.gmail.com]:587
smtp_use_tls = yes
smtp_sasl_auth_enable = yes
smtp_sasl_security_options =
smtp_sasl_password_maps = hash:/usr/local/etc/postfix/sasl_passwd
smtp_tls_CAfile = /etc/mail/certs/cacert.pem

保存并关闭此文件

4. 处理密码文件:

Ubuntu、Fedora、CentOS、OpenSUSE、Arch Linux、Debian:

postmap /etc/postfix/sasl_passwd

适用于 FreeBSD

postmap /usr/local/etc/postfix/sasl_passwd

4.1) 重新启动邮件服务器

Ubuntu、Fedora、CentOS、OpenSUSE、Arch Linux、Debian:

systemctl restart postfix.service

对于 FreeBSD:

service postfix onestart
nano /etc/rc.conf

添加

postfix_enable=YES

保存并运行以启动

service postfix start

5. 开启Gmail中的“较不安全应用程序”,请参考以下链接:

https://support.google.com/accounts/answer/6010255

6. 发送测试邮件

mail -s "subject" recever@domain.com

按下回车键

随意添加邮件正文,按下回车键,然后按ctrl+d以正确终止

如果不起作用,请检查所有步骤检查是否在您的Gmail中启用了“较不安全的应用程序

如果您修改了任何内容,则重新启动postfix

对于shell脚本,请创建.sh文件,并根据您的要求添加6个步骤命令

例如只是为了示例

#!/bin/bash
REALVALUE=$(df / | grep / | awk '{ print $5}' | sed 's/%//g')
THRESHOLD=80

if [ "$REALVALUE" -gt "$THRESHOLD" ] ; then
    mail -s 'Disk Space Alert' mailid@domainname.com << EOF
Your root partition remaining free space is critically low. Used: $REALVALUE%
EOF
fi

脚本会在磁盘使用率超过THRESHOLD变量指定的百分比(这里为80%)时发送电子邮件。

1
这个答案的名称不应该是“通过Gmail从Linux发送邮件到recever@domain.com”吗? - Cameron Hudson

6

如果您想使用某个 SMTP 服务器,可以执行以下操作:

export SUBJECT=some_subject
export smtp=somehost:someport
export EMAIL=someaccount@somedomain
echo "some message" | mailx -s "$SUBJECT" "$EMAIL"

somehostsomeportsomeaccount@somedomain更改为您实际使用的值。 此示例中不执行加密和身份验证。

1
如果未安装 mailx ,该怎么办? - nalply

2
你可以使用'email'或'emailx'命令。
(1) $ vim /etc/mail.rc # 或者 # vim /etc/nail.rc
将"Original Answer"翻译成"最初的回答"

set from = xxx@xxx.com #
set smtp = smtp.exmail.gmail.com #gmail's smtp server 
set smtp-auth-user = xxx@xxx.com #sender's email address
set smtp-auth-password = xxxxxxx #get from gmail, not your email account passwd
set smtp-auth=login #because if it is not sent from an authorized account, email will get to junk mail list.

(2)

$ echo "Pls remember to remove unused ons topics!" | mail -s "waste topics" -a a.txt developer@xxx.com #send to group user 'developer@xxxx.com' 

2
您甚至不需要一个MTA。SMTP协议足够简单,直接编写到您的SMTP服务器即可。如果您安装了OpenSSL包,甚至可以通过SSL/TLS进行通信。请查看此帖子:https://33hops.com/send-email-from-bash-shell.html 上面是一个示例,演示如何发送文本/HTML电子邮件,它将开箱即用。如果您想添加附件,则情况可能会变得更加复杂,您需要对二进制文件进行base64编码,并在边界之间嵌入它们。这是一个开始调查的好地方:http://forums.codeguru.com/showthread.php?418377-Send-Email-w-attachments-using-SMTP

2
mail 命令可以实现这一功能(谁能想到呢 ;-)。打开你的终端并输入 man mail 来获取 mail 命令的手册页,了解所有可用选项。

3
我做了那件事,但没有选项来指定要使用的服务器。 - yazzapps.com
1
这是您本地邮件传输代理配置的一部分,例如Sendmail或Postfix。 - DarkDust

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接