用Gnus收发邮件泡新闻组

用gnus收发邮件、泡新闻组(1)

如果你象我一样,接触 email 是从 Outlook Express 开始的,已经用惯了 Foxmail 这类邮件客户端,习惯了它们的工作方式,在 linux 下用的也是工作方 式类似的邮件程序,那么改用 Gnus 将对你是一种文化上的冲击,换句话说,你 得先洗洗脑。

Gnus 与传统的邮件阅读程序完全不同。Gnus 最初的定位是 newsreader,是用来 阅读 newsgroup 中的新闻的,Gnus 采用相同的方式来处理新闻和邮件。因此, 如果你还打算用 Gnus 收发邮件,就要准备接受 Gnus 的工作方式,

设置新闻服务器

启动gnus非常简单,在你的Emacs里执行`M-x gnus'命令就可以了,如果你想在另 一个frame里启动gnus,那就执行 `M-x gnus-other-frame' 。但是,现在先别启 动,因为我们先得进行一些配置。gnus启动的时候会去读你写在`~/.gnus.el'里 的内容,就像Emacs启动时要读`~/.emacs'一样。当然你也可以把对 gnus 的配置 写在`~/.emacs'里,但是最好还是使用gnus自己的配置文件。

首先,我们要设置新闻服务器,也就是nntp服务器,nntp是 Network News Transfer Protocal的缩写,国内提供nntp服务的主机不多,教育网内能访问的 nntp服务器,我只找到了一个: news.cn99.com,好了,现在就在`~/.gnus.el' 里加上这一句:

 (setq gnus-select-method '(nntp "news.cn99.com"))

设置邮件服务器

现在,我们进行接收邮件的设置。玩*nix的老鸟都知道,*nix的哲学是每个程序 "Only do one thing, and do it well." 因此就有了 sendmail, fetchmail, mailreader 等等一大票程序来干收发邮件这个活儿。严格地说Emacs(gnus)的分 工是做 mailreader,也就是说我们用emacs来写信,然后由另一个程序,比如 sendmail 来把信发出去;收信的过程也是类似的,由一个程序(比如fetchmail) 负责把信取回来,放在一个spool里面,然后我们用Emacs来读信。你先别跑,我 不是让你去配置sendmail这样的大怪物,我们平常发发信、收收信这点小活儿,用 不着劳sendmail老人家的大驾。

我们用的最多的邮件收发方式是这样的,有个POP3服务器,收信时我们到那里去 取;有个SMTP服务器,发信时我们把信送到那里去。这点小活儿,现在emacs自己 就可以搞定了。现在我们看看怎么设置:

首先我们设置POP3服务器:

(setq mail-sources
      '((pop :server "pop.163.com"   ;; 在这里设置pop3服务器
             :user "myname"            ;; 用户名
             :port "pop3"
             :password "mypasswd"))) ;; 密码

然后我们还要告诉gnus如何存放接收来的邮件,gnus把这个叫做backend,最 常用的方式是nnfolder,另外还有nnmbox, nnml等其它几种方式,我们选择其中 一种就可以了:

 (setq gnus-secondary-select-methods '((nnfolder "")))

然后我们设置SMTP服务器,采用smtp方式发送邮件需要一个小程序smtpmail.el, 这个程序现在已被纳入了官方的Emacs,如果你用的是最新的CVS Emacs,比如 Emacs22, Emacs23等,就已经包含了这个程序。你可以检查一下emacs的安装目 录中 lisp/mail/ 目录下有没有这个文件,如果没有的话,就只好自己下载、安 装了。现在我们看看如何设置:

(setq user-full-name "Brep") ;; 外发的邮件采用这个名字
(setq user-mail-address "myname@163.com") ;;外发的邮件采用这个地址
(setq smtpmail-auth-credentials
    '(("smtp.163.com"  ;; SMTP服务器
       25
       "myname"          ;; 用户名
       "mypasswd")))   ;; 密码
(setq smtpmail-default-smtp-server "smtp.163.com")
(setq smtpmail-smtp-server "smtp.163.com")
(setq message-send-mail-function 'smtpmail-send-it)

中文设置

中文!中文!永远都是头痛的事儿。把下面这些加在`.gnus.el'里面吧:

