FreeBSD handbook中文版 11 打印 (2)高级打印机设置 B.Header
发布时间:2006-10-14 8:46:23   收集提供:gaoqian
=============================================================
11.4 高级打印机设置
=============================================================

11.4.2 Header Pages 
如果你有很多使用者使用不同的打印机,那么你也许会觉得需要打印header pages。
Header pages,也称做banner 或burst pages,是用来辨认打出来的工作是属于谁的。通
常header pages 以粗体的大字,可能再加上外框打出来的,如此,使用者才能快速的在一堆
打出的结果找到属于自己的部分。不过header page 的缺点就是每个工作都会多使用一张纸
来打印header page。它的功用可能不会超过一分钟,而最后的下场都是丢进资源回收箱或是
垃圾筒。(不过header pages 是一份工作一张,而不是一个文件一张,所以纸张的浪费可能没
有你想象的那么严重)。
如果你的打印机可以直接打印纯文本的话,那么LPD 可以自动为你的输出加上header 
pages。如果你的打印机是PostScript 的,那么你将会需要额外的程序来产生header page;请
阅读在PostScript 打印机上打印Header Pages 这一节。
11.4.2.1 启用header pages 
在简单的打印机设置这节里,我们在/etc/printcap 文件里利用设置sh 以不打印header 
page (sh 即“suppress header”的意思)。如果某一台打印机要打印header pages 的话,那么只
要将sh 关键词删除就行了。
看起来是不是很简单? 
没错。你也许需要提供一个输出用过滤程序将初始化句柄送给打印机。下面是一个适用
于Hewlett Packard PCL 兼容打印机使用的输出用过滤程序: 
#!/bin/sh 

# hpof - Output filter for Hewlett Packard PCL-compatible printers 
# Installed in /usr/local/libexec/hpof 
printf “\033&k2G” || exit 2 
第39 页FreeBSD 使用手册
exec /usr/libexec/lpr/lpf 
我们用of 关键词来指定输出用过滤程序的路径。请阅读输出用的过滤程序这一节以
取得更多的信息。
下面是一个为我们先前提到的打印机teak 在teak 文件里设置要打印header pages 及输
出用过滤程序的例子: 

# /etc/printcap for host orchid 

teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\ 
:lp=/dev/lpt0:sd=/var/spool/lpd/teak:mx#0:\ 
:if=/usr/local/libexec/hpif:\ 
:vf=/usr/local/libexec/hpvf:\ 
:of=/usr/local/libexec/hpof: 
现在,当使用者用teak 打印时,它们每个工作都会有一张header page。如果使用者们
愿意花时间自己找出自己打出的东西,那么它们可以用lpr -h 命令设置不打出header pages; 
请阅读Header Page 参数以得知更多lpr 的参数。
注意: LPD 打完header page 后会送出form feed 字符。如果你的打印机送出纸张的命令
不是用这个字符,你可以在/etc/printcap 文件中用ff 关键词指定。
11.4.2.2 控制header pages 
如果选择要打印header pages,LPD 将会产生出long header,这将使用者、机器以及工
作名称以大字打印在一整页上。这里有一个例子(kelly 从rose 这台印机打印outline 这个工
作): 
k ll ll 
k l l 
k l l 
k k eeee l l y y 
k k e e l l y y 
k k eeeeee l l y y 
kk k e l l y y 
第40 页ll 
FreeBSD 使用手册
k k e e l l y yy 
k k eeee lll lll yyy y 

