Chapter 6. 打印

Table of Contents
6.1. 打印机常驻程序
6.2. 设定 /etc/printcap
6.3. 设定 Ghostscript
6.4. 管理打印机的指令
6.5. 远程打印

这一章描述简单的打印设定,使用 HP Deskjet 690C 打印机, 以并行端口为连结接口作为例子。首先,必须设定系统来印纯文件, 接着延伸设定并使用 Ghostscript 程序来打印 PostScript 文件。

6.1. 打印机常驻程序

在安装完成后还不能进行打印,因为 lpd 打印队列常驻程序还未启动。要启动 lpd , 则在 /etc/rc.conf 中必须更改这一行:

lpd=NO
    

lpd=YES
    

这个改变在下次开机时便会生效,但可以立刻以手动方式启动:

# lpd -s
    

要检查 lpd 是否启动,键入以下指令:

# ps ax | grep lpd
  179 ??  Is     0:00.01 lpd
    

如果你没有看到有关 lpd 的项目,则常驻程序没有启动。

在设定 /etc/printcap 以前,最好先做 打印机测试,检查联机是否正常。例如:

# lptest 20 10 > /dev/lpt0
    

看看输出的结果,使用相同的指令,但是不要将输出重导到打印机:

# lptest 20 10
    

常见的问题是输出至打印机的数据不会标齐而会有"锯齿状"。 这通常是表示是指打印机被设定为,在同时接收到 <CR> (carriage return, ASCII 13) 字符和 <LF> (line feed, ASCII 10) 字符后,才会在左边界开始新的一行。 可以修正这个问题:

Note: 在先前的例子,lpd 队列程序 并没有用到,因为程序的输出直接导向打印装置 (/dev/lpt0) 而且没有被队列。

6.2. 设定 /etc/printcap

这一段解释如何简单的设定来打印纯文件。

/etc/printcap 中必须有打印机的 记载项目;这个项目包括打印机的 id(打印机的名称)和打印机的 描述。lp id,是许多程序的默认值。

Example 6-1. /etc/printcap

lp|local printer|HP DeskJet 690C:\
        :lp=/dev/lpa0:sd=/var/spool/lpd/lp:lf=/var/log/lpd-errs:\
        :sh:pl#66:pw#80:if=/usr/local/libexec/lpfilter:
    

档案格式和选项都被详细地描述在 printcap(5) 里。请注意 输入过滤程序已经被指明 (即为 if 选项)而将会避免产生锯齿状的问题。

if=/usr/local/libexec/lpfilter
    

打印机驱动程序和 HP 打印机: Example 6-1 使用 lpa# 装置做为打印机(询查模式),而不是 lpd# (中断模式)。使用中断模式会和某些打印机产生沟通的问题, 而 HP Deskjet 690C 正好是其中之一:打印会非常慢,打印一页 PostScript 文件可能要花上一个小时。这个问题可以藉由使用 lpa 驱动程序来解决。我们也可以重新 编译一个个人化核心使 lpd 成为询查模式。

printcap 中关于打印机的项目所指明的队列目录必须被建立; 这个目录将被 lpd 常驻程序用来累积 数据以进行打印。

# cd /var/spool/lpd
# mkdir lp
# chown daemon:daemon lp
# chmod 770 lp
    

唯一遗漏的部份是 lpfilter 输入过滤程序,我们必须撰写它。这个过滤程序唯一的工作只是在 数据被送往打印以前,做排除锯齿状问题的工作。在此例中,打印机 需要以下的字符串做初始化:"ESC &k2G"。

Example 6-2. /usr/local/libexec/lpfilter

#!/bin/sh
# Treat LF as CR+LF
printf "\033&k2G" && cat && exit 0
exit 2
    
# cd /usr/local/libexec
# chmod 755 lpfilter*
    

Note: 有另一个过滤程序可以被使用:

:if=/usr/libexec/lpr/lpf:
    
这个过滤程序比之前的更为复杂。它被用来处理 nroff 的输出以及底线和附加打印, 展开 tab 字符和转换 LF 成 CR + LF。这个过滤程序的 原始码可以在此被找到 /usr/src/usr.sbin/lpr/filters/lpf.c

再一次执行 lptest 指令,这次使用 lpd 队列程序。

# lptest 20 10 | lpr -h
    

使用 lpr 程序行印文件将会利用队列程序 将数据送往打印机;-h 选项会避免标题页的 打印(不是必要的,因为 sh 选项已经 出现在 /etc/printcap 中了)。

你可以使用各种不同的工具和方法解决锯齿状的问题,例如 C 程序。 使用上述的方法是最简单的。

6.3. 设定 Ghostscript

基本的打印已经可以运作了,我们现在要加入打印 PostScript 档案 的功能。此例中的打印机并不支持 PostScript;我们必须使用程序来 转换 PostScript 文件成一连串的命令使打印机能了解。在 package 集合中的 Ghostscript 程序可以达成 这个目的(请看 Chapter 8)。这一段解释如何设定 Ghostscript 使 HP Deskjet 690C 能 打印 PostScript 档案。

