配置Mutt二三事
与无数国人一样,我也是从王垠的《Mutt email 程序使用入门》入门的。很荣幸,当初我直接找到了这篇博文的原始地址,而不是满天飞的CSDN转载。我想要使用Mutt的初衷,不仅仅是觉得tui应用很酷,而且也有想要在自动化shell脚本里加入发送邮件的功能。后来,我把Mutt安装到每一台我所使用的服务器上,Mutt配置也在各台计算机之间传来传去,就像其他费时费力的配置脚本一样,例如
.vimrc(笑)。再后来,我接触到NeoMutt。与Mutt一样,NeoMutt也是使用纯C语言实现的项目,并且使用与Mutt相同的图标:一只像素风格的小狗。“Teaching an Old Dog New Tricks.”,NoeMutt的Github主页信息栏里,似乎蕴含着Mutt的历史与未来。
一个完整的邮件客户端(Mail user agent, MUA)至少应该能够做两件事情: 1. 查看邮件 2. 发送邮件。接下来也将分成这两大部分介绍Mutt的使用方法。
查看邮件
协议
从服务器上获取邮件有两种协议,POP3和IMAP。 粗略来理解,可以认为基于IMAP协议会把本地的操作(已读、删除)同步到云端;而POP3则不会。作为颇有类Unix组件化哲学的Mutt,在查看邮件方面也有广泛对接的程序,例如fetchmail,一个可以定期将邮件下载回本地的后台程序。当然,Mutt也保证自己是开箱即用的,不使用其他软件下载邮件也可以,Mutt支持直接查看服务器上邮件。不过,直接查看邮件有一个问题,IMAP/POP3协议支持查询邮件目录而不下载,如果在Mutt里配置显示邮件行数的话,那一列就全都是0了,除非打开一封邮件看看。
显示
控制台的资源总是很紧张,每一个字符都会占用一个显示位,不多也不少。因此合理安排显示的内容、每列的宽度与间隔就显得很重要。顺便一提Mutt对CJK字符宽度的计算是正确的,不会像某些愚蠢的软件一样出现对不齐的问题(说的就是你,snap,以及到底是谁给服务器安装中文版的Ubuntu的……)。
邮件渲染
现代大多数的邮件除了会发一份HTML格式的文件之外,也会照顾到老旧的MUA(Mutt:正是在下)而附带一份纯文本的“fallback”。但是,不是所有的邮件都是如此,至少Mutt写出这样一份有好几种预备方案的健壮的邮件是很困难的(Mutt何苦为难Mutt)。所以,当接收到仅有一份HTML内容的邮件时,用默认配置的Mutt就只能阅读HTML源码了。
如何解决这个问题呢?
正巧,之前我了解过一个著名的cli浏览器w3m,它可以实现一些浏览器的基本功能。那么,Mutt是否可以使用w3m渲染HTML邮件呢?
省流总结如下:
- 创建一个
~/.mutt/mailcap文件, - 在上述文件里写入一行
text/html; w3m -I %{charset} -T text/html; copiousoutput; - 把原本的
~/.muttrc文件移动到~/.mutt/muttrc
注意 顺便一提,w3m无法安装在WSL1里。
发送邮件
编辑器
写邮件或者回信的时候,Mutt允许你自定义编辑器,通过指定EDITOR的值。 EDITOR其实是常见的变量,例如crontab也需要这个值作为默认编辑器(没有则默认vi)。在我的shell初始化脚本里,EDITOR值为vim。当然,你可以指定其为emacs、nano、甚至VSCode(code)。
命令行调用
在shell里调用mutt/neomutt非常简单,令它接收管道的输出作为自己的输入就好了。一行代码就是,echo "something" | mutt -s "Subject" you@addr.com。
有的时候,还可以添加一些类似于.muttrc文件里的选项的设置:
1 | echo "mail content" | mutt -e "set content_type = \"text/html\"" -s "Subject" you@addr.com |
注意-e参数一定要在最前面。
与cat、sed一样,Mutt是从管道里接收数据的软件,因此可以写类似以下形式的代码:
1 | mutt -s "Are ya ready kids?" spongebob@pineapple.house <<MAIL |
最后是一个小细节。 Mutt的指令是mutt,NeoMutt的指令是neomutt。其实就此与mutt诀别也没什么,但是我还是舍不得破坏~/.zsh_history里的指令统一性。(并没有这种东西)
一个简单的处理方法是在~/.bashrc或者~/.zshrc里添加一行alias mutt='neomutt'。
MSMTP
MSMTP是一个SMTP客户端,配合mutt使用,可以实现更丰富的发信功能,比如,本地的日志记录,设置SOCKS代理等。 Ubuntu上大多数软件的配置流程都是轻松的,因为基本是开箱即用的。但那都是服务级应用,MSMTP这种用户级应用还是要踩不少坑的。
就比如说,我喜欢把所有的用户级日志放在~/logs目录下。而MSMTP,就经常报错:msmtp: cannot log to /home/julia/logs/msmtp.log: cannot open: No such file or directory。创建日志文件并将文件权限设置成777并不能解决这个问题。更神秘的是,这个bug时有时无,从Ubuntu 18.04到Ubuntu 22.04,不论是物理机还是WSL兼容层,像一个u0,飘荡在Linux系统里。
这是为什么呢?
没想到,这样的小问题,居然困扰了我4年。从刚假设邮件服务器刚开始使用Mutt,一直到给邮箱服务器上SSL并使用NeoMutt作为客户端的刚刚。 或许,都怪我懒得修吧。
查阅资料可知,查看/etc/apparmor.d/usr.bin.msmtp可以看到msmtp被设定为对特定pattern的文件有写入权限:
1 | owner @{HOME}/.msmtp*.log wk, |
可以看到,我设置的日志文件/home/julia/logs/msmtp.log不满足任一pattern。但是我懒得改这个文件,所以我选择把日志文件设置为/home/julia/.msmtp-$(date +%Y-%m).log。问题顺利得到解决。
除了突然冒出来的apparmor。
apparmor是什么?
以前我从未听说。
Ubuntu居然默认安装着这种东西,以前完全没有注意到。
它甚至不是一个开机启动的守护进程,而仅仅是一系列传统Unix自主访问控制(discretionary access control, DAC)策略。
只有在追查这个bug的时候,我才发现了它,静悄悄地影响着几乎每一个后台运行的服务。
1 | {21:35}~ ➭ aa-status |
怪恐怖的。
Fin.