y y 
yyyy 
t l i 
t l 
oooo u u ttttt l ii n nnn eeee 
· o u u t l i nn n e e 
· o u u t l i n n eeeeee 
· o u u t l i n n e 
· o u uu t t l i n n e e 
oooo uuu u tt lll iii n n eeee 
r rrr oooo ssss eeee 
rr r o o s s e e 
r o o ss eeeeee 
r o o ss e 
r o o s s e e 
r oooo ssss eeee 
Job: outline 
Date: Sun Sep 17 11:04:58 1995 
LPD 在打印完这些后会送出form feed 字符,使得真正的打印工作会以新的一页开始打
印(除非你在/etc/printcap 文件为指定的打印机设置了sf (supress form feeds))。
第41 页FreeBSD 使用手册
如果你希望LPD 打印short header,那么在/etc/printcap 文件里使用sb (short banner) 
即可。这样打出来的header page 看起来会像下面这个样子: 
rose:kelly Job: outline Date: Sun Sep 17 11:07:51 1995 
LPD 的默认值是先打印header page 再打印工作。如果你想要调换顺序,那么在
/etc/printcap 里使用hl (header last) 即可。
11.4.2.3 统计打印
如果我们打印LPD 内建的header pages,那么在做统计时可能会遇到一个问题:header 
pages 得免费提供。为什么?因为只有控制打印header page 的输出用过滤程序可以在打印
header pages 时做打印统计,但是这个过滤程序却没有使用者及机器的资料或是一个统计资
料文件,所以无法向使用者收钱。我们也不能在文字过滤程序或是转换用过滤程序(这些过
滤程序可以直接取得使用者及机的资料)将统计结果都“多加上一页”,因为使用者可以用
lpr -h 命令设置不要打印header page,而你可能就向这些使用者多收了打印header page 的
费用。基本上,lpr -h 是许多较环保的使用者喜好的参数,你无法鼓励别人不去使用它。
而修改每个过滤程序使它们都可以打出header page 也是不可行的(虽然这么做就可以正
确的计费)。因为LPD 并不会把使用者有没有使用-h 的信息传给过滤程序,这么一来,即
使使用者下了lpr -h 的命令要求不打印header page,它仍然会因为得到一张header page 而
多收取了这个费用。
那么,有什么好办法呢? 
你可以: 
1. 接收LPD 的缺点,不收取打印header page 的费用。
2. 安装可以取代LPD 的程序,比如说LPRng 或是PLP。请参考标准Spooler 之外的选择
这一节所介绍其它可以替代LPD 的程序。
3. 撰写一个聪明的输出用过滤程序。在打印header page 及纯文本时,如果没有文字(输入
用)过滤程序,那么一般的输出用过滤程序只做初始化打印机以及一些简单的字符转换
工作。如果有设置文字过滤程序,那么LPD 只会用输出用过滤程序来做打印header page 
的工作。事实上,输出用过滤程序可以根据从LPD 产生的header page 资料来判断打印
工作的使用者及机器而加以收费。唯一的问题就是输出用过滤程序会无法取得记录使用
情况的记录文件(由af 关键词所指用的记录文件不会被传入),但是如果你的记录文件
是固定的,你可以这个文件直接设置在输出用过滤程序里。如果你考虑要用这种方式来
第42 页FreeBSD 使用手册
处理的话,那么在/etc/printcap 文件使用sh (short header) 关键词使判断的工作较容
易。上述的做法其实可能是很麻烦的,比较起来,使用者应该会较感谢让打印header page 
免费的管理者。
# Check arguments 

11.4.2.4 在postscript 打印机上打印header pages 
前面提到LPD 可以为打印机产生合适的纯文本header page,当然,因为PostScript 不
能直接打印纯文本,所以LPD 产生header page 的工能在PostScript 打印机上是用不到的— 
或是几乎用不到。
一个直接产生header page 的方法是让所有的转换用过滤程序及文字过滤程序产生
header page。过滤程序可以让使用者及机器的参数产生合适的header page。这个方法的缺点
就是即使使用者以lpr -h 的方式送出工作,它们仍然会得到header pages。
让我们来试试这个方法。下面的script 可以接收三个参数(使用者名称、机器名称以及
工作名称)并产生PostScript 打印机能打印的header page: 
#!/bin/sh 

# make-ps-header - make a PostScript header page on stdout 
# Installed in /usr/local/libexec/make-ps-header 


# These are PostScript units (72 to the inch). Modify for A4 or 
# whatever size paper you are using: 

page_width=612 
page_height=792 
border=72 

