注意Mutt的reply-hook会被send-hook覆盖

一般经常上网的不会只有一个邮箱的,大多数人都会私人邮箱和工作邮箱一起用,我也是,不过我不愿意把他们混淆,我希望发到工作邮箱的邮件就用工作邮箱回复,其他的用私人邮箱回复。在mutt中,只要我们设置了邮件的From,procmail在发信的时候就会根据这个From来选择相应的identity,所以,只要根据邮件是发送到哪个邮箱,设置相应的From即可。

要想实现上面所说的筛选,需要用到mutt的hook,mutt有很多种类型的hook,通过他们可以实现根据当前邮件的情况和用户所要作的操作,自动进行一些设置。hook的不同主要在于他们的触发时间,比如切换目录的时候会触发folder-hook,回复邮件的时候会触发reply-hook(触发时间大约是用户按下回复命令“r“的时候),发送邮件的时候会触发send-hook等等。

首先来介绍一下我的环境,我的私人邮箱为P@gmail.com,工作邮箱为W@gmail.com,那么为了设置在大多数情况下都使用私人邮箱发信,首先在muttrc中设置:

reply-hook . “my_hdr From: Fwolf <P@gmail.com>” send-hook . “my_hdr From: Fwolf <P@gmail.com>”

这就定义了默认使用我的私人邮箱来回复和发送邮件,然后再在下面定义特殊情况下的处理。因为hook是按照定义的顺序来触发和执行的,所以如果没有特殊情况,就会使用刚才定义的设置,如果出现了特殊情况,就会执行特殊情况对应的设置,不过这并不意味这上面我们定义的默认情况下的设置就不会执行,而是默认情况下的设置的执行效果被“覆盖”了。

reply-hook “~t W@gmail” “unmy_hdr From:; my_hdr From: Fwolf <W@gmail.com>”

这样就定义了一个特殊情况——当回复邮件时,如果要回复的邮件是发送到我的工作邮箱W@gmail.com的,就把我要写的回复邮件的From设置为我的工作邮箱。在实际执行的时候就是这样一种顺序:

  1. 首先,用户按“r“回复邮件
  2. reply-hook . 被触发,From被设置为P@gmail.com
  3. reply-hook “~t W@gmail” 被触发,From被设置为W@gmail.com,覆盖了上面一条reply-hook的效果

看起来并没有问题,思路也对,设置也对,可是一执行就不对了,回复发送到工作邮箱的邮件,发信人仍然是P@gmail,难道是reply-hook的条件没有设置对么?不是,仔细分析之后,我发现刚才的执行过程中漏掉了一条:

  • send-hook . 被触发,From被设置为P@gmail.com

From被覆盖了两次,最终的结果还是P@gmail,所以看起来好像reply-hook没有正确触发似的。究其原因,mutt中是这样定义的:

  • 不管是reply-hook,还是send-hook,都是按照定义的顺序来触发的。
  • 但所有的reply-hook都将在send-hook之前被执行。

所以,我只顾着设置reply-hook的匹配和设置,却忘记了后面还有一条肯定会被执行的send-hook。要解决这个问题,可以使用unhook把已经定义了的hook关闭掉,刚才的设置调整为:

reply-hook “~t W@gmail” “unmy_hdr From:; my_hdr From: Fwolf <W@gmail.com>; unhook send-hook”

如果回复发送到工作邮箱W@gmail的邮件,不仅把From设置为W@gmail,而且还把所有的send-hook都关掉,这样就不会受前面定义的send-hook .的影响了,经测试执行正常,并且捎带脚把signature和pgp sign也给“unhook“掉了,正好。

如果在unhook之后确实还需要使用send-hook定义进一步的设置,可以直接在后面再加上send-hook ....的设置,记得命令之间用;间隔就可以了。

update @ 2007-03-24 其实上面介绍的方法并不科学(不过reply-hook和send-hook的顺序关系没有错),今天找到了更适合的方式,首先在正常的muttrc设置中要尽量不用my_hdr,而是用下面几行来代替:

alternates “P@gmail.com|W@gmail.com” #所有我可能会用到的邮箱 set from=”P@gmail.com” #默认的发信人 set use_from=yes #mutt自动生成from地址 set reply_to=yes #尽量使用原信中的reply-to,对邮件列表尤其适用 set reverse_name=yes #用哪个邮箱收的信,就用哪个邮箱回信

这样就基本实现了根据信件发送到的邮箱来自动选择回信了,如果要在发信时根据收信人来选择邮箱,可以用下面的设置:

send-hook . “unmy_hdr From:” send-hook “~t my_workmate@gmail.com” “my_hdr From: Fwolf ; set pgp_autosign=no”

这样在发信时的特殊情况下,就会选择非默认发信邮箱了,而在一般情况下,my_hdr是不存在的,mutt会选择set from设置的发信人邮箱,比较完美得解决了发信人邮箱选择问题。

在使用send-hook的时候,千万不要用发信人来作为判断条件,肯定不会匹配,reply-hook执行更在前面,更不会匹配了,所以下面的写法是错误的:

send-hook “~f W@gmail.com” “do something”

~f一样在send-hook中不工作的还有~h~B,直接报错。

最后还有一点遗留问题,私人邮箱使用数字签名,工作邮箱不用,但由于同样采用了先“默认设置”再设置“特殊情况”的方式,加上上面的send-hook和~f无法搭配,导致即使使用工作邮箱发信,默认也会进行数字签名,甚至会导致默认的发信人别名(<>之前的部分)不是我设置的名称,而是数字证书中的名称,郁闷,暂时我只好用宏macro来强制去除了:

macro compose <F9> "pc<ESC>f<HOME><DELETE><DELETE><DELETE><DELETE><DELETE><DELETE>\n"

参考:

2 thoughts on “注意Mutt的reply-hook会被send-hook覆盖”

Leave a Reply

Your email address will not be published. Required fields are marked *