/etc/printcap 中为打印机建立第二 个 id:新的 id 将使用不同的输入过滤程序,将会呼叫 Ghostscript 来执行 PostScript 文件的打印。因此,纯文件将会使用 lp 打印机而 PostScript 文件则使用 ps 打印机:两者都使用相同的实体打印机, 但却有不同的打印过滤程序。

可以使用不同的设定来达到相同的结果。例如,在设定项目中只使用 一个过滤程序:过滤程序能够自动地决定所要打印文件的格式并使用 适当的打印程序。这个方法较为简单但却导致一个较为复杂的过滤程 式;或许你可以考虑从 package 集合安装 magicfilter:它会自动地完成这个结 果并做许多其它的工作。

新的 /etc/printcap 看起来像这样:

Example 6-3. /etc/printcap

lp|local printer|HP DeskJet 690C:\
        :lp=/dev/lpa0:sd=/var/spool/lpd/lp:lf=/var/log/lpd-errs:\
        :sh:pl#66:pw#80:if=/usr/local/libexec/lpfilter:

ps|Ghostscript driver:\
        :lp=/dev/lpa0:sd=/var/spool/lpd/ps:lf=/var/log/lpd-errs:\
        :mx#0:sh:if=/usr/local/libexec/lpfilter-ps:
    

对打印 PostScript 档案而言,mx#0 是非常重要 的选项,因为它排除了输入档案大小的限制;PostScript 文件可以 非常大。if 选项指向新的过滤程序。也有一个新 的队列目录。

最后的步骤是建立新的队列目录和过滤程序。

# cd /var/spool/lpd
# mkdir ps
# chown daemon:daemon ps
# chmod 770 ps
    

处理 PostScript 输出的过滤程序比纯文件的较为复杂:要打印的档案 必须经过直译器,也就是利用打印机的控制语言,传送一连串的命令给 打印机。我们可以利用 NetBSD 操作系统和一些功能强大的而免费的 package,使得廉价的彩色打印机能够接受 PostScript 格式的输出。 设定 Ghostscript 所使用的选项在 Ghostscript 文件中有详细的叙述:cdj550 是 HP 打印机的驱动程序。

Example 6-4. /usr/local/libexec/lpfilter-ps

#!/bin/sh
# Treat LF as CR+LF
printf "\033&k2G" || exit 2
# Print the postscript file
/usr/pkg/bin/gs -dSAFER -dBATCH -dQUIET -dNOPAUSE -q -sDEVICE=cdj550 \
-sOutputFile=- -sPAPERSIZE=a4 - && exit 0
exit 2
    

摘要:在系统上要建立两个不同的打印机名称,指向相同的实体打印机 但使用不同的选项,不同的过滤程序和不同的队列目录。纯文件和 PostScript 文件都可以被打印。要打印 PostScript 文件则 Ghostscript package 必须安装在系统上。

6.4. 管理打印机的指令

这一段列出一些有用的 BSD 的打印和管理打印工作的指令。除了 已经提到的 lprlpd 以外,我们有:

lpq

检查打印队列。

lprm

删除打印队列中的工作。

lpc

检查打印系统,增加或取消打印机及打印机的功能。

6.5. 远程打印

我们也可以设定打印系统来使用连接在远程主机上的打印机。举例 说明,你在 wotan 主机上工作而你想要使 用连接在 loge 主机上的打印机。 /etc/printcap 是在特别情况 Example 6-3 中的一个设定档。 在这个特殊情况中,在 wotan 上也可以 打印 Ghostscript 文件。

第一步是使这个特殊的主机能够打印从 wotan 主机上所提交的工作。在特殊主机的 /etc/hosts.lpd 中,加入一行 wotan 主机的名称。这个档案的格式非常简单: 每一行都包含一个能够使用的主机。

接着,必须设定 wotan 上的 /etc/printcap 为了使工作能传送到特殊主机。例如:

lp|line printer on loge:\
	:lp=:sd=/var/spool/lpd/lp:lf=/var/log/lp-errs:\
	:rm=loge:rp=lp

ps|Ghostscript driver on loge:\
	:lp=:sd=/var/spool/lpd/lp:lf=/var/log/lp-errs:\
	:mx#0:\
	:rm=loge:rp=ps
    

There are four main differences between this configuration and the one of Example 6-3. 在这个设定和 Example 6-3 中的那一个有四个 主要的不同点。

  1. "lp" 定义是空白的。

  2. "rm" 设定项目定义了打印机所连接的主机的名称。

  3. "rp" 设定项目定义了连接到远程主机的打印机的名称。

  4. 指明输入过滤程序是必要的,因为在特殊主机上的定义将会被使用。

现在在 wotan 上执行 "lp" 和 "ps",所产生 的打印工作将被自动地传送到打印机所连接的主机上。