我从acme.sh项目中了解到它们使用python或者curl来发送邮件,并受到启发。在邮箱启用了smtp服务或者自己搭建邮箱服务的情况下我们可以非常容易地使用curl命令来发送邮件,我觉得通过这个方法来给自己发送服务器运行信息是个不错的应用场景。
使用curl发送邮件的相关参数
想要给目标邮箱发送邮件首先你需要具备发送邮箱的smtp服务器地址;发送时的邮箱用户名和密码;目标邮箱地址;邮件内容(邮件头和邮件体)。像是这样:
curl smtp://smtp.example.com \ 发送者的smtp服务器地址,可以指定端口 --ssl-reqd \ 要求SSL/TLS加密 --mail-from [email protected] \ 发送者的邮箱地址 --mail-rcpt [email protected] \ 接收者的邮箱地址(可以有多个) --user [email protected]:password \ 发送者的邮箱用户名和密码 --upload-file email.txt 发送的邮件内容
smtp服务器
smtp://smtp.example.com --ssl-reqd
意味着要求与smtp服务器全程SSL/TLS加密,也可以写成smtps://smtp.example.com
,curl会与服务器465端口建立加密连接
smtp://smtp.example.com --ssl
则表示curl会尝试与smtp服务器建立SSL/TLS加密,先与服务器25端口建立连接,再通过STARTTLS加密通讯。
smtp://smtp.example.com --starttls
或 smtp://smtp.example.com:587
要求使用 STARTTLS 升级连接。
而smtp://smtp.example.com
,curl则会与smtp服务器25端口建立连接,全程都不会加密(不推荐)。
邮件内容
最基本的邮件内容应当包含以下内容:
From: [email protected] //发送者的电子邮件地址。 To: [email protected] //收件人的电子邮件地址,多个收件人用逗号分隔。 Subject: Test Email //邮件主题。 Date: Thu, 27 Jun 2024 12:34:56 +0000 //发送日期(可选),curl会自动填写。 This is a test email sent using curl. //邮件体
通过–upload-file或者 -T 添加邮件内容文件发送
--upload-file email.txt -T email.txt
或者通过输入流添加邮件内容文件发送
-T <(echo -e "From: $sender_name <$smtp_user>\nTo: $recipient\nSubject: $subject\n\n$content") 或 -T - <<EOF From: [email protected] To: [email protected] Subject: Test Email Date: Thu, 27 Jun 2024 12:34:56 +0000 This is a test email sent using curl. EOF
接收者的邮箱地址
可以通过多个--mail-rcpt
参数来指定多个收件人,但是发送的邮件内容是相同的。如果你希望邮件中所有的收件人都是单独的而不是cc或者bcc,你应该使用其它方法来发件而不是直接指定多个--mail-rcpt
参数;
参考调用脚本
#!/bin/bash smtp_url="smtps://" smtp_user="用户邮箱地址" smtp_password="密码" # 参数1:发件人名 # 参数2:主题 # 参数3:内容 # 参数4:收件人列表,空格分隔的邮件地址字符串 mail_to() { local sender_name="$1" local subject="$2" local content="$3" local recipients="$4" # 遍历所有收件人并发送邮件 for recipient in $recipients do echo "发送邮件给: $recipient" curl -s --url "$smtp_url" \ --mail-from "$smtp_user" \ --mail-rcpt "$recipient" \ --ssl-reqd \ --user "$smtp_user:$smtp_password" \ -T <(echo -e "From: $sender_name <$smtp_user>\nTo: $recipient\nSubject: $subject\nContent-Type: text/html;\n\n$content") done }