第 11 章 打印

如果发现翻译错误,请直接 发起PR修改

将信息记录在纸上是一项重要的功能,尽管有许多试图消除它的尝试。打印有两个基本组成部分。数据必须传递给打印机,并且必须以打印机能够理解的形式呈现。

11.1. 快速入门

基本的打印设置可以很快完成。打印机必须能够打印纯文本的 ASCII 字符。如需打印其他类型的文件,请参阅 过滤器

  1. 创建一个目录来存储正在打印的文件:

    # mkdir -p /var/spool/lpd/lp
    # chown daemon:daemon /var/spool/lpd/lp
    # chmod 770 /var/spool/lpd/lp
  2. root 身份创建 /etc/printcap 文件,并使用以下内容:

    lp:\
    lp=/dev/unlpt0:\  (1)
    sh:\
    mx#0:\
    sd=/var/spool/lpd/lp:\
    lf=/var/log/lpd-errs:
    1 这行是为连接到 USB 端口的打印机准备的。

    对于连接到并行或“打印机”端口的打印机,请使用:

    :lp=/dev/lpt0:\

    对于直接连接到网络的打印机,请使用以下方法:

    :lp=:rm=network-printer-name:rp=raw:\

    将_network-printer-name_替换为网络打印机的 DNS 主机名。

  3. 通过编辑 /etc/rc.conf 文件,添加以下行来启用 LPD :

    lpd_enable="YES"

    启动服务:

    # service lpd start
    Starting lpd.
  4. 打印一个测试:

    # printf "1. This printer can print.\n2. This is the second line.\n" | lpr

    如果两条线都不从左边界开始,而是“阶梯状”开始,请参见 防止普通文本打印机上的阶梯状输出

    现在可以使用 lpr 命令打印文本文件。在命令行上给出文件名,或直接将输出通过管道传递给 lpr

    % lpr textfile.txt
    % ls -lh | lpr

11.2. 打印机连接

打印机可以通过多种方式连接到计算机系统。小型台式打印机通常直接连接到计算机的 USB 端口。旧式打印机则连接到并行或“打印机”端口。有些打印机直接连接到网络,方便多台计算机共享使用。少数打印机使用罕见的串行端口连接。

FreeBSD 可以与所有这些类型的打印机进行通信。

USB 是一种通用串行总线( Universal Serial Bus )的缩写,它是一种用于连接计算机和外部设备的标准接口。 USB 接口可以用于连接各种设备,包括打印机、键盘、鼠标、摄像头、移动存储设备等。 USB 接口具有热插拔功能,可以在计算机运行时插入或拔出设备,而无需重新启动计算机。 USB 接口还可以提供电力供应,使连接的设备可以通过 USB 接口获得电力。 USB 接口有多个版本,包括 USB 1.0 、 USB 2.0 、 USB 3.0 和 USB 4.0 ,每个版本都有不同的传输速度和功能。

USB 打印机可以连接到计算机上的任何可用的 USB 端口。

当 FreeBSD 检测到一个 USB 打印机时,会创建两个设备条目: /dev/ulpt0/dev/unlpt0 。发送到任何一个设备的数据都会传递给打印机。在每个打印作业之后, ulpt0 会重置 USB 端口。重置端口可能会导致一些打印机出现问题,所以通常使用 unlpt0 设备代替。 unlpt0 根本不会重置 USB 端口。

并行( IEEE-1284 )

并行端口设备是 [/dev/lpt0] 。无论是否连接打印机,该设备都会出现,不会自动检测。

供应商们大多已经放弃了这些“传统”端口,许多计算机不再配备这些端口。可以使用适配器将并行打印机连接到 USB 端口。通过这样的适配器,打印机可以被视为实际上是一台 USB 打印机。还可以使用称为“打印服务器”的设备将并行打印机直接连接到网络。

串行( RS-232 )

串口是另一种遗留端口,在某些特定的利基应用中除外,很少用于打印机。电缆、连接器和所需的布线各不相同。