(set-language-environment 'Chinese-GB)
(setq gnus-default-charset 'chinese-iso-8bit
   gnus-group-name-charset-group-alist '((".*" . chinese-iso-8bit))
   gnus-summary-show-article-charset-alist
       '((1 . chinese-iso-8bit)
         (2 . gbk)
         (3 . big5)
         (4 . utf-8))
   gnus-newsgroup-ignored-charsets
       '(unknown-8bit x-unknown iso-8859-1))

有关中文设置的更详细的说明参见拙文 Gnus的编码设定

另外,有些用web方式发出的邮件里有html,加入下面的设置,只看其中的 plain text部分:

(eval-after-load "mm-decode"
  '(progn
     (add-to-list 'mm-discouraged-alternatives "text/html")
     (add-to-list 'mm-discouraged-alternatives "text/richtext")))

订阅新闻组

现在我们可以选择几个自己喜欢的新闻组,作为默认的新闻组:

(setq gnus-default-subscribed-newsgroups
  '("gnu.emacs.help"     ;; 这里不错噢,有关emacs使用的问题都在这里讨论
    "cn.comp.os.linux")) ;; 这里也有一个emacs小团伙,
                         ;; 有空去凑个热闹吧,中文的哟

启动gnus

现在到了关键时刻,成败在此一举:

 M-x gnus

嘿嘿,傻眼了吧,Emacs没反应了!!! 没关系,表担心,这是正常现象,gnus 是个单线程程序,nntp服务器又慢的要命(你要是在公网,说不定能好点儿), 多等一会儿就好了,一般也就两三分钟,运气不好的话还要长些,什么?你等不 及了,要编辑文件?那就只好麻烦您老再开一个Emacs吧!

Group buffer

如果一切正常,gnus启动完成的时候,我们就会看到group buffer,这里列出 了我们订阅的新闻组,类似这样:

      49: gnu.emacs.help
       6: cn.comp.os.linux
       8: nndoc+gnus-help:gnus-help
       0: nndraft:queue
       0: nndraft:drafts

新闻组前面的数字,表示这个组里还有多少帖子没读过。现在,只要把光标移动 到要读的新闻组上面,敲下回车键就可以读帖子了。

不要kill掉这个buffer哟,我们经常需要回到这个buffer。如果你读完了新闻、 信件,想退出gnus,只要在这个buffer里按下 `q' 键就可以了。

Summary buffer

当我们阅读某个新闻组的时候,就会进入summary buffer,其中列出了作者和帖 子的标题,如果是跟帖,会缩进表示,象下面这样:

 [  51: 空壳壳                 ] 已调试好的Emacs下载(WIN版本)
     [ 283: 空壳壳                 ] 这个包的.emacs配置文件
         [   5: Brep                   ]
       <   4: watercloud             > Re: 已调试好的Emacs下载(WIN版本)
          [   9: It's me FKtPp ;)       ]
              [   2: 空壳壳                 ]
                  [   7: It's me FKtPp ;)       ]

如果要读贴子,只要按下空格键就行了。按下 `q' 键将返回到 Group buffer.

发帖、回帖

在newsgroup里发帖子叫post article, 发贴子很简单,只要我们按下`a'这一个 键就可以了,写完后`C-c C-c'发出,如果写了一半儿想取消,则键入`C-c C-k'。

在newsgroup回帖子叫follow up,按下`f'键就行了,但是这样回帖并不引用原作 者的文章,如果你想引用原作者的文章,那就用`F'键。

如果你想和文章的作者私下聊聊,那就用 `r' 或者 'R' 键,给原作者回信叫做 reply to, 这时只有原作者一个人能收到信,与follow up不同,follow up的时 候,凡是订阅了新闻组的人都能读到信。

我的信箱哪里去了???

按照手册中的说法,我们通过 POP3 接收到的信件会被送到一个叫做 `mail.misc' 的组里,gnus 会自己建立这个组,但是我找了好几天也没找到,怎么回事呢,原来只 有当 gnus 收到第一封信时才会真正建立这个组,如果它一封信也没收到,它就懒 得去建立这个组,据说这种做法在计算机术语里叫 "lazy create",gnus 偷了一 回懒,却让我这个新手忙了大半天,真 !@#$%&*。

怎么办呢,没关系,我们自己手工建一个:

在 Group buffer 里,键入 `G m',系统提示我们输入组名:mail.misc,然后 提示我们输入server名,此时我们输入: nnfolder,注意,服务器名要与你选择 的backend一致。

建立完成之后,我们可以在Group buffer里键入`^',此时我们将进入Server buffer, 在这里我们将看到自己选择的服务器,比如:news.cn99.com。其 中,nnfolder服务器里应该有我们新建的`mail.misc'组。我们在服务器名上输入 回车,这样就能看到这个服务器中的组,在想要订阅的组上面按下'u'键即可订 阅这个组,取消订阅同样也是用这个键。

发信

用gnus发信极其简单,随时都可以,按 `m' 一键搞定,gnus会新建一个 buffer让我们写信

To: 在这里添上收件人的email
Subject: 在这里写上标题
From: Brep <myname@163.com>
--text follows this line-- 千万不要删除这一行

写完信后`C-c C-c'发出, 不想要了就`C-c C-k'。

大功告成了吗?

现在我们已经完成基本任务了,但是大功告成了吗? 没有!苦难才刚刚开始......

我看到一篇很好的帖子,怎么才能保存下来? 我想备份自己发出的所有信件,怎么办? 我想删除信箱里的信件,怎么办? 我的联系人很多,我想建个地址簿,怎么办? 我想把不同的人发来的信,分别放在不同的信箱里,怎么办?

用gnus收发邮件、泡新闻组(2)

给帖子加标记

你可能已经注意到了,当你读过一个帖子之后,Gnus会自动在帖子的最左边加上 一个`R',这就是标记。这些标记有些是我们自己加上的,有些是Gnus自动加上的。 标记不止`R'一个,还有很多符号被Gnus用来当作标记符号。这些标记表明了帖子 的状态,比如`R'表示这个帖子你已经读过了。

现在我们来看看常见的标记是什么意思。标记分为两大类,一类是“已读(read)” 标记,一般用字母表示,比如R, r, O, E等等;另一类是“未读(unread)”标 记,一般用特殊符号表示,比如 !, ?, *等等。标记的数量比较多,但我们只要 了解常见的几个标记是什么意思就行了。

Gnus之所以要把帖子分为“已读”和“未读”两类,是因为对这两类帖子, Gnus采取的处理方式不同。如果一个帖子别标记为“已读”,那么当你离开这个 group(用`q'命令)以后,下次再进入的时候,你就不会再见到它了(除非你要求 gnus把老帖翻出来给你看),只有那些被标记为“未读”的帖子和新帖才会显示 给你看。

已读标记

`R' 这个符号表示这篇帖子你的确已经读过了,每次你读完一篇帖子之后,Gnus 就会自动加上这个标记。

`r' 这个标记表示是你自己手动把帖子标记为已读的,但实际上你可能并没读过。 你可以用`d'命令加这个标记。

`O' 表示这是个老帖,上次进来的时候你已经读过了。那么怎么才能看到老贴呢, 用`/ o'命令,就可以把所有老贴翻出来看。

未读标记

`!' 保留(ticked)标记,带有这个标记的帖子将一直保持可见,如果你对某个贴 子感兴趣,想留着以后读,可以加上这个标记,用`!'命令就行了。但是请注 意,并不是说这种帖子就永久保留下来了,如果这个帖子被从管理员从nntp 服务器上删除了,那么你就再也看不到它了。nntp服务器按照相应的设置, 定期删除过期(expired)的老贴。

`?' 休眠(dormant)标记,这个标记比较有意思,所谓一个帖子进入“休眠状态”, 指的是除非有人跟帖,否则你以后不会见到这个帖子,也就是说,平常这个 帖子和已读没有差别,但是一旦有人跟帖,它就会跳出来,用`?'命令可以加 上这个标记。

`空格' 如果一个帖子前面什么符号也没有,就表示这是一个“未读”的帖子。

清楚所有标记

用 `M c' 或者 `Meta-u' 清除所有标记,也就是说标记为“未读(unread)”。

保存有价值的帖子

要想永久保存有价值的帖子,也就是说把帖子拷贝到自己的机器上保存起来,那 么可以打开gnus的cache功能,在`.gnus.el'中加入:

 (setq gnus-use-cache 'passive)

以后看到有价值的帖子,只要按下`*'键,这篇帖子就会被拷贝到本地的cache中 保存起来,这样即使服务器那边删除了这篇帖子,也没关系了。如果你又不想要 了,用`Meta-*'就可以把帖子从缓存中删掉。

如果你想查看自己保存在缓存里的帖子,只要在 summary buffer 中用 'Y c' 命令即可。

用gnus收发邮件、泡新闻组(3)

邮件分类

可能你每天都要收到大量的邮件,有的是亲朋好友寄来的,有的是你订阅的 maillist 寄来的。如果这些邮件都放在 mail.misc 这一个组里,那么很快这里 就会拥挤不堪了,说不定有些重要的信件会被漏看。

在Gnus里,我们可以对收到的邮件进行分类,比如把所有来自 tsinghua.edu.cn 的信都放在 mail.tsinghua 这个组里。我们可以这样做:

首先我们建一个 mail.tsinghua 组,在 Group buffer 里键入`G m', 然后输入 "mail.tsinghua", 接着系统会让我们选择Method,此时输入"nnfolder",这样 mail.tsinghua 这个组就建立好了。

然后我们设置 nnmail-split-methods 变量,在 .gnus.el 中加入:

(setq nnmail-split-methods
       '(("mail.tsinghua" "^From:.*tsinghua.edu.cn")
         ("mail.misc" "")))

这样以后凡是来自tsinghua.edu.cn的信件都会被放到mail.tsinghua这个组里去。 这个变量的值是一个由list组成的list,每个list由两个部分组成,前面的是组 名,比如"mail.tsinghua", 后面的是个正则表达式,Gnus会按这个正则表达式的 要求到邮件里去搜索,然后把找到的邮件放在指定的组里面。

这是一种简单的分类方式,如果你觉得不过瘾,可以试试 nnmail-split-fancy, 那是一种更灵活的分类方式。

需要注意的一点是,我们刚才用的术语都是“组(group)”,而没有说“邮件夹”。 实际上,在Gnus里面组就是邮件夹,邮件夹就是组,我们说过,Gnus采用同样的 方式处理信件和新闻,因此它并不对组和邮件夹进行区分。

既然是 group,那么你就可以取消订阅,假如你把女朋友的来信都放在 mail.lovers 组里面,随后不小心 unsubscribe 了这个组,那么你就读不到她们 的来信了,要是你的女朋友跟你分了手,千万别怪Gnus,就像Gnus的手册里说的:

Gnus gives you all the opportunity you could possibly want for shooting yourself in the foot.

保存自己发送的邮件

基本上所有的邮件客户端都有一个“已发送邮件”或是“sent”的邮件夹,你自己写 的信发送出去的同时,都会在这里都有一个备份,因为我们有时候需要看看自己 发出去的信件。

在Gnus里做到这一点很容易,而且它还可以自动把你发出去的邮件分分类,比如 把发出去的信放在一个组里,把你在newsgroup里post的帖子放在另一个组里。

现在我们看看怎么做到这一点,比如我们想把自己发的信备份到mail.sent.mail组 里,把自己post的帖子备份到在mail.sent.news组里,那么首先我们建立这两个 组:

在 group buffer 里键入`G m',然后输入组名"mail.sent.mail", 接着是输入 "nnfolder", 这个组就建好了,然后用同样的方式建立"mail.sent.news"组。

最后在.gnus.el里加入:

(setq gnus-message-archive-group
      '((if (message-news-p)
            "nnfolder:mail.sent.news"
          "nnfolder:mail.sent.mail")))

搞定了。

删除邮件

当你想删除一个邮件的时候,你先得搞清楚它是个news还是个mail, 因为你是 没有权力删除新闻组里的文章的,就象你上BBS的时候一样,就算你看到一篇不 爽的帖子,你也删不了它,除非你是版主。

在这里我还要多一句嘴,newsgroup管理的不像bbs那样严格,bbs的每个版都有若 干版主进行管理,删除无关的文章,封禁不按规矩发帖的人等等,象joke这种大 板,有8个版主严阵以待,随时准备删贴封人。newsgroup是没有版主管理的,一 般只有nntp服务器的管理员才有删帖的权力,但是一个nntp服务器上有成千上万 的group,管理员才没时间管删帖这种事儿呢,他们一般是制定一些规则,让系统 自动删除一些过期的帖子。因此,如果你在newsgroup上发了个垃圾帖子,它就有 可能在那里呆上好几年。

正因为如此,我们在newsgroup上发帖子一定要慎重,不要发垃圾邮件什么的。更 严重的是,如果你发了这种邮件,那么订阅这个组的人就会认为你很不礼貌,不 懂规矩,他们可能就会在自己的Gnus里增加一条规则,从此以后凡是你发表的帖 子,他们都不下载、不看。

好了,言归正传,我们谈谈怎么删除邮件。有两种方法可以删除邮件,一种是使 用邮件专用命令`B DEL', 也就是现键入'B',然后再按'Delete'键,这时系统会 询问你是否真的要删除什么的,回答`yes'就可以了。但是这种方法太暴力了,在 Gnus里有一种更好的方法删除邮件,那就是给邮件加上“保质期”,也就是说,让 Gnus替你干删除邮件这个活儿,它会忠实地按照你的要求,删除“过了保质期”的 邮件。

怎样给邮件加上“保质期”呢,很简单,在邮件组的summary buffer里,用`E'键就 可以给光标所在的邮件贴上expirable的标签,此时帖子前面会出现一个字母E作 为标记,然后你就不用管了,到了期限,gnus就会自动删除它们。

你也可以用`E'命令,给新闻组里的帖子加上expirable的标签,但是这毫无意 义,因为不论是你还是Gnus都无权删除新闻组里的帖子。

Gnus默认的保质期是7天,如果你觉得时间不合适,可以自己设置,更改变量 `nnmail-expiry-wait'的值就行了,在 .gnus.el 里加入:

(setq nnmail-expiry-wait 3)

这样就把保质期设成3天了。

你还可以给不同的组设置不同的保质期,象下面这样:

(setq nnmail-expiry-wait-function
  (lambda (group)
    (cond ((string= group "mail.tsinghua")
            31)
          ((string= group "mail.misc")
            3)
          ((string= group "mail.lovers")
            'never)
          (t
            6))))

这样就把mail.tsinghua这个组的保质期设为31天,mail.misc组设为3天等等。除 了数字,还有另外两个符号可以用,一个是`immediate',表示立即删除标为过期 的邮件;另一个是 `never',表示永不删除过期的邮件,“如果你一定要加个期 限,Gnus希望是一万年。”

地址簿

如果你的联系人比较多,没办法全部记住这些人的email地址,想建个地址簿,该 怎么办呢?

有两个种方法可以完成这个任务,一种是简单的,但是不太灵活;另一种麻烦点 儿,但是功能很强。

先说简单的,实际上这是一种很古老的方法了,那就是采用mail alias(地址别 名),你只要把联系人的邮件地址和别名都写在 ~/.mailrc 文件里就行了,语法 很简单,每个联系人占一行,像下面这样:

    alias brep     "Brep <brep@smth.org>"
    alias heyyy    "和伊有约 <heyyy@who.knows.where>"
    alias EOF      "EOF <EOF@god.knows>"
    alias ilovecpp "ilovecpp <ilovecpp@please.tellme.ifyouknow>"

发信的时候,在To: 后面输入别名,比如 heyyy,然后按空格键,Gnus会自动把 全名替你插进去。

然后我们再说复杂点儿的,其实也不复杂,只是麻烦点儿,要自己去下载一个软件 包,到这里:

http://bbdb.sourceforge.net/

去下载一个叫做bbdb的软件包,全名是 "Insidious Big Brother Database"。不 知怎么搞的,现在一提数据库我就开始反胃,不过这个 bbdb 只是个 Emacs 扩 展,全都是用 elisp 写成的,并不是那种巨无霸似的操作繁琐的数据库管理系统。 bbdb很小,压缩包只有300多k。bbdb只是建立了一个~/.bbdb文件,然后把你的联 系人每个一行地写在里面罢了,这是个纯文本文件,不过最好不要自己编辑这个 文件,可以用bbdb的命令往里添加联系人。

下载回来以后解开,然后make一下,象这样:

  $ tar xzf bbdb-2.35.tar.gz
  $ cd bbdb-2.35
  $ ./configure --with-emacs=emacs \
       --with-gnus-dir=/usr/share/emacs/23.0.0/lisp/gnus/
  $ make gnus

然后把 bbdb-2.35 目录下的lisp子目录整个扔到site-lisp下面就行了:

  $ cp -r lisp/ /usr/share/emacs/23.0.0/site-lisp/

还有文档,如果你要看的话也要自己装:

  $ cd texinfo/ && make
  $ cp bbdb.info /usr/share/info
  $ cd /usr/share/info
  $ install-info bbdb.info

如果你觉得太麻烦了,也可以解开压缩包后,直接把 lisp/ 子目录整个扔到 site-lisp 下面,bbdb的手册中说可以这样,不过我没试过。

好了,把下面这些写在 .gnus.el 里面:

(require 'bbdb)
(bbdb-initialize 'gnus 'message)

;; bbdb自己检查你填写的电话是否符合北美标准,
;; 如果你不是生活在北美,应该取消这种检查
(setq bbdb-north-american-phone-numbers-p nil)

;; 把你的 email 地址告诉bbdb
(setq bbdb-user-mail-names
      (regexp-opt '("myname@163.com"
                    "brep@smth.org")))
;; 补全 email 地址的时候循环往复
(setq bbdb-complete-name-allow-cycling t)
;; No popup-buffers
(setq bbdb-use-pop-up nil)

然后重新启动Gnus, 或者是在 Group buffer 中用`r'键,让Gnus重新读入 ~/.gnus.el

bbdb使用起来很简单,第一次用的时候,要用"M-x bbdb-create"命令创建联系 人,此时bbdb会问你一些相关的问题,比如联系人的Name, company, Network Address(这里要添email 地址)等等,你如实回答就是了。然后bbdb会创建一个 ~/.bbdb 文件,并把你的联系人加进去。

以后你可以随时用"M-x bbdb-create"命令添加联系人,也可以用 `M-x bbdb RET RET' 命令让bbdb把所有联系人显示给你看。

不过,bbdb最方便的地方在于你写信的时候,只要在 To: 面用 TAB 键,bbdb就 会把联系人替你填好,如果不对,就继续按 TAB 键,bbdb会填下一个,循环往 复。

还有一个方便的地方,如果你在Summary buffer中的某个邮件或帖子上按 `:' 建,bbdb将自动把发信人替你加到地址簿里,方便吧!

结束语

啰啰嗦嗦说了这么多,也只是把Gnus最基本的功能介绍了一下,实际上,Gnus还 有很多高级的功能可以发掘。那就去读Gnus的manual吧,我觉得Gnus的手册写的 真不错,语言诙谐幽默,读起来趣味盎然。

当你用了一段时间Gnus以后,你就很难再离开它了,那时候你就会理解下面这句话:

No Gnus is bad news.

返回主页

返回主页

Author: Brep <Brep@smth.org>

Date: 2006/11/02 02时20分32秒