第43 页if [ $# -ne 3 ]; then 
exit 1 
fi 


user=$1 
host=$2 
job=$3 
date=‘date‘ 


exec cat <<EOF 
%!PS 


save 


$border $border moveto 
FreeBSD 使用手册
echo “Usage: ‘basename $0‘ <user> <host> <job>” 1>&2 
# Save these, mostly for readability in the PostScript, below. 
# Send the PostScript code to stdout. 
% Make sure we do not interfere with user’s job that will follow 
% Make a thick, unpleasant border around the edge of the paper. 
$page_width $border 2 mul sub 0 rlineto 
0 $page_height $border 2 mul sub rlineto 
第44 页% 

($user) show 


/y 200 def 
[ (Job:) (Host:) (Date:) ] { 
forall 
/y 200 def 
[ ($job) ($host) ($date) ] { 
FreeBSD 使用手册
currentscreen 3 -1 roll pop 100 3 1 roll setscreen 
$border 2 mul $page_width sub 0 rlineto closepath 
0.8 setgray 10 setlinewidth stroke 0 setgray 
% Display user’s login name, nice and large and prominent 
/Helvetica-Bold findfont 64 scalefont setfont 
$page_width ($user) stringwidth pop sub 2 div $page_height 200 sub moveto 
% Now show the boring particulars 
/Helvetica findfont 14 scalefont setfont 
200 y moveto show /y y 18 sub def } 
/Helvetica-Bold findfont 14 scalefont setfont 
270 y moveto show /y y 18 sub def 
} forall 

% That is it 

restore 
第45 页showpage 
EOF 
现在,每个转换用过滤程序以及文字过滤程序可以在打印前先呼叫这个script 打印出
FreeBSD 使用手册
header page 然后再打印工作的内容。我们修改之前提过的DVI 转换用过滤程序使它可以打
印header page: 
#!/bin/sh 

# psdf - DVI to PostScript printer filter 
# Installed in /usr/local/libexec/psdf 

# Invoked by lpd when user runs lpr -d 

orig_args=”$@” 
fail() { 
echo “$@” 1>&2 
exit 2 

while getopts “x:y:n:h:” option; do 
case $option in 
x|y) ;; # Ignore 
n) login=$OPTARG ;; 
h) host=$OPTARG ;; 
*) echo “LPD started ‘basename $0‘ wrong.” 1>&2 
exit 2 
;; 
esac 
done 
[ “$login” ] || fail “No login name” 
第46 页FreeBSD 使用手册
[ “$host” ] || fail “No host name” 
( /usr/local/libexec/make-ps-header $login $host “DVI File” 
/usr/local/bin/dvips -f ) | eval /usr/local/libexec/lprps $orig_args 
注意这个过滤程序如何从参数中取出使用者名称及机器名称。虽然这个过滤程序使用了
一些不同的参数(请阅读过滤程序的运作方式这一节),不过同样的技巧也可以应用在其它
不同的过滤程序上。
不过就如我们前面所提到的,这个方式虽然很简单,但是却让lpr 命令无法“不打印
header page”(即-h 参数无效)。如果使用者想要少花些钱(如果打印header pages 要收费的
话),那么它们将无法做到。因为每个过滤程序都会为每个工作打印header page。
如果要允许使用者可以自己选择是否打印header pager,你得使用统计打印Header 
Pages 这里介绍的技巧:写一个可以判断由LPD 产生的header page 的输出用过滤程序,并
由它输出PostScript 打印机可以处理的资料。这么一来,如果使用者以lpr -h 送出工作, 
LPD 将不会产生header page,且你的输出用过滤程序也不会。否则,你的输出用过滤程序
将要根据LPD 送出的资料然后以适当PostScript 码将header page 送给打印机处理。
如果你的PostScript 打印机是接在串行端口上,那么你可以使用lprps 里提供的输出用
过滤程序,psof,这个过滤程序会做上述的动作。注意, psof 这个过滤程序将不会为header 
pages 计费。
11.4.3 网络打印
FreeBSD 支持网络打印:将工作送给远程的打印机处理。网络打印有两大类型: 
1. 访问远程机器所安装的打印机。你在某一台机器上的串口或并口上接了一台打印机,然
后你设置LPD 使该台打印机可以接收网络上其它机器来使用。安装远程机器上的打印
机这一节将告诉你如何设置。
2. 使用直接接在网络上的打印机。这种打印机通常有一个额外的网络接口,以及(或是取
代掉原本的)传统的串口或并口。这种打印机可能有下列的工作方式: 
a) 它可能可以使用LPD 通讯协议直接接收从其它机器送来的工作。在这种情况下, 
就和一般的机器上面运行LPD 没什么不同。只要照着安装远程机器上的打印机
这一节里的设置即可。
第47 页FreeBSD 使用手册
b) 它可能支持网络数据传输接口。这种情况下,你得将打印机“连接”到网络上的某
一台机器上,然后让该机器负责接收工作以及在打印机间传送资料。请阅读使用
网络数据传输接口的打印机里关于这类打印机安装的建议。
11.4.3.1 安装远程机器上的打印机
LPD spooling 系统内建有将工作送给网络上其它执行LPD (或与LPD 兼容)程序的机器
打印的功能。这个功能让你可以将打印机安装在一台机器上,并让网络上其它的机器可以使
用。这功能也可以直接配合支持LPD 通讯协议的网络接口打印机使用。
要使用远程打印,首先,我们要先按照简单的打印机设置在打印机服务器上将打印机设
置好。然后也参考高级打印机设置设置你所需要的参数,确定你的打印机可以和LPD 配合
运作。最后要确定本机有在LPD 的已授权使用远程机器列表里(请阅读限制来自远程打印机
的工作这一节)。
如果你是使用兼容于LPD 通讯协议的网络接口打印机,那么下面讨论的打印机服务器
就是这台打印机,而打印机名称则是你为打印机设置的名称。请查阅随打印机或网络接口附
的手册来设置。
在其它要访问这些网络打印机的机器上,它们的/etc/printcap 设置文件得这么设置: 
1. 为你的网络打印机取个名字,为了简单起见,你可能会把打印机的名称及别名和打
印机服务器取一样的名字。
2. 明确地将lp 关键词设置为空(:lp=:)。
3. 建立一个spooling 目录同时将其位置以sd 关键词指定。LPD 在将工作送给打印机服
务器之前,会将这此工作放在这个目录下。
4. 将打印机服务器的名称以rm 关键词指定。
5. 将打印机服务器上的打印机名称用rp 关键词指定。
这些就足够了,你不需要在/etc/printcap 文件里将转换用的过滤程序列出,或是指定
纸张的大小。
下面是一个例子。rose 这台机器有两台打印机, 分别为bamboo 及rattan。我们要让
orchid 这台机器上的使用者可以使用这两台打印机。下面是orchid 这台机器上的
/etc/printcap 设置文件(回想要求打印Header Pages 这一节),这个文件里面已经设置teak 
这台打印机了,我们将要再加入两台连接在rose 这台机器上的网络打印机: 
第48 页# 