对于集成在主板上的串口,串口设备名称是 [/dev/cuau0] 或 [/dev/cuau1] 。串口 USB 适配器也可以使用,它们将显示为 [/dev/cuaU0] 。

与串行打印机通信需要了解几个通信参数。其中最重要的是波特率( Baud Rate )或 BPS (每秒比特数)和奇偶校验( Parity )。具体数值可能有所不同,但典型的串行打印机使用波特率为 9600 ,无奇偶校验。

网络

网络打印机直接连接到本地计算机网络。

必须知道打印机的 DNS 主机名。如果打印机通过 DHCP 分配动态地址,则应动态更新 DNS ,以便主机名始终具有正确的 IP 地址。为了避免这个问题,通常给网络打印机分配静态 IP 地址。

大多数网络打印机都能理解使用 LPD 协议发送的打印作业。还可以指定打印队列名称。根据使用的队列不同,一些打印机会以不同的方式处理数据。例如, raw 队列会原样打印数据,而 text 队列会在纯文本中添加回车符。

许多网络打印机还可以打印直接发送到端口 9100 的数据。

11.2.1. 摘要

有线网络连接通常是最容易设置并且打印速度最快的。对于直接连接到计算机, USB 是首选,因为速度快且简单。并行连接也可以工作,但是在电缆长度和速度方面有一些限制。串行连接更难配置。电缆布线在不同的型号之间有所不同,通信参数如波特率和奇偶校验位增加了复杂性。幸运的是,串行打印机很少见。

11.3. 常见的页面描述语言

发送给打印机的数据必须使用打印机能够理解的语言。这些语言被称为页面描述语言( Page Description Languages ,简称 PDLs )。

Ports Collection 中的许多应用程序和 FreeBSD 实用程序会生成 PostScript® 输出。下表显示了可用于将其转换为其他常见 PDL 的实用程序:

为了实现最简单的打印,选择支持 PostScript® 的打印机是最好的选择。其次是支持 PCL 的打印机。使用 print/ghostscript9-base 软件包,这些打印机可以像本地支持 PostScript® 一样使用。几乎所有直接支持 PostScript® 或 PCL 的打印机也支持直接打印纯 ASCII 文本文件。

像典型的喷墨打印机一样,基于行的打印机通常不支持 PostScript® 或 PCL 。它们通常可以打印纯文本文件。 print/ghostscript9-base 支持一些这些打印机使用的页面描述语言( PDL )。然而,由于需要传输和打印的数据量很大,使用这些打印机打印整个基于图形的页面通常非常慢。

基于主机的打印机通常更难设置。由于专有的页面描述语言( PDL ),有些打印机根本无法使用。尽量避免使用这些打印机。

许多页面描述语言( PDL )的描述可以在 http://www.undocprint.org/formats/page_description_languages 找到。各种型号打印机使用的特定 PDL 可以在 http://www.openprinting.org/printers 找到。

11.4. 直接打印

对于偶尔打印的情况,可以直接将文件发送到打印机设备,无需进行任何设置。例如,可以将名为 sample.txt 的文件发送到一个 USB 打印机。

# cp sample.txt /dev/unlpt0

直接打印到网络打印机取决于打印机的功能,但大多数打印机可以在端口 9100 上接受打印作业,可以使用 nc(1) 与它们一起使用。要将同一文件打印到名为_netlaser_的打印机上:

# nc netlaser 9100 < sample.txt

11.5. LPD ( Line Printer Daemon )是一种用于打印机的网络协议。

在后台打印文件被称为“spooling”。一个打印机缓冲程序允许用户在打印作业慢慢完成的过程中继续使用计算机上的其他程序,而无需等待打印机完成。

FreeBSD 包含一个名为 lpd(8) 的打印队列管理器。打印作业可以使用 lpr(1) 提交。

11.5.1. 初始设置

创建了一个用于存储打印作业的目录,设置了所有权,并设置了权限,以防止其他用户查看这些文件的内容:

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

打印机在 /etc/printcap 中定义。每个打印机的条目包括名称、连接端口和其他各种设置。使用以下内容创建 /etc/printcap 文件:

