使用 MagicFilter 进行强大打印
在 Linux 上打印可能是一项令人畏惧的体验——但其实不必如此。如果您真的想成为打印专家,请查看 Linux 打印 HOWTO、Linux 打印使用 HOWTO 以及 lp 系列手册页。但是,如果您只是想让您的 Linux 机器打印文本、PostScript、图形以及您今天投给它的其他格式,请继续阅读。
当某事听起来好得难以置信时,它通常就是如此。但这条规则的一个例外是 H. Peter Anvin 编写的 MagicFilter-1.2。它是一个可扩展、可定制的打印过滤器,使几乎任何类型的打印机都可以自动打印几乎任何类型的文件。
MagicFilter 有两个任务。首先,它检测正在打印的文件类型。它通过搜索文件中特定偏移量处的关键字符串来完成此操作。它不依赖文件名或扩展名作为文件类型的指示。例如,如果文件的前两个字符是 %!,则它将被处理为 PostScript 文件。其他文件类型,例如 gifs、bmps 等,也通过类似的规则进行检测。MagicFilter 的第二个任务是调用适当的转换实用程序,以便在您的特定打印机上打印文件。如果您碰巧尝试打印一些不可打印的内容(如二进制文件),则作业将中止,并且您将收到(通过电子邮件)通知,告知您的文件无法打印。
显而易见的好处是,安装 MagicFilter 后,您可以输入命令
lpr first.txt second.ps third.gif fourth.jpeg\ README.gz
在提示符下,所有五个文件都将排队并以良好的样式打印出来。另一个可能更大的好处是,大多数 Linux 软件包都预配置了 lp 或 lpr 作为默认打印机。安装 MagicFilter 后,您所有喜欢的程序(如 Pine、Netscape、Applixware 等)都应该可以开箱即用。稍后我将更详细地介绍应用程序打印。
在构建 MagicFilter 之前,您需要一些支持软件包。至少,您需要 gcc 编译器。MagicFilter 的 Makefile 由一个名为 configure 的脚本生成,该脚本扫描您路径中的目录,并缓存它找到的任何转换实用程序的位置。如果 configure 未找到某些实用程序,MagicFilter 仍将构建,但无法打印某些文件类型。表 1 显示了不同级别文件打印能力所需的支持软件包。
表 1 中提到的阶梯效应发生在打印机省略行尾序列中的回车符时。如果您想查看阶梯效应的实际效果,请通过运行以下示例(替换您的 lp 设备名称)将一个简短的文本文件直接发送到您的打印机设备
cp /etc/group /dev/lp1
确定您在 MagicFilter 中需要的稳健性级别,安装那些支持软件包,然后构建 magicfilter。我在本文末尾列出了一些这些软件包的来源。
好的,让我们假设您已识别出所有支持软件包并将其安装在您路径中的某个位置。您已获得文件 magicfilter-1.2.tar.gz,并以 root 用户身份将其移动到合适的位置。(我总是使用 /usr/local。)使用以下命令解压缩文件
tar -xzf magicfilter-1.2.tar.gz
此命令将 MagicFilter 解压缩到新创建的目录 /usr/local/magicfilter-1.2 中。将目录更改为 magicfilter-1.2,然后运行 configure 脚本。请注意屏幕上显示的输出;您可能会看到 configure 未找到的一些软件包。Peter Anvin 向我保证,如果您安装了表 1 中显示的所有软件包并在您的路径中,您将构建一个功能齐全的 magicfilter 程序。搜索到的一些软件包已被支持软件包中的较新软件包(至少在功能上)替换。无论如何,现在运行 make;接下来,运行 make<\!s>install。之后,目录 /usr/local/magicfilter-1.2/filters 将包含大约 40 个脚本,几乎适用于您可能遇到的任何打印机。实际的 magicfilter 二进制文件可能位于 /usr/local/bin 中。此时,您要做的是将您的打印机的脚本复制或移动到 /usr/local/bin。例如,如果您有一台 Canon BJ-200ex 打印机,则您的脚本是 bj200-filter。有些打印机可能没有脚本本身,但应该有一个适用于几乎所有打印机的脚本。
或者,您可以运行 make<\!s>install_filters,所有脚本都将被复制到 /usr/local/bin。值得注意的是,此时 /usr/local/bin(或您安装 MagicFilter 的任何位置)不需要在您的路径中。当我们接下来引用这些文件时,我们将使用绝对路径名。
由于我正在撰写关于 Linux 的文章,它使用 BSD 打印系统,因此我将仅介绍 /etc/printcap 文件中的 Linux 特定安装。请注意,并非所有 Unix 版本都实现了此打印系统。编辑 /etc/printcap 文件,并将对您的打印机脚本的调用编织为输入过滤器。以下是一个示例,适用于具有两台打印机的系统,分别是 /dev/lp1 和 /dev/lp2 上的 HP LaserJet 4 和 HP DeskJet 550C
pencil|lp|PostScript|ljet4|HP LaserJet 4:\ :lp=/dev/lp1:sd=/var/spool/lpd/pencil:sh:mx#0:\ :if=/usr/local/bin/ljet4-filter: crayon|dj550c|color|HP DeskJet 550C:\ :lp=/dev/lp2:sd=/var/spool/lpd/crayon:sh:mx#0:\ :if=/usr/local/bin/dj550c-filter:
/etc/printcap 文件的语法本身就是一个主题。有关完整描述,请参阅 Linux Printing-HOWTO。Peter 指出,“请注意默认(文本)打印机的别名 `lp`,以及首选 PostScript 打印机的别名 `PostScript`。”
接下来,终止并重新启动您的 lpd(打印守护进程)。我的打印守护进程已成功终止,但无法正确重新启动;所以,我重新启动了计算机。重新启动后,lpd 确实再次运行。
现在是进行一些测试的时候了。首先,尝试从您的提示符处打印一个普通的文本文件;一些简短的内容,例如
lpr /etc/group
您的打印机应该打印该文件,而不会出现阶梯效应。假设这里没有问题,请尝试打印 PostScript (.ps) 文件。接下来,尝试图形文件,如 .gif 或 .jpeg。如果您手头有一个 .dvi 文件,请尝试打印它。所有这些文件都应生成完美的输出。最后,尝试打印二进制文件,如 /bin/sync。您不应从打印机获得任何输出,并且,如果您正在运行 sendmail、smail 或其他邮件代理,您应该立即收到来自 bin@your.localhost 的电子邮件,解释您的文件为何无法打印。如果您没有运行邮件程序,您的 $ 提示符将返回,并且您将不会从打印机获得任何输出。MagicFilter 不会在控制台上显示错误消息。
此时,值得打印您的打印机的实际过滤器脚本的列表。您会注意到它是一个以 MagicFilter 作为解释器的解释型脚本。它分为三列垂直列。第一列是距文件开头的偏移量,第二列是要搜索的字符串,第三列是处理每种文件类型的功能。向下读取列,您可以看到 MagicFilter 可以处理的所有不同类型的文件以及它如何处理它们,以及它无法处理的文件。请注意第三列中的 pipe 和 fpipe 方法。该方法的输出被反馈到 MagicFilter 以进行第二次或后续传递。例如,对于 .dvi 文件来说,这是必要的。首先 dvips 在 .dvi 文件上运行,生成的临时 PostScript 文件被反馈到 MagicFilter,其中 ghostscript 然后执行实际打印——非常巧妙。
这个流行的电子邮件程序需要稍微调整才能正常工作。如果您将 Pine 的默认打印机制设置为 lpr,您可能会发现超过一页的电子邮件将在某些打印机上丢失最后 2 或 3 行文本。这是因为某些打印机(例如佳能喷墨打印机)每页最多只能打印 63 行,而 lpr 认为它们应该有 66 行每页。为了解决这个问题,创建一个名为 print 的简短脚本,其中包含以下两行
#!/bin/sh pr $1 | lpr
将此脚本放在您的主目录或路径中的某个位置,然后将其安装为 Pine 的打印命令。从 Pine 的主菜单中,按如下方式选择:S (setup)、P (printers),然后向下箭头到“Personally selected print command”。将“Printer List”设置为 /dev/lp1(或您的打印机设备名称),并将您的打印命令(在同一行上)设置为 ~/print。要进行这些更改,请输入 C-N(change, name),然后再次输入 C(change command)。在提示时保存您的更改。
此打印设置将在排队打印之前,通过 pr 实用程序运行您的电子邮件以进行格式化。这有点巧妙,因为您的输出页面将在每页顶部都有日期/时间戳和页码。您可以使用命令行开关修改 pr 的行为,以产生您希望的外观(请参阅 man(1) pr)。
您应该能够从 Netscape 打印,而无需进行任何调整。要对其进行测试,请启动 Netscape 并加载一个具有挑战性的文档。从“文件”菜单中,选择“打印”,并观察打开的对话框。从对话框顶部,验证是否已按下“打印机”按钮,您的“打印命令”是否为 lpr,以及其余打印设置对于您的打印机和纸张是否合理。然后,按下“打印”按钮。图 1 显示了它的外观。
您应该获得浏览器屏幕上内容的精确打印输出,包括图形和所有内容。当然,这假设您有一台支持图形的打印机,并且您构建的 MagicFilter 至少支持 ghostscript。Netscape 默认设置存储在一个名为 ~/.Netscape/preferences 的文件中。您可以检查该文件以确保您的打印命令是 lpr,并在必要时进行调整。
您甚至可以将 Netscape 用作一种笨拙的文字处理器。从“文件”菜单中,选择“新建文档 -> 空白”。Netscape 编辑器将打开一个空白屏幕,准备复制。此编辑器是针对 HTML 的;它非常适合编写 WWW 页面,但对于生成信件等,它还有很多不足之处。使用 Netscape 的编辑器,您在屏幕上看到的内容通常不完全匹配打印机输出。
对于真正的实际文字处理,我认为您无法击败 Applixware,尤其是因为它的价格刚刚降至每份 199 美元。事实上,我正在 Applixware 文字处理器上键入这篇文章。它仅在 Red Hat Linux 上获得官方支持,但它在 Slackware 96 上也能正常工作。安装时,请务必将您的 DISPLAY 环境变量设置为
export DISPLAY=:0
在 486 平台上,注释掉 /etc/XF86Config 文件中的 Speedo 和 Type I 字体,可以使 Applixware 加载速度足够快,以防止 X 服务器连接超时。此调整也使 Netscape 加载速度更快。同样在 486 上,Applixware 在仅 X 环境中工作,即,在级别 4 而不是通常的级别 3 重新启动 /sbin/init。最后,要通常运行 Applixware,需要大量 RAM。
要使用 Applixware 打印项目,请按下顶部菜单栏上的打印图标,并注意随后出现的打印对话框。只需在“打印机”下按下 lp,将“类别”设置为 PostScript(应该已经在那里),确保未按下“打印到文件”按钮,然后单击“确定”。安装 MagicFilter 后,Applixware 应该真正可以开箱即用。图 2 显示了打印前打印对话框的显示方式。
通常,打印 .tex 文件是一个三步过程。首先,您在 .tex 文件上运行 tex,然后在 .dvi 文件上运行 dvips,然后在 .ps 文件上运行 ghostscript。使用 MagicFilter,您只需在文档文件上运行 TeX 或 LaTeX,将生成的 .dvi 文件直接发送到 lpr,然后让 MagicFilter 处理其余部分。这里有一个注意事项——如果 .dvi 文件包含对 PostScript 图形的引用,您必须手动运行 dvips 并将生成的 .ps 文件发送到 lpr。由于 dvips 的默认设置是将输出发送到打印机,因此您可以简单地将其视为运行 dvips 将文档发送到打印机。这不是 MagicFilter 的缺陷,而是 .dvi 文件处理嵌入式 PostScript 的方式中的一个“缺失功能”。
在使用 MagicFilter 一段时间后,我认为它将成为商业 Linux 软件包的绝佳补充,作为其初始安装的一部分。但转念一想,考虑到我们今天拥有的打印机和文件格式种类繁多,这说起来容易做起来难。MagicFilter 的优点之一是它可以根据您的个人系统、打印机和打印需求进行定制。尝试将其集成到发行版的安装过程中可能会适得其反。MagicFilter 及其支持软件包易于构建,并且易于获得。最好还是保持现状。如果您从未在自己的系统上编译过软件,MagicFilter 是一个很棒的入门项目,并且可以为新的 Linux 用户建立很大的信心。
Brian McCauley 在 Linux Printing-HOWTO 中指出,MagicFilter 阻止用户打印例如二进制文件的列表,他是对的。但是,我认为大多数人宁愿关闭 MagicFilter(如果这种情况发生),打印列表,然后重新打开 MagicFilter。它只是让生活变得更加简单。