:if=/usr/local/libexec/ifhp:\ 
:vf=/usr/local/libexec/vfhp:\ 
:of=/usr/local/libexec/ofhp: 




FreeBSD 使用手册
# /etc/printcap for host orchid - added (remote) printers on rose 
# teak is local; it is connected directly to orchid: 
teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\ 
:lp=/dev/lpt0:sd=/var/spool/lpd/teak:mx#0:\ 
# rattan is connected to rose; send jobs for rattan to rose: 
rattan|line|diablo|lp|Diablo 630 Line Printer:\ 
:lp=:rm=rose:rp=rattan:sd=/var/spool/lpd/rattan: 
# bamboo is connected to rose as well: 
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ 
:lp=:rm=rose:rp=bamboo:sd=/var/spool/lpd/bamboo: 
然后,我们只要在orchid 建立spooling 目录: 
# mkdir -p /var/spool/lpd/rattan /var/spool/lpd/bamboo 
# chmod 770 /var/spool/lpd/rattan /var/spool/lpd/bamboo 
# chown daemon.daemon /var/spool/lpd/rattan /var/spool/lpd/bamboo 
现在,orchid 上的使用者可以将资料交由rattan 及bamboo 打印。举例来说,orchid 
上的使用者可以输入
第49 页FreeBSD 使用手册
% lpr -P bamboo -d sushi-review.dvi 
require ‘sys/socket.ph’; 
而orchid 上的LPD 系统将会将工作拷贝到/var/spool/lpd/bamboo spooling 目录下并
注明它是要打印DVI 的工作。当rose 这台机器上给bamboo 用的spooling 目录有空间时, 
这两个LPD 就会开始沟通将文件传给rose。然后这工作便进入rose 的队列直到它被打出为
止。而将DVI 转换成PostScript(因为bamboo 是PostScript 打印机)的工作将会在rose 这
台机器上执行。
11.4.3.2 使用网络数据传输接口的打印机
如果你为你的打印机安装了一块网卡接口,通常有两种情况:这个接口具有spooler 的
能力(较贵),或是只是拿来取代串口或并口(较便宜)。这一节要讨论的是如何使用较便宜的
那种方式。如果你是选用较贵的接口,请参考前一节:安装远程机器上的打印机。
/etc/printcap 设置文件里允许你指定使用串口或是并口,以及(如果你使用串行端口) 
使用什么传输速率、哪一种流量控制、是否需要延长转换换行字符等等。但是,却没有一种
方法可以指定以TCP/IP 或是其它的网络连接端口与打印机连接。
如果要将资料送给这种网络打印机,你需要一种可以被文字及转换用过滤过程调用的数
据传输程序。这里有一个例子:netprint 这个script 可以读取标准输入的资料并将这些资料
送到用网络连接的打印机。我们在netprint 命令的第一个参数传入该打印机的机器名称, 
并使用第二个参数传送通讯端口的号码。注意,这个程序只支持单向的传输(即从FreeBSD 
到打印机),而很多网络打印机都支持双向传输,而你可能会想要使用这些功能(如取得打印
机状态、统计打印情况等)。
#!/usr/bin/perl 

# netprint - Text filter for printer attached to network 
# Installed in /usr/local/libexec/netprint 

$#ARGV eq 1 || die “Usage: $0 <printer-hostname> <port-number>”; 
$printer_host = $ARGV[0]; 
$printer_port = $ARGV[1]; 
第50 页FreeBSD 使用手册
($ignore, $ignore, $protocol) = getprotobyname(‘tcp’); 
($ignore, $ignore, $ignore, $ignore, $address) 
= gethostbyname($printer_host); 
$sockaddr = pack(‘S n a4 x8’, &AF_INET, $printer_port, $address); 
socket(PRINTER, &PF_INET, &SOCK_STREAM, $protocol) 
|| die “Can’t create TCP/IP stream socket: $!”; 
connect(PRINTER, $sockaddr) || die “Can’t contact $printer_host: $!”; 
while (<STDIN>) { print PRINTER; } 
exit 0; 
然后我们可以在不同的过滤程序里使用这个script。假设我们有一台连接在网络上的
Diablo 750-N 行式打印机。这台打印机用通讯端口5100 接收资料。这台打印机的名字叫做
scrivener。以下是给这打印机使用的文字过滤程序: 
#!/bin/sh 

