SMTP 即簡單郵件傳輸協(xié)議(Simple Mail Transfer Protocol),是一種基于 TCP 的應用層協(xié)議,用于將電子郵件發(fā)送到收件人的郵件服務器。不使用 SSL/TLS 加密的 SMTP 協(xié)議默認使用 25 端口,通過 SSL/TLS 加密的 SMTP 協(xié)議使用 465/587 端口。
命令行結合 SMTP 協(xié)議主要是為了通過一些簡單的腳本,完成在特定情景下通知郵件的自動發(fā)送。
MacOS 系統(tǒng)和很多 Linux 發(fā)行版默認已經配置好了 postfix 服務,可以直接發(fā)送郵件。不過此時使用的發(fā)件服務器在本地,發(fā)件人為用戶名@本地主機名,而該種類型的郵件會被現在絕大多數的郵箱服務封禁。導致郵件發(fā)送失敗。


而 postfix 本身的配置也較復雜,所以這里討論通過 QQ 郵箱或 gmail 等第三方 SMTP 服務器進行郵件發(fā)送的方式。
一、msmtp
msmtp 是一個非常簡單又易用的 SMTP 客戶端,且它與 sendmail有很好的兼容性。
MacOS 系統(tǒng)和大部分 Linux 都可以使用包管理器進行安裝。
軟件包安裝:
brew install msmtp(MacOS)
sudo apt-get install msmtp(Ubuntu)
Ubuntu 系統(tǒng)下還需要安裝 ca-certificates 軟件包(證書)
sudo apt-get install ca-certificates
軟件配置
msmtp 配置文件(Linux)如下(~/.msmtprc):
defaults
account gmail
host smtp.gmail.com
tls on
tls_starttls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
tls_certcheck on
port 587
auth login
from username@gmail.com
user username@gmail.com
password ****************
account default: gmail
其中
- host 項用于配置使用的發(fā)件服務器(smtp.gmail.com)
- tls_starttls on 用于指定啟用 STARTTLS 加密,此時 port (端口號)則為 587 。默認的 25 端口不使用加密,在 gmail 等服務器中是不允許訪問的
- tls_trust_file 用于指定證書文件。MacOS 系統(tǒng)下此路徑不存在,則可以注釋掉(#)該行配置,并將 tls_certcheck (是否驗證證書)設置為 off 。(可以正常發(fā)件,但不夠安全)
- from 和 user 為 gmail 郵箱地址,必須為同一個郵箱賬號,否則無法通過驗證
- password 并非登錄 gmail 時的密碼,而是 Google 賬號應用專用密碼,可在此地址進行創(chuàng)建。
編輯 /etc/mail.rc 配置文件,令 mail 命令使用 msmtp 作為發(fā)件程序(可通過 which msmtp 命令查看 msmtp 程序的具體路徑)
set sendmail=/usr/bin/msmtp
配置完成后,即可使用 mail 命令發(fā)送郵件了(郵件內容輸入完成后按 Crtl-D 發(fā)送)


二、sendemail
sendemail 是一個輕量級的命令行下的 SMTP 郵件客戶端,用 Perl 語言編寫,簡單但功能豐富。無需額外配置,只需要配合適當的命令選項和參數,即可使用 gmail 的 SMTP 服務發(fā)送電子郵件。
MacOS 和 Linux 系統(tǒng)下都可直接使用包管理器進行安裝:
(brew install sendemail 或 sudo apt-get install sendemail)
命令示例:
sendemail -l email.log -f "sender@gmail.com" -u "subject" -t "recipient@xx.com" -s "smtp.gmail.com:587" -o tls=yes -xu "sender@gmail.com" -xp "your_password"

可以通過它創(chuàng)建簡單的 shell 腳本,作為一個交互式的發(fā)件程序。
更多用法可參考
man sendemail
三、Python & smtplib
Python 語言的內置庫中即包含了對電子郵件的支持,比如 email 模塊可用于編輯郵件內容,smtplib 模塊可用于訪問 SMTP 服務。
通過 Python 腳本使用 gmail 的 SMTP 服務發(fā)送郵件的示例如下:
#!/usr/bin/env python3
import getpass
import smtplib
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
SMTP_SERVER = 'smtp.gmail.com'
SMTP_PORT = 587
def send_email(sender,recipient):
msg = MIMEMultipart()
msg['To'] = recipient
msg['From'] = sender
msg['Subject'] = input('Subject: ')
message = input('Enter your message. Press Enter when finished:\n')
part = MIMEText('text',"plain")
part.set_payload(message)
msg.attach(part)
session = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
# session.set_debuglevel(1)
session.ehlo()
session.starttls()
session.ehlo
# password = getpass.getpass(prompt="Enter your email password:")
password="your_password"
session.login(sender, password)
session.sendmail(sender, recipient, msg.as_string())
print("Your email is sent to {0}.".format(recipient))
session.quit()
if __name__ == '__main__':
sender="sender@gmail.com"
recipient = input("Enter recipient address: ")
send_email(sender, recipient)

取消 # session.set_debuglevel(1) 前面的注釋,可以在程序運行時輸出調試信息
參考資料:
Learning Python Network Programming by Dr. M. O. Faruque Sarker et al.
msmtp - ArchWiki