BSD 打印系统架构与操作指南
1. 系统问题处理
在使用打印机时,若创建的打印机让系统产生混淆,最佳解决办法是彻底移除该打印目标,然后重新设置。有时系统混乱程度严重,甚至连移除打印机都变得困难。此时可采用以下强力方法解决:
$ sudo lpshut
$ sudo lpadmin -xhoser
$ sudo find /usr/spool/lp -name hoser | xargs rm -rf
# remove queued jobs
$ sudo lpsched
$ sudo lpstat -t
上述命令中,前两条命令用于关闭打印假脱机程序,并尝试按照规定方法移除打印机。若系统混乱,
lpadmin -x
可能会失败。
find
命令用于移除打印机的所有接口程序和假脱机目录。
lpsched
用于重启假脱机程序,
lpstat
则会显示打印系统中不再有对该打印机的引用。
2. BSD 打印系统概述
2.1 系统历史与特点
BSD 打印系统最初是为老式行式打印机设计的,但因其设计优良,如今已能支持更多现代打印机和打印语言。其网络部分还可扩展到大型异构网络,允许多台计算机共享打印机。曾有一段时间,BSD 打印假脱机程序
lpd
被广泛接受,甚至出现在一些网络打印机的固件中。
2.2 系统架构
-
lpd 守护进程
:控制对打印机的访问,接收用户或其他(远程)
lpd发送的打印作业,处理后将其发送到实际打印机。它从/etc/printcap(系统的打印机信息数据库)中读取打印机配置信息。 -
lpr 程序
:用户使用
lpr程序向lpd提交打印作业,二者通过 UNIX 域套接字/dev/printer进行通信。lpr确定打印目标的顺序为:先查看命令行中的-Pprinter参数;若未指定,则检查环境变量PRINTER;若仍未找到,则将作业提交给系统默认打印机(名为 “lp” 的打印机,若不存在则为/etc/printcap文件中描述的第一台打印机)。 -
打印作业处理流程
:
-
lpr确定目标打印机后,在/etc/printcap中查找该打印机信息,获取假脱机目录(通常为/var/spool/lpd/printername)。 -
为每个作业在假脱机目录中创建两个文件:以
cf开头的控制文件,包含作业的引用和处理信息;以df开头的数据文件,包含实际要打印的数据。 -
lpr完成文件假脱机后,通知lpd作业的存在。 -
lpd接收通知后,根据/etc/printcap判断打印机是本地还是远程。若是本地打印机,检查相应队列上的打印守护进程是否运行,必要时创建一个;若是远程打印机,打开与远程机器lpd的连接,传输数据和控制文件,并删除本地副本。 -
打印作业按先进先出原则调度,但系统管理员可使用
lpc对单个作业进行调整。 -
作业准备打印时,
lpd在假脱机文件和打印硬件之间创建一系列 UNIX 管道,并在中间安装过滤进程,用于在数据到达打印机前审查和编辑数据流。
-
2.3 打印环境控制命令
日常维护打印系统通常只需使用三个命令:
lpq
、
lprm
和
lpc
。
| 命令 | 位置 | 功能 |
| ---- | ---- | ---- |
|
lpc
|
/usr/sbin
| 控制打印机或队列 |
|
lpd
|
/usr/sbin
| 调度和打印作业 |
|
lpq
|
/usr/bin
| 显示打印队列内容和状态 |
|
lpr
|
/usr/bin
| 排队打印文件 |
|
lprm
|
/usr/bin
| 取消排队或正在打印的作业 |
|
lptest
|
/usr/bin
| 生成 ASCII 测试图案 |
2.4 各命令详细介绍
-
lpd
:使用
-l标志启动lpd时,它会通过syslog在 “lpr” 设施下记录打印请求;不使用该标志时,仅记录错误。访问控制基于主机粒度,只有/etc/hosts.lpd文件中列出的主机才能假脱机打印作业。 -
lpr
:是 BSD 风格系统中唯一可对文件进行打印排队的程序。其他导致文件打印的程序(如
enscript或浏览器)必须通过调用lpr来实现。常用标志包括-#num(打印num份副本)和-h(取消页眉页)。例如,要打印名为thesis的文件两份到名为howler-lw的打印机,可运行:
$ lpr -Phowler-lw -#2 thesis
-
lpq
:通常使用
-P选项选择打印机,-l标志可提供更详细的输出。示例输出如下:
$ lpq
anchor-lj is ready and printing
Rank Owner Job Files Total Size
active garth 314 domain.2x1.ps 298778 bytes
1st kingery 286 standard input 17691 bytes
2nd evi 12 appendices 828 bytes
…
-
lprm
:最常见的形式是
lprm jobid,用于删除指定作业;lprm user用于删除指定用户的所有作业;不带参数的lprm删除当前活动作业;lprm -删除自己提交的所有作业(若为根用户,则删除队列中的所有作业)。普通用户无法删除他人的作业,只有超级用户可以。需要注意的是,尝试删除活动作业可能会导致某些打印机出现问题,若出现问题,可使用ps识别过滤进程并手动终止,也可杀死并重启lpd的主副本,手动从假脱机目录中删除作业。 -
lpc
:可执行多种功能,如启用或禁用特定打印机的排队、启用或禁用特定打印机的打印、移除打印机队列中的所有作业、将作业移到打印机队列顶部、启动、停止或重启
lpd守护进程以及获取打印机状态信息。不过,当打印系统出现小问题时,lpc可能会出现故障,甚至有时声称已解决问题但实际并未执行任何操作。lpc不能跨网络使用,必须登录到拥有要操作打印机的机器上使用。其常用命令如下:-
help [command]:不带参数时显示所有可用lpc命令的简短列表;带参数时显示特定命令的单行描述。 -
enable printer和disable printer:启用或禁用向指定打印机的作业假脱机。 -
start printer和stop printer:启用或禁用指定打印机的打印。 -
abort printer:类似于stop,但不允许当前活动作业完成,重新启用打印时作业将重新打印。 -
down printer message和up printer:影响打印机的假脱机和打印功能,down用于在打印机出现问题或需要长时间离线时使用,可提供一条描述信息;up用于恢复打印机。 -
clean printer:移除打印机队列中的所有排队作业,但允许当前作业完成。 -
topq printer jobid和topq printer username:将指定作业或指定用户的所有作业移到打印机队列顶部。 -
restart printer:重启神秘死亡的打印守护进程。 -
status printer:显示打印机的四个方面信息:是否启用假脱机、是否启用打印、队列中的条目数以及打印机守护进程的状态。
-
3. /etc/printcap 文件
3.1 文件概述
/etc/printcap
是 BSD 打印系统的主数据库,包含打印到本地和远程打印机所需的信息。在向打印机提交作业之前,必须在该文件中描述该打印机。
3.2 文件格式
其格式与
/etc/termcap
和
/etc/remote
相同。每个条目的第一项是打印机的名称列表,用竖线分隔;后面是一系列用冒号分隔的配置设置。配置选项的形式为
xx
、
xx=string
或
xx#number
,其中
xx
是参数的双字符名称,
string
和
number
是要分配给它的值。若未分配值,该变量为布尔型,其存在表示 “true”。允许使用空语句,可在每行开头和结尾添加冒号以方便后续修改。注释以井号
#
开头,条目可跨多行,中间行以反斜杠结尾,后续行按惯例缩进。
3.3 示例
以下示例定义了一台连接到
anchor
机器的远程打印机:
anchor-lj|cer|1-56|LaserJet 5M in lab:\
:lp=/var/spool/lpd/anchor-lj/.null:\
:sd=/var/spool/lpd/anchor-lj:\
:lf=/var/adm/lpd-errs:\
:rw:mx#0:rm=anchor:rp=anchor-lj:
从第一行可知,“anchor - lj”、“cer”、“1 - 56” 和 “LaserJet 5M in lab” 都是同一台打印机的等效名称。建议为打印机提供至少三种主要名称形式:
- 全名:主机名和打印机类型(如 “anchor - lj”)。
- 短名称:三到四个字符,易于输入(如 “cer”)。
- 描述性名称:其他信息(如 “LaserJet 5M in lab”)。
后续行包含设备名称(
lp
)、假脱机目录(
sd
)和错误日志文件(
lf
)的配置设置,最后一行指定与打印机的读写连接(
rw
)、最大文件大小(
mx
,此处无限制)、远程机器名称(
rm
)和远程打印机名称(
rp
)。
3.4 常用变量
| 名称 | 类型 | 含义 | 示例 |
|---|---|---|---|
sd
| 字符串 | 假脱机目录 |
sd=/var/spool/lpd/howler-lw
|
lf
| 字符串 | 错误日志文件 |
lf=/var/log/lpr
|
lp
| 字符串 | 设备名称 |
lp=/dev/lp0
|
rw
| 布尔型 | 以读写方式打开设备 |
rw
|
af
| 字符串 | 会计文件 |
af=/usr/adm/lpr.acct
|
mx
| 数字 | 最大文件大小 |
mx#0
|
rm
| 字符串 | 远程机器名称 |
rm=beast.xor.com
|
rp
| 字符串 | 远程打印机名称 |
rp=howler-lw
|
of
| 字符串 | 输出过滤器 |
of=/usr/libexec/lpr/lpf
|
if
| 字符串 | 输入过滤器 |
if=/usr/sbin/stylascii
|
sh
| 布尔型 | 取消页眉 |
sh
|
3.5 各变量详细介绍
-
sd(假脱机目录)
:每个打印机应有自己的假脱机目录,通常位于
/var/spool/lpd下,名称与打印机全名相同。即使打印机位于不同机器上,也需要本地假脱机目录,因为假脱机文件会先存储在本地,直到可以传输到远程系统进行打印。安装新打印机时,必须手动创建其假脱机目录,权限应为 775,所有者和组均为daemon。该目录还包含两个状态文件:status和lock,分别用于记录打印机状态和防止多个lpd实例在单个队列上活动。 -
lf(错误日志文件)
:打印过滤器产生的错误会记录到该变量指定的文件中。一个错误日志可以供所有打印机共享,可放置在任意位置。记录日志时会包含出错打印机的名称,远程打印机也应设置日志文件,以防与远程机器通信出现问题。需要注意的是,
lpd会通过syslog以 “lpr” 设施发送错误消息,部分过滤器也会将错误消息发送到syslog,因此出现问题时需检查这两个位置。 -
lp(设备名称)
:若打印机为本地打印机,必须指定其设备名称,通常是
/dev目录中代表打印机连接端口的文件。lpd使用lp文件上的建议锁来确定打印机是否正在使用,即使打印机通过网络连接访问,也应提供lp变量的值,可指定一个为该目的创建的唯一虚拟文件,该文件应存在于本地磁盘上。 -
rw(设备打开模式)
:若打印机可通过其设备文件向主机发送状态信息,应指定布尔变量
rw,以请求以读写方式打开设备。读写模式对会计和状态报告很有用,部分过滤器也需要该模式。 -
af(会计文件)
:在打印机物理连接的机器上指定会计文件即可启用会计功能。会计记录在作业实际打印后才会写入,因此在远程打印机的
printcap条目中指定会计文件没有意义。可使用pac命令查看会计信息摘要,打印机会计数据文件通常名为/var/adm/printer - acct,记录每个作业的打印页数(通常不准确)、作业发起的主机名和作业所有者的用户名。打印机的输入过滤器负责生成会计记录,除非过滤器在作业前后实际查询打印机的页数,否则页数记录非常不可靠。 -
mx(文件大小限制)
:
mx变量限制一次可以假脱机的数据量。在某些系统中,mx默认值不为 0(无限制),若要允许大作业,必须显式指定mx#0。 -
rm 和 rp(远程访问信息)
:在大多数情况下,希望从网络上的多台机器访问打印机。应选择一台机器负责与打印机通信,其他机器将作业转发给该机器。远程机器的
printcap条目中,rm指定作业应发送到的机器,rp指定该机器上的打印机名称。为了在多台机器之间共享一个printcap文件,可使打印机的本地和远程名称不同,例如howler - lw - local和howler - lw,但使用lpc命令时必须使用本地名称。 -
of 和 if(打印过滤器)
:过滤器有多种用途,默认打印过滤器(通常为
/usr/lib/lpf)可修复各种非打印序列,并在适当情况下写入会计记录。不过,过滤器没有标准化,不同供应商的过滤器可能不同。过滤器通常是调用一系列翻译程序的 shell 脚本,必须接受标准输入的打印作业,将作业转换为适合设备的格式,并将结果发送到标准输出。若用户在执行lpr时未指定过滤器,则使用if(输入过滤器)或of(输出过滤器)。需要注意的是,这两个名称具有欺骗性,实际上它们都将数据发送到打印机。不同过滤器配置的处理方式如下:-
若
printcap条目列出输入过滤器但未指定输出过滤器,设备将为每个作业打开一次,过滤器应将一个作业发送到打印机后退出。 -
若指定输出过滤器但未指定输入过滤器,
lpd将打开设备一次并调用过滤器程序一次,将队列中的所有作业作为一个大组发送。这种方式适用于连接时间较长的设备,但此类设备非常罕见。 - 若同时指定输入过滤器和输出过滤器,横幅页将发送到输出过滤器,即使关闭横幅页也会调用输出过滤器,输入过滤器用于处理作业的其余部分,这种组合选项较为复杂,应尽量避免。
-
若需要编写新的过滤器,建议使用输入过滤器,因为它们更容易调试。输入过滤器会接收许多参数,其中最有用的是用户名、发起主机和会计文件名称。若要为打印机进行会计记录,输入过滤器必须生成会计记录并追加到会计文件中;若要限制对打印机的访问,输入过滤器也必须处理该功能,因为
lpd没有内置的方法来阻止个别用户打印。以下是一个连接到本地串行线路的 PostScript 打印机的输入过滤器脚本示例:
-
若
#!/bin/bash
/usr/local/bin/textps $* | /usr/local/bin/psreverse
该脚本中,
textps
程序检查输入是否为 PostScript 格式,若不是则进行转换,并根据接收到的参数生成会计记录;
psreverse
程序用于反转页面顺序,使打印结果按正确顺序堆叠。
3.6 printcap 扩展
lpr/lpd 系统的一个优点是,它不介意用户为非标准的
printcap
变量提供值。当特定打印机需要比基本系统定义更多的配置信息时,可以在
printcap
中为打印机的过滤器添加额外变量。例如,网络打印机的输出过滤器可能需要知道设备的网络名称,打印机的
printcap
条目可能包含如下内容:
:nn=laser.colorado.edu:\
使用
printcap
扩展可将打印机的所有配置信息存储在一个方便的位置。若在
printcap
文件中看到未在
printcap
手册页中讨论的变量,可查看打印机过滤器的文档以确定其含义。
综上所述,BSD 打印系统虽然历史悠久,但通过合理配置和使用相关命令及文件,仍能有效地满足各种打印需求。在实际使用过程中,需要根据具体情况灵活运用这些知识,以确保打印系统的稳定运行。
4. 打印系统操作流程总结
为了更清晰地展示 BSD 打印系统的操作流程,下面通过 mermaid 格式的流程图进行总结:
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;
A([用户发起打印请求]):::startend --> B{指定打印机?}:::decision
B -- 是 --> C(使用 -P 参数指定目标打印机):::process
B -- 否 --> D{环境变量 PRINTER 定义?}:::decision
D -- 是 --> E(使用 PRINTER 变量值作为目标打印机):::process
D -- 否 --> F(使用系统默认打印机):::process
C --> G(lpr 查找 /etc/printcap 中的打印机信息):::process
E --> G
F --> G
G --> H(确定假脱机目录):::process
H --> I(创建控制文件和数据文件):::process
I --> J(lpr 通知 lpd 作业存在):::process
J --> K{打印机本地或远程?}:::decision
K -- 本地 --> L(lpd 检查守护进程并按需创建):::process
K -- 远程 --> M(lpd 连接远程 lpd 并传输文件):::process
M --> N(删除本地文件副本):::process
L --> O(按先进先出调度作业):::process
N --> O
O --> P{作业准备打印?}:::decision
P -- 是 --> Q(lpd 创建管道和过滤进程):::process
Q --> R(数据传输到打印机):::process
R --> S([打印完成]):::startend
这个流程图展示了从用户发起打印请求到最终打印完成的整个过程,涵盖了打印机选择、文件创建、作业调度和打印执行等关键步骤。
5. 常见问题及解决方法
5.1 打印机混淆问题
当创建的打印机使系统混淆时,可按以下步骤解决:
1. 停止打印假脱机程序:
$ sudo lpshut
- 尝试移除打印机:
$ sudo lpadmin -xhoser
若此步骤失败,可能是系统过于混乱。
3. 手动移除打印机相关的接口程序和假脱机目录:
$ sudo find /usr/spool/lp -name hoser | xargs rm -rf
- 重启打印假脱机程序:
$ sudo lpsched
- 检查打印系统状态:
$ sudo lpstat -t
5.2 删除活动作业导致系统卡住问题
在某些打印机上,尝试使用
lprm
删除活动作业可能会使系统卡住。此时可按以下步骤解决:
1. 使用
ps
命令识别过滤进程:
$ ps -ef | grep [过滤进程关键字]
- 手动终止过滤进程:
$ kill -9 [过滤进程 ID]
-
杀死并重启
lpd的主副本:
$ sudo killall lpd
$ sudo lpsched
- 手动从假脱机目录中删除作业:
$ sudo rm -rf /var/spool/lpd/[打印机名称]/*
5.3 lpc 命令失效问题
当打印系统出现小问题时,
lpc
可能会出现故障,甚至声称已解决问题但实际未执行任何操作。此时可尝试以下方法:
1. 手动检查和修改打印机状态文件,如
/var/spool/lpd/[打印机名称]/status
和
/var/spool/lpd/[打印机名称]/lock
。
2. 若问题严重,可尝试重启打印机设备和相关服务。
3. 若以上方法都无效,可考虑重启系统,但这是最后的手段。
6. 打印系统的安全与优化建议
6.1 安全方面
-
访问控制
:使用
/etc/hosts.lpd文件控制允许假脱机打印作业的主机,避免使用已弃用的/etc/hosts.equiv文件,以增强系统安全性。 - 过滤进程安全 :确保过滤进程的脚本和程序来源可靠,避免因过滤进程漏洞导致系统安全问题。
-
日志监控
:定期检查
lpd通过syslog记录的错误和打印请求日志,以及printcap中指定的错误日志文件,及时发现异常情况。
6.2 优化方面
-
文件大小限制
:根据实际需求合理设置
mx变量,避免因文件大小限制过严影响大作业的打印,或因限制过松导致系统资源过度占用。 - 过滤进程优化 :选择高效的过滤程序,或根据打印机特点编写自定义过滤脚本,提高打印作业处理效率。
-
假脱机目录管理
:定期清理假脱机目录中的过期文件,避免磁盘空间被大量占用。可使用定时任务(如
cron)实现自动清理:
0 2 * * * find /var/spool/lpd -type f -mtime +7 -exec rm -f {} \;
此定时任务将在每天凌晨 2 点删除假脱机目录中 7 天前的文件。
通过以上对 BSD 打印系统的架构、操作命令、
/etc/printcap
文件、常见问题解决方法以及安全优化建议的介绍,希望能帮助用户更好地理解和使用该打印系统,确保打印工作的顺利进行。在实际应用中,还需根据具体的硬件环境和业务需求进行灵活调整和优化。
超级会员免费看
7

被折叠的 条评论
为什么被折叠?