# diablo-if-net - Text filter for Diablo printer ‘scrivener’ listening 
# on port 5100. Installed in /usr/local/libexec/diablo-if-net 

exec /usr/libexec/lpr/lpf “$@” | /usr/local/libexec/netprint scrivener 5100 
11.4.4 限制打印机的使用
这一节讨论如何限制打印机的使用。LPD 系统可以限制本机及远程使用打印机的使用
者,设置它们是否可以打印多份、打印工作大小的限制以及打印机队列的上限。
11.4.4.1 限制打印多份
LPD 系统让使用者可以很容易地将一个文件打印多份。举例来说,使用者只要以lpr -#5 
命令就可以将这个工作里的每个文件都打印5 份。不论这些文件里是什么东西。
如果你觉得打印多份会造成打印机的损坏,你可以在/etc/printcap 设置文件里以sc 
关键词关闭lpr 命令的-# 参数。如此,当使用者尝试以-# 参数送出工作时,它们将看到: 
lpr: multiple copies are not allowed 
注意,如果你允许从远程使用你的打印机(请阅读安装远程机器上的打印机这一节),那
第51 页FreeBSD 使用手册
么你得在远程机器上的/etc/printcap 文件里也设置sc 关键词,否则使用者仍然可以从远
程的机器上要求打印多份。
这里有一个例子。这是rose 这台机器的/etc/printcap 设置文件。rattan 这台打印机
十分强大,所以我们允许在它上面打印多份,但是bamboo 这台激光打印机有点弱小,因此
我们在它上面设置了sc 关键词,不允许打印多份: 

# /etc/printcap for host rose - restrict multiple copies on bamboo 

rattan|line|diablo|lp|Diablo 630 Line Printer:\ 
:sh:sd=/var/spool/lpd/rattan:\ 
:lp=/dev/lpt0:\ 
:if=/usr/local/libexec/if-simple: 
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ 
:sh:sd=/var/spool/lpd/bamboo:sc:\ 
:lp=/dev/ttyd5:fs#0x82000e1:xs#0x820:rw:\ 
:if=/usr/local/libexec/psif:\ 
:df=/usr/local/libexec/psdf: 
然后,我们也需要在orchid 这台机器上的/etc/printcap 设置文件里为网络打印机加
上sc 关键词(同时,我们也不允许使用者用teak 这台打印机来做打印多份的工作): 

# /etc/printcap for host orchid - no multiple copies for local 
# printer teak or remote printer bamboo 
teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\ 
:lp=/dev/lpt0:sd=/var/spool/lpd/teak:mx#0:sc:\ 
:if=/usr/local/libexec/ifhp:\ 
:vf=/usr/local/libexec/vfhp:\ 
:of=/usr/local/libexec/ofhp: 
rattan|line|diablo|lp|Diablo 630 Line Printer:\ 
第52 页FreeBSD 使用手册
:lp=:rm=rose:rp=rattan:sd=/var/spool/lpd/rattan: 
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ 
:lp=:rm=rose:rp=bamboo:sd=/var/spool/lpd/bamboo:sc: 
使用sc 关键词之后,我们可以防止使用者使用lpr -#,但是无法防止使用者执行多次
lpr,或是在一个工作里将同样的文件送好几次,像这样: 
:lp=/dev/ttyd5:fs#0x82000e1:xs#0x820:rw:\ 
:if=/usr/local/libexec/psif:\ 
% lpr forsale.sign forsale.sign forsale.sign forsale.sign forsale.sign 
有很多方式可以防止这个滥用(包括忽略它),你可以自己尝试看看。
11.4.4.2 限制访问打印机
你可以使用UNIX 下群组的机制及/etc/printcap 设置文件的rg 关键词来控制谁可以
使用哪台打印机。只要将允许访问打印机的使用者放在某一个群组中,然后用rg 关键词指
定这个群组名称即可。
在这个群组之外的使用者(包括root)将会看到“lpr: Not a member of the restricted 
group” 如果它们尝试使用被限制使用的打印机。和sc (禁止打印多份)一样,如果你觉得
需要限制远程使用者使用你的打印机,你也得在远程机器上的设置文件里设置rg 关键词。
(请阅读安装远程机器上的打印机这一节)。
我们将让所有人都可以使用rattan 这台打印机,但是只有在artists 群组里的人可以
使用bamboo 这台打印机。下面是rose 这台机器的/etc/printcap 设置文件: 

# /etc/printcap for host rose - restricted group for bamboo 