lp:\				(1)
	:lp=/dev/unlpt0:\	(2)
	:sh:\			(3)
	:mx#0:\			(4)
	:sd=/var/spool/lpd/lp:\	(5)
	:lf=/var/log/lpd-errs:	(6)
1 这台打印机的名称。 lpr(1) 命令将打印作业发送到 lp 打印机,除非使用 -P 指定了其他打印机,因此默认打印机应该被命名为 lp
2 打印机连接的设备。将此行替换为适用于此处显示的连接类型的正确行。
3 在打印作业开始时禁止打印页眉。
4 不要限制打印作业的最大大小。
5 这台打印机的排队目录路径。每台打印机都使用自己的排队目录。
6 这台打印机报告错误的日志文件。

创建 /etc/printcap 后,使用 chkprintcap(8) 来测试是否存在错误:

# chkprintcap

在继续之前,请修复所有报告的问题。

/etc/rc.conf 文件中启用 lpd(8)

lpd_enable="YES"

启动服务:

# service lpd start

11.5.2. 使用 lpr(1) 打印

使用 lpr 命令将文档发送到打印机。要打印的文件可以在命令行上指定名称,也可以通过管道传递给 lpr 。以下两个命令是等效的,将 doc.txt 的内容发送到默认打印机:

% lpr doc.txt
% cat doc.txt | lpr

可以使用 -P 选项选择打印机。要打印到名为_laser_的打印机:

% lpr -Plaser doc.txt

11.5.3. 过滤器

到目前为止展示的示例已经直接将文本文件的内容发送到打印机。只要打印机能理解这些文件的内容,输出就会正确打印。

有些打印机无法打印纯文本,而输入文件甚至可能不是纯文本。

过滤器 允许文件进行翻译或处理。典型的用法是将一种类型的输入(如纯文本)转换为打印机可以理解的形式,如 PostScript® 或 PCL 。过滤器还可以用于提供额外的功能,如添加页码或突出显示源代码以便更容易阅读。

这里讨论的过滤器是“输入过滤器”或“文本过滤器”。这些过滤器将输入的文件转换为不同的形式。在创建文件之前,使用 su(1) 命令切换为“ root ”用户。

过滤器在 /etc/printcap 中使用 `if = ` 标识符进行指定。要使用 /usr/local/libexec/lf2crlf 作为过滤器,修改 /etc/printcap 如下:

lp:\
	:lp=/dev/unlpt0:\
	:sh:\
	:mx#0:\
	:sd=/var/spool/lpd/lp:\
	:if=/usr/local/libexec/lf2crlf:\   (1)
	:lf=/var/log/lpd-errs:
1 `if = ` 标识了将用于处理传入文本的 输入过滤器

printcap 条目的行尾处使用反斜杠 line continuation 字符,揭示了打印机条目实际上只是一行长字符串,其中条目由冒号字符分隔。一个早期的示例可以重写为一行不易读的字符串:

lp:lp=/dev/unlpt0:sh:mx#0:sd=/var/spool/lpd/lp:if=/usr/local/libexec/lf2crlf:lf=/var/log/lpd-errs:

11.5.3.1. 防止普通文本打印机上的阶梯状输出

典型的 FreeBSD 文本文件每行末尾只包含一个换行符。这些行在标准打印机上会呈“阶梯状”排列:

A printed file looks
                    like the steps of a staircase
                                                 scattered by the wind

一个过滤器可以将换行符转换为回车和换行符。回车使打印机在每行结束后返回到左侧。创建名为 /usr/local/libexec/lf2crlf 的文件,并将以下内容写入该文件:

#!/bin/sh
CR=$'\r'
/usr/bin/sed -e "s/$/${CR}/g"

设置权限并使其可执行:

# chmod 555 /usr/local/libexec/lf2crlf

/etc/printcap 修改为使用新的过滤器:

:if=/usr/local/libexec/lf2crlf:\

通过打印相同的纯文本文件来测试过滤器。回车符将导致每行从页面的左侧开始。

11.5.3.2. 使用 print/enscript 在 PostScript® 打印机上打印时,可以得到漂亮的纯文本输出。