rattan|line|diablo|lp|Diablo 630 Line Printer:\ 
:sh:sd=/var/spool/lpd/rattan:\ 
:lp=/dev/lpt0:\ 
:if=/usr/local/libexec/if-simple: 
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ 
:sh:sd=/var/spool/lpd/bamboo:sc:rg=artists:\ 
第53 页FreeBSD 使用手册
:df=/usr/local/libexec/psdf: 
我们在这里不修改其它的/etc/printcap 设置文件(比如说orchid 机器上的)。这么一来, 
所有orchid 机器上的使用者都可以用bamboo 来打印。通常这种情况是因为orchid 上的使
用者不多且希望它们都可以访问打印机。
注意: 每个打印机只能使用一个群组名称来做限制。
11.4.4.3 限制提交工作的大小
如果你有很多使用者在使用打印机,你也许会想要设置使用者能传过来打印的文件大小
限制。毕竟,在我们spooling 目录所在的文件系统空间有限,而你得确保有足够的空间给其
它的使用者在打印时用。
LPD 让你可以用mx 关键词限制一个打印工作中的文件大小,以BUFSIZ 区块为单位, 
每一块大小为1024 字节。如果你将值设置为0,那么表示对文件大小没有限制。如果没有
使用mx 关键词的话,那么默认的大小是1000 个区块。
注意: 这些限制将会套用在打印工作中的文件,而不是整个打印工作的大小。
LPD 不会拒绝接收一个文件大小超过你为打印机设置上限的文件。而会尽量将该文件
小于上限的资料放入缓存并打出,而超出上限的资料则取消。这是不是一个正确的处理方式
还有待争议。
让我们为我们举例的打印机rattan 和bamboo 设置上限。既然这些艺术家的PostScript 
文件都蛮大的,我们将上限设置为5 MB。而我们在纯文本行式打印机上不做任何限制: 

# /etc/printcap for host rose 


# No limit on job size: 

rattan|line|diablo|lp|Diablo 630 Line Printer:\ 
:sh:mx#0:sd=/var/spool/lpd/rattan:\ 
:lp=/dev/lpt0:\ 
:if=/usr/local/libexec/if-simple: 
第54 页FreeBSD 使用手册

# Limit of five megabytes: 

bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ 
:sh:sd=/var/spool/lpd/bamboo:sc:rg=artists:mx#5000:\ 
:lp=/dev/ttyd5:fs#0x82000e1:xs#0x820:rw:\ 
:if=/usr/local/libexec/psif:\ 
:df=/usr/local/libexec/psdf: 
同样的,这些限制仅对本机使用者有效。如果有人通过网络使用这些打印机,那么这些
设置是不会产生效用的。你得在远程的/etc/printcap 设置文件里也设置mx 关键词才行。
请阅读安装远程机器上的打印机这一节以取得更多关于远程打印的信息。
有另一种更好的方法来限定远程打印机传送过来的打印工作大小。请阅读限制来自远
程打印机的工作这一节的说明。
11.4.4.4 限制远程打印机的工作
LPD spooling 系统提供好几种方法来限制从远程传过来的打印工作: 
限制机器来源
你可以用/etc/hosts.equiv 和/etc/hosts.lpd 这两个文件来限制LPD 接收哪些远
程机器的要求。LPD 会检查传出要求的机器是否列在这些文件中。如果没有的话, 
那么LPD 会拒绝这些要求。
这两个文件的格式很简单: 一行写一台机器名称即可。不过你得注意
/etc/hosts.equiv 这个文件也被ruserok 通讯协议所使用,因此会影响到像rsh 和rcp 
等程序,所以你得小心的设置。
举例来说,rose 的/etc/hosts.lpd 设置文件是下面这样的: 
orchid 
violet 
madrigal.fishbaum.de 
意思就是rose 这台机器将会接收从orchid、violet、以及madrigal.fishbaum.de 
这三台机器送过来的要求。如果其它的机器想要来使用rose 这机器的LPD,那么
第55 页FreeBSD 使用手册
LPD 将会拒绝它们。
限制大小
你可以控制有多少空间得保留在spooling 目录所在的文件系统上。只要在本机打印
机的spooling 目录上建立一个叫做minfree 的文件就行了。而这个文件的内容是一
个数字记录。当文件系统至少还有多少磁盘区块(512 字节)的剩余空间时,才接收远
程传来的打印工作。
这可以确保远程的使用者不会将你的文件系统空间用完。而这块空间可以给本机使
用者一些保障:它们在文件系统剩余空间小于minfree 文件里所指定的大小时,还
是可以将打印工作送进打印队列。
举例来说,我们如果想要为bamboo 设置minfree 文件。我们得先查看/etc/printcap 
文件以找出这台打印机spooling 目录的位置。下面是关于bamboo 的设置: 
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ 
:sh:sd=/var/spool/lpd/bamboo:sc:rg=artists:mx#5000:\ 
:lp=/dev/ttyd5:fs#0x82000e1:xs#0x820:rw:mx#5000:\ 
:if=/usr/local/libexec/psif:\ 
:df=/usr/local/libexec/psdf: 
Spooling 的目录是以sd 关键词设置。我们可以设置当那个文件系统的剩余空间在3 
MB(即6144 个磁盘区块)以上时,就接收远程来的打印工作: 
# echo 6144 > /var/spool/lpd/bamboo/minfree 
限制使用者
你可以在/etc/printcap 里用rs 关键词设置哪些远程使用者可以使用本机的打印
机。当你为本机的打印机使用了rs 之后,LPD 只有在远程的使用者名称在本机上
也有同样的使用者名称时,才会接收这个打印工作。否则LPD 会拒绝接收该工作。
这个功能(举例来说)在不同部门共享打印机时,另一个部门的某些使用者需要用到
打印机。你只要在你的机器上为这些使用者建立帐户,那么它们就可以在它们的部
门里使用你的打印机。如果你只想要让它们使用你的打印机而不能使用你机器上的
其它资源的话,那么你只要为它们建立“token”帐户,即没有home 目录也没有可
用的shell 像/usr/bin/false 这样子即可。
11.4.5 统计打印机的使用情况
第56 页FreeBSD 使用手册
纸张及墨水都是要钱的,管理也是需要花钱的—打印机常常因为运转负荷过重而发生故
障,为何不向使用者收取打印的费用呢?如果你打算收钱,你必需检查你的打印机、制定使
用方式、以及制定打印一张纸(一英尺、一公尺,等等)要收多少钱。那么你要如何统计打
印了多少呢? 
不幸的是,LPD spooling 系统在这方面的帮助并不大。统计的方法与你所使用的打印机、
打印的格式,以及其它你想收费的项目有关。
如果要统计这个功能,你得修改打印机的文字过滤程序(以对打印纯文本收费) 或转换
用过滤程序(以对列其它的格式收费),以计算打印的张数或是如果无法计算的话,则向打印
机查询打出的张数。你没有办法用输出用的过滤程序来做统计的工作。请阅读过滤程序这
一节的说明。
一般来说,有两种统计的方式: 
1. 定期统计是较常见的方式,也许是因为它比较容易。当有人打印工作时,过滤程序将使
用者名称、机器以及打印的张数记录到一个记录文件里。每个月、每个学期、每年或是
任何一段时间,你可以根据这些不同打印机的记录文件来结算每个使用者所需的费用, 
并向它们收费。然后你就可以删除这些记录再重新开始计算。
2. 实时统计是较少用的方式,也许是因为它比较难设置。这个方式让过滤程序马上计算出
使用者打印的数目并向它们收费。就像磁盘配额一样,这个统计是马上生效的。你可以
提供一种方式供使用者检查或调整它们的“打印配额”,以防止某些使用者打印过量。
但是这种方法需要一些维护数据库的程序代码以记录使用者使用的配额。
LPD spooling 系统可以很容易地支持上述两种情况:因为(大部分的时候)你得提供你的
过滤程序以及计算的程序。这有一个好处就是你可以很有弹性地调整计算的方法。举例来说, 
不管你是使用定期统计还是实时统计,你可以选择要记录哪些信息:使用者名称、机器名称、
工作型态、打印的张数、纸张的大小、打印工作所花的时间等等。而你只要调整你的过滤程
序就可以了。
11.4.5.1 快速设置打印机的使用统计
FreeBSD 提供两个程序让你可以快速设置好定期统计。它们是在文字过滤程序:lpf 那
节所提到的lpf 以及pac,一个可以从打印机打印记录文件读取并统计资料的程序。
在前几节(过滤程序的运作方式),我们曾提到LPD 会将记录文件名以参数的方式传给文字
第57 页FreeBSD 使用手册
过滤程序和转换用过滤程序。如此过滤程序就知道可以将计算结果记录到哪个文件里。这个
文件名在/etc/printcap 文件里是以af 关键词指定,如果不是以绝对路径来指定的话,那
么这个文件将会放在相对应于spooling 目录的位置下。
LPD 会将纸张的宽度及高度传给lpf 命令(由pw 及pl 关键词所指定)。lpf 使用这些参
数来计算将会用到多少张纸。而将文件送给打印机打印后,它会将这些结果记录在记录文件
里。这些结果看起来是像这个样子的: 
2.00 rose:andy 
3.00 rose:kelly 
3.00 orchid:mary 
5.00 orchid:mary 
2.00 orchid:zhang 
由于lpf 没有使用文件锁定的相关操作,因此每台打印机都要有独立的统计记录文件, 
否则两个lpf 同时对同一个文件做写入的动作可能会使彼此的记录都不正确。而最简单的解
决方式就是让不同的打印机在/etc/printcap 设置文件里以af=acct 关键词指定不同的统计
记录文件。这些acct 文件将会分别放置在不同的spooling 目录下。
当你准备要向使用者收钱时,执行pac 这个程序。只要将目录切换到你想收钱的打印机
spooling 目录下,然后打pac。你将会得到一份像下列的收费摘要: 
Login pages/feet runs price 
orchid:kelly 5.00 1 $ 0.10 
orchid:mary 31.00 3 $ 0.62 
orchid:zhang 9.00 1 $ 0.18 
rose:andy 2.00 1 $ 0.04 
rose:kelly 177.00 104 $ 3.54 
rose:mary 87.00 32 $ 1.74 
rose:root 26.00 12 $ 0.52 
total 337.00 154 $ 6.74 
pac 有下列参数可以使用: 
1. Pprinter 
指定要处理哪一台printer 的统计资料。这个参数只有在/etc/printcap 文件里
第58 页FreeBSD 使用手册
的af 关键词是使用绝对路径时才有用。
2. c 
将输出的结果以费用排序,而不是以使用者的名字排序。
3. m 
忽略记录文件里的机器名称。如果使用这个参数,那么alpha 机器上的使用者smith 
和gamma 机器上的使用者smith 将会被视为同一个使用者。否则,它们会被视为不
同的使用者。
5. r 
6. s 
4. pprice 
计算时以每一页收取price 元计算,而不是使用/etc/printcap 里的pc 所指定的
费率或2 分美金(默认的费率)计算。你可以用浮点数来指定price 这个参数。
颠倒排列的顺序。
将计算的结果写到一个摘要文件里,同时清除统计记录文件的内容。
name ... 
只为指定的使用者names 做统计。
在pac 默认的输出里,你可以看到不同机器上不同使用者所打印的张数。如果你不在乎
使用者使用的机器(比如说使用者可以用任何机器),那么你可以用pac -m 产生下列的摘要
输出: 
Login pages/feet runs price 
andy 2.00 1 $ 0.04 
kelly 182.00 105 $ 3.64 
mary 118.00 35 $ 2.36 
root 26.00 12 $ 0.52 
zhang 9.00 1 $ 0.18 
total 337.00 154 $ 6.74 
pac 计算应缴纳的金额时,会使用/etc/printcap 文件里pc 关键词所指定的费率(默认
值为2 美分)。即每一页或是每一英尺你想要收多少钱就是在这里指定。你可以在执行pac 
第59 页FreeBSD 使用手册
时以参数-p 改变这个费率。不过-p 的单位是元,而不是分,举例来说, 
# pac -p1.50 
将使打印每一页以1 元5 分计算。你可以用这个参数调整你所收取的费用。
最后,如果你使用pac -s 将会把这些摘要信息存在一个文件里,这个文件的名称会和
统计记录文件相同,不过文件名后面会再加上_sum。然后它会将统计记录文件清空。如果你
再执行一次pac 命令,那么它会先读取之前统计的结果,然后再加上从统计记录文件里所计
算出来的结果。
11.4.5.2 如何统计有几页被打印? 
为了要能精确统计打印的情况,你必须要能得知每个工作用了几张纸。这是打印机使用
情况统计最基本的问题。
对于纯文本的工作,这个问题并不难解决:你只要统计这个工作里有几行并知道你的打
印机一张纸可以印几行就行了。别忘了考虑倒退字符以及因为同一行字符过多而换行的情
况。
lpf 文字过滤程序(在文字过滤程序:lpf 这一节里介绍的)在做统计时会将这些情况都
考虑进去。如果你要自己撰写有统计功能的文字过滤程序,你可以参考lpf 的原始码。
那么要如何统计其它格式的文件呢? 
对于DVI 转成LaserJet 或DVI 转成PostScript,你可以让你的过滤程序处理由dvilj 或
dvips 的输出以判断一共转换了几页。你也许可以用类似的方式来处理其它的文件格式以转
换程序。
但是这样的方法所计算出来的和打印机实际打出来的可能不大相同,举例来说,打印机
可能会卡纸、用完色带碳粉或墨水、或是其它的故障—而这些使用者仍然需要付费。
那么,我该怎么办? 
只有一种方式肯定是可以做出精确的统计。买一台可以告诉你一共打出多少纸张的打印
机,同时将它接在串行端口或是以网络连接。几乎所有的PostScript 打印机都支持这个功能。
当然其它种类的打印机也有支持的(如网络Imagen 激光打印机)。为这些打印机修改你的过
滤程序,使得过滤程序在打印完成后可以从打印机取得这些信息,同时也只根据这些记录来
做统计。不需要做行数统计或是其它可能发生错误的计算方式。当然,你也可以大方的让所
有的纸张打印输出都免费。
第60 页FreeBSD 使用手册

 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50