GNUEnscript 将纯文本文件转换为适合在 PostScript 打印机上打印的格式良好的 PostScript 文件。它添加页码,换行长行,并提供许多其他功能,使打印的文本文件更易于阅读。根据本地纸张尺寸,从 Ports Collection 安装 print/enscript-letterprint/enscript-a4

创建 /usr/local/libexec/enscript 文件,并使用以下内容:

#!/bin/sh
/usr/local/bin/enscript -o -

设置权限并使其可执行:

# chmod 555 /usr/local/libexec/enscript

/etc/printcap 修改为使用新的过滤器:

:if=/usr/local/libexec/enscript:\

通过打印一个纯文本文件来测试过滤器。

11.5.3.3. 将 PostScript® 打印到 PCL 打印机

许多程序生成 PostScript® 文档。然而,廉价打印机通常只能理解纯文本或 PCL 格式。该过滤器将 PostScript® 文件转换为 PCL 格式,然后发送给打印机。

从 Ports Collection 安装 Ghostscript PostScript® 解释器,包名为: print/ghostscript9-base[] 。

创建 /usr/local/libexec/ps2pcl 文件,并使用以下内容:

#!/bin/sh
/usr/local/bin/gs -dSAFER -dNOPAUSE -dBATCH -q -sDEVICE=ljet4 -sOutputFile=- -

设置权限并使其可执行:

# chmod 555 /usr/local/libexec/ps2pcl

将发送给此脚本的 PostScript® 输入将在发送到打印机之前被渲染并转换为 PCL 格式。

/etc/printcap 修改为使用这个新的输入过滤器:

:if=/usr/local/libexec/ps2pcl:\

通过向过滤器发送一个小的 PostScript® 程序来测试过滤器:

% printf "%%\!PS \n /Helvetica findfont 18 scalefont setfont \
72 432 moveto (PostScript printing successful.) show showpage \004" | lpr

11.5.3.4. 智能过滤器

一个能够检测输入类型并自动将其转换为打印机正确格式的过滤器非常方便。 PostScript® 文件的前两个字符通常是 % ! ` 。过滤器可以检测到这两个字符。 PostScript® 文件可以直接发送到 PostScript® 打印机进行打印。文本文件可以使用之前展示的 Enscript 工具转换为 PostScript® 格式。请创建一个名为 `/usr/local/libexec/psif 的文件,并将以下内容添加到其中:

#!/bin/sh
#
#  psif - Print PostScript or plain text on a PostScript printer
#
IFS="" read -r first_line
first_two_chars=`expr "$first_line" : '\(..\)'`

case "$first_two_chars" in
%!)
    # %! : PostScript job, print it.
    echo "$first_line" && cat && exit 0
    exit 2
    ;;
*)
    # otherwise, format with enscript
    ( echo "$first_line"; cat ) | /usr/local/bin/enscript -o - && exit 0
    exit 2
    ;;
esac

设置权限并使其可执行:

# chmod 555 /usr/local/libexec/psif

/etc/printcap 修改为使用这个新的输入过滤器:

:if=/usr/local/libexec/psif:\

通过打印 PostScript® 和纯文本文件来测试过滤器。

11.5.3.5. 其他智能过滤器

编写一个能够检测多种不同类型输入并正确格式化的过滤器是具有挑战性的。 Ports Collection 中的 print/apsfilter 是一个智能的“魔法”过滤器,它可以检测数十种文件类型,并自动将它们转换为打印机理解的 PDL 格式。更多详情请参考 http://www.apsfilter.org

11.5.4. 多个队列

/etc/printcap 中的条目实际上是对_队列_的定义。一个打印机可以有多个队列。与过滤器结合使用时,多个队列可以使用户更好地控制他们的作业如何打印。

以一个办公室中的网络化 PostScript® 激光打印机为例。大多数用户希望打印纯文本,但是少数高级用户希望能够直接打印 PostScript® 文件。可以在 [/etc/printcap] 中为同一台打印机创建两个条目:

textprinter:\
	:lp=9100@officelaser:\
	:sh:\
	:mx#0:\
	:sd=/var/spool/lpd/textprinter:\
	:if=/usr/local/libexec/enscript:\
	:lf=/var/log/lpd-errs:

psprinter:\
	:lp=9100@officelaser:\
	:sh:\
	:mx#0:\
	:sd=/var/spool/lpd/psprinter:\
	:lf=/var/log/lpd-errs:

发送给 textprinter 的文档将由之前示例中显示的 /usr/local/libexec/enscript 过滤器进行格式化。高级用户可以在 psprinter 上打印 PostScript® 文件,不进行任何过滤。

这种多队列技术可以用来提供对各种打印机功能的直接访问。具有双面打印功能的打印机可以使用两个队列,一个用于普通的单面打印,另一个使用过滤器发送命令序列以启用双面打印,然后发送传入的文件。

11.5.5. 监控和控制打印

有几种实用工具可用于监控打印作业、检查和控制打印机操作。

11.5.5.1. lpq(1) 是一个命令,用于查看打印队列的状态。

lpq(1) 显示用户打印作业的状态。不显示其他用户的打印作业。

显示当前用户在单个打印机上的待处理作业。

% lpq -Plp
Rank   Owner      Job  Files                                 Total Size
1st    jsmith     0    (standard input)                      12792 bytes

显示当前用户在所有打印机上的待处理作业。

% lpq -a
lp:
Rank   Owner      Job  Files                                 Total Size
1st    jsmith     1    (standard input)                      27320 bytes

laser:
Rank   Owner      Job  Files                                 Total Size
1st    jsmith     287  (standard input)                      22443 bytes

11.5.5.2. lprm(1)

lprm(1) 用于删除打印作业。普通用户只能删除自己的作业。 root 可以删除任何或所有作业。

从打印机中删除所有待处理作业。

# lprm -Plp -
dfA002smithy dequeued
cfA002smithy dequeued
dfA003smithy dequeued
cfA003smithy dequeued
dfA004smithy dequeued
cfA004smithy dequeued

从打印机中删除一个作业。使用 lpq(1) 命令查找作业编号。

% lpq
Rank   Owner      Job  Files                                 Total Size
1st    jsmith     5    (standard input)                      12188 bytes

% lprm -Plp 5
dfA005smithy dequeued
cfA005smithy dequeued

11.5.5.3. lpc(8)

lpc(8) 用于检查和修改打印机的状态。 lpc 后面跟着一个命令和一个可选的打印机名称。可以使用 all 代替特定的打印机名称,命令将应用于所有打印机。普通用户可以使用 lpc(8) 查看状态。只有 root 用户可以使用修改打印机状态的命令。

显示所有打印机的状态:

% lpc status all
lp:
	queuing is enabled
	printing is enabled
	1 entry in spool area
	printer idle
laser:
	queuing is enabled
	printing is enabled
	1 entry in spool area
	waiting for laser to come up

阻止打印机接受新的任务,然后再次开始接受新的任务:

# lpc disable lp
lp:
	queuing disabled
# lpc enable lp
lp:
	queuing enabled

停止打印,但继续接受新的任务。然后再次开始打印:

# lpc stop lp
lp:
	printing disabled
# lpc start lp
lp:
	printing enabled
	daemon started

在发生错误情况后重新启动打印机:

# lpc restart lp
lp:
	no daemon to abort
	printing enabled
	daemon restarted

关闭打印队列并禁用打印功能,并附带一条消息向用户解释问题原因:

# lpc down lp Repair parts will arrive on Monday
lp:
	printer and queuing disabled
	status message is now: Repair parts will arrive on Monday

重新启用处于离线状态的打印机:

# lpc up lp
lp:
	printing enabled
	daemon started

更多的命令和选项请参考 lpc(8)

11.5.6. 共享打印机

打印机在企业和学校中通常由多个用户共享。为了更方便地共享打印机,还提供了额外的功能。

11.5.6.1. 别名

打印机名称设置在 [/etc/printcap] 文件的第一行中。在该名称之后可以添加其他名称,也称为“别名”。别名之间和与名称之间用竖线分隔:

lp|repairsprinter|salesprinter:\

别名可以用来替代打印机名称。例如,销售部门的用户可以使用别名来打印到他们的打印机。

% lpr -Psalesprinter sales-report.txt

维修部门的用户使用他们自己的打印机进行打印。

% lpr -Prepairsprinter repairs-report.txt

所有的文件都打印在同一台打印机上。当销售部门发展到需要自己的打印机时,可以从共享打印机条目中删除别名,并将其用作新打印机的名称。两个部门的用户继续使用相同的命令,但销售文件将被发送到新的打印机。

11.5.6.2. 页眉页

对于用户来说,在繁忙的共享打印机产生的一堆页面中定位他们的文档可能很困难。为了解决这个问题,创建了“页眉页”。在每个打印作业之前,会打印一个包含用户姓名和文档名称的页眉页。这些页面有时也被称为“横幅”或“分隔符”页面。

启用页眉页面的方法取决于打印机是通过 USB 、并行或串行电缆直接连接到计算机,还是通过网络远程连接。

直接连接的打印机上的页眉页面可以通过从 /etc/printcap 文件中的条目中删除 :sh: \ ` ( Suppress Header )行来启用。这些页眉页面只使用换行字符作为换行符。一些打印机需要 /usr/share/examples/printing/hpif 过滤器来防止文本出现阶梯状。该过滤器配置 `PCL 打印机在接收到换行符时同时打印回车和换行符。

网络打印机的页眉页面必须在打印机本身上进行配置。 /etc/printcap 中的页眉页面条目将被忽略。通常可以通过打印机前面板或使用 Web 浏览器访问的配置网页来进行设置。

11.5.7. 参考文献

示例文件: [/usr/share/examples/printing/](/usr/share/examples/printing/) 。

《 4.3BSD 行打印机排队程序手册》, /usr/share/doc/smm/07.lpd/paper.ascii.gz

手册页面: printcap(5)lpd(8)lpr(1)lpc(8)lprm(1)lpq(1)

11.6. 其他打印系统

除了内置的 lpd(8) 之外,还有几个其他的打印系统可供选择。这些系统提供对其他协议或附加功能的支持。

11.6.1. CUPS ( Common UNIX® Printing System )

CUPS 是一个在许多操作系统上可用的流行打印系统。在 FreeBSD 上使用 CUPS 的方法在一个单独的文章中有详细说明: CUPS

11.6.2. HPLIP 是一种用于 Linux 操作系统的开源打印机和扫描仪驱动程序。它提供了与 HP 打印机和扫描仪的通信接口,使用户能够轻松地配置和使用这些设备。 HPLIP 支持各种 HP 打印机和扫描仪的功能,包括打印、扫描、复印和传真等。它还提供了一些额外的功能,如墨水和墨盒状态监测、打印机设置和网络打印等。 HPLIP 是一个非常有用的工具,可以帮助用户更好地管理和使用他们的 HP 打印机和扫描仪。

惠普公司提供了一个支持他们的喷墨和激光打印机的打印系统。该端口是 print/hplip 。主要网页位于 https://developers.hp.com/hp-linux-imaging-and-printing 。该端口在 FreeBSD 上处理所有安装细节。配置信息显示在 https://developers.hp.com/hp-linux-imaging-and-printing/install

11.6.3. LPRng 是一个用于打印管理的软件系统,它是 LPD ( Line Printer Daemon )的一个增强版本。 LPRng 提供了更多的功能和灵活性,可以在 UNIX 和类 UNIX 系统上运行。它支持多种打印机和打印队列,并提供了高级的打印作业控制和管理功能。 LPRng 还支持通过网络打印,并提供了安全性和权限控制机制。它是一个强大而可靠的打印管理解决方案。

LPRng 是作为 lpd(8) 的增强替代品开发的。该端口是 sysutils/LPRng 。有关详细信息和文档,请参阅 http://www.lprng.com/


上次修改时间: September 18, 2024 by fiercex