Linux 版 (精华区)
发信人: clx (楚留香), 信区: Unix
标 题: Printing HOW-TO
发信站: 紫 丁 香 (Sat Jun 27 13:43:58 1998), 转信
Printing HOW-TO
这是 Linux Printing HOW-TO, 一份关於如何在 Linux 下预视, 列印, 传真
的文件.
1. Intro 前言
因为此文件己完全重写过, 有很多前版的资讯都已经失去, 这是就是为何前
版的文件那麽巨大的原因. 如果你在这份文件找不到你要的答案, 建议你可以
a) 到 PHT 的 homepage 找前一版的 printing how-to
<http://www.picante.com/~gtaylor/pht/>
b) 写信给我并说明发生了什麽在这里找不到答案的事 !
1.1 History
这是第三版, 也就是第三次完全重写过的 Printing HOW-TO, 关於 PHT 的
各版演进历程如下:
1. 我在 comp.os.linux 写了 printing hot-to 以回答各式各样关於列印方面的
问题! How-to 的前身为 FAQ 之类的集合! 这版为 ascii 格式.
2. 在加入 HOE-TO 专案後, Printing HOW-TO 加入了 Brian McCauley
<B.A.McCaulaey@bham.ac.uk> 的 Lpd FAQ; 我们又继续共同创作 PHT 两年左
右. 我们也同时和 Karl Auer<Karl.Auer@anu.edu.au> 一起工作. 这版的 PHT
文件格式有 TeXinfo, PS, HTML, Ascii, 和 Info.
3. 在一年後 PHT 文件已过时并难已继续维护的情况下, 我们决定重写.
此版的 PHT 为 Linuxdoc-SGML 格式.
2. How to print 如何列印
如果你已经设定好你的印表机, 或是你的系统管理者(厂商)已经帮你设好,
那麽你所要知道的就是 lpr 指令的使用了. 在 Printing Usage HOWTO
<http://sunsite.unc.edu/mdw/HOWTO/Printing-Usage-HOWTO.html> 包含这些指令
的说明, 并有一些你该知道的小技巧.
3. Kernel printer devices 核心印表装置
3.1 the lp devices lp 装置
假设你在编译核心已经把 lp 装置编译进去的话, 可以用 cat /proc/devices 看
看是否包含 lp. 在 /dev 下应有 lp0. lp1, lp2 等装置名, 这些并不是动态指定的,
每个装置都有自己的 I/O 位址, 这表示你的第一台印表机可能是 lp0 或 lp1,
要看你的硬体而定, 两个都试试看 ;)
lpip 不能和 lp 同时执行.
有一个叫 tunelp 的小工具可以让你调整 lp 装置的 interrupt usage, polling rate,
和其它功能.
当你用 module (1.3.X 的 kernel 中) 时, 可以在 insmod 时加入一些参数来指
定 io 位址和中断值. 参数是 io=x,y,z 和 irq=x,y,z . x,y,z 由你指定. 请 man
insmod 以得知更多关於 insmod 的用法.
3.2 Serial devices 序列装置
序列装置在 Linux 下通常叫做 /dev/ttyS1 之类的, 工具 stty 将使你以互动的
方式查看(view) 并设定序列埠; setserial 可让你控制一些非标准埠的外部属性并
设定 IRQs 和 I/O 位址. 更多关於linux 下序列埠的讨论可以在 Serial-HOWTO
中找到 <http://sunsite.unc.edu/mdw/HOWTO/Serial-HOWTO.html>
4. How it works, basic 基本运作方式
在使印表运作正常前, 你必须□解 lpd 系统是如何运作的.
Lpd 是 Line Printer Daemon 的总称, 其内文(context) 依 deamon 和程式使用
spooling 的不同而有所差异. 包括了:
lpd : the spooling deamon. 一个负责控制机器. 另外, 在每一台印表机印表
时也都有一个 lpd.
lpr : 使用者下的 spooling 指令. Lpr 与 lpd 联系并插入一个新的印表工作
到 spool 中.
lpq : 列出印表伫列(print queue) 中的工作.
lpc : Lpd 系统的控制指令. 可用来 stop, start, recorder 你在 lpc 中看到的
工作.
lprm: 可从 spool 中移除印表工作.
那麽它们如何正适当的时候工作呢 ? 在开机的过程中, lpd 就开始执行, 它会
扫描 /etc/printcap 以得知那一台印表机由那一个 spool 所管. 每当有人执行 lpr
时, lpr 就会经由 /dev/printer 的 socket 来和 lpd 联系, 并将待印档案和谁要
列印, 如何列印的资讯交给 lpd. lpd 就会适当地将档案印出.
lp 系统原本是设计时大部分的人只需要印 ascii 的档 (line printer). 现在虽有
所改变, 但我们只要加上一些 script 就可以使 lpd 将目前的印表处理的很好,
例如: PostScript, text , dvi...
5. How to set things up, basic 基本设定
5.1 传统的 lpd 设定
设定的结果至少要让印表机能排伫列, 能列印. 如果你对 lp 不是很懂的话,
这些设定并不能让你印出漂漂的文件来. 但无论如何, 这是第一步, 所以, 看下
去吧 !
最基本的, 将伫列加入 lpd 中, 你必须在 /etc/printcap 中登录, 并在
/var/spool/lpd 中加入一个新的目录.
在 /etc/printcap 的登录如下:
# LOCAL djet500
lp|dj|deskjet:\
:sd=/var/spool/lpd/dj:\
:mx#0:\
:lp=/dev/lp0:\
:sh:
上面这一段定义了一个叫 lp, dj 或是 deskjet 的 spool, spool 的路径为
/var/spool/lpd/dj , 由 /dev/lp0 印出的东东并没有预设的列印最大值的限制, 而且
不能在列印工作的前端加上标题(像是谁印的...之类). 现在先去看看 printcap
的 man page 吧 !
上面这一段看起来似乎很简单, 但这里面却有阻碍. 除非我送了一个 DeskJet
500 认识的档案, 否则 DeskJet 将印出一堆奇怪的文字来. 例如: 送一个原始的
unix text 档到 deskjet中, 虽然每一行都有换行, 但我得到的结果将为:
This is line one.
This is line two.
This is line three.
若将 PostScript 的档送往这个 spool, 将得到很漂漂的, 楼梯状但无用的输出.
很显然的, 我们需要更多的设定, 这就是过滤(filtering)的目的. 如果你有仔细
地看 printcap 的 man page 的话, 你应该注意到了 spool 的 if 和 of 属性 !
嗯, if 属性(或说是输入过滤器) 就是我们要的啦 !
如果我们要写一个在新一行前加入换行符号的 shell script, 以消除楼梯形状的
话, 我们可以在 printcap 中加入 if 如下:
lp|dj|deskjet:\
:sd=/var/spool/lpd/dj:\
:mx#0:\
:lp=/dev/lp0:\
:if=/var/spool/lpd/dj/filter:\
:sh:
一个简单的过滤 script 如下:
#!perl
while(<STDIN>){printf "$_\r";};
如果我们照上面做了以後, 就可以正常列印一般的 unix text 档了.(有4千万个
方式可写出更好的过滤器, 但太难去举例了, 你不妨自己去试著写写看)
但问题是只能印文字档真是不爽, 最好是可以出 PostScript 或其它格式, 甚至
图形才能满足我. 那好吧, 其实也很简单, 在上面的方法再加上延伸的 linefeed-
fixing filter 就行了. 如果你能写一个可接受任何档案格式输入, 并可由 DeskJet
正常输出的 script, 那麽你的确是一个聪明的 spooler !
像这种 filter 叫做 magic filter. 这并不困难, 除非你真的要印很怪的东东. 因
为网路上已经有人帮你写好罗 !
5.2 File Permissions 档案权限
我开了张表以列出在我自己系统上一些有趣的档案及其权限. 理论上最好只
要用到 SGID 而不要用 SUID, 有一狗票的方式可做到, 但我的系统将真实情
形揭露如下(Quite frankly, if your vendor can't even ship a working lpd you're in for a
rough ride):
-r-sr-sr-x 1 root lp /usr/bin/lpr*
-r-sr-sr-x 1 root lp /usr/bin/lprm*
-rwxr--r-- 1 root root /usr/sbin/lpd*
-r-xr-sr-x 1 root lp /usr/sbin/lpc*
drwxrwxr-x 4 root lp /var/spool/lpd/
drwxr-xr-x 2 root lp /var/spool/lpd/lp/
Lpd 目前是以 root 的身份在 run, 也就是如此它才可以使用低号码的服务埠
(service port). 看起来它好像可以在 binding 之後变成 lp.lp 之类的 UID, 可是
我想这是行不通的, 真令人失望.
6. How to obtain an appropriate magic filter 如何获得一个适当的 magic filter
6.1 APS Filter
Andreas Klemm 的 aps filter 是最好的 magic tilter 其中之一, The Linux
Software Map entry goes something like this:
Begin3
Title: apsfilter
Version: 4.9.1
Entered-date: Montag, 10. Juli 1995, 21:22:35 Uhr MET DST
Description: magicfilter for lpd with auto filetype detection
Keywords: lpd magicfilter aps apsfilter
Author: andreas@knobel.GUN.de (Andreas Klemm)
Maintained-by: sledge@hammer.oche.de (Thomas Bueschgens)
andreas@knobel.GUN.de (Andreas Klemm)
Primary-site: sunsite.unc.edu
/pub/Linux/system/Printing/
211KB aps-491.tgz
Original-site: ftp-i2.informatik.rwth-aachen.de
/pub/Linux/pak/APSfilter/aps-491.tgz
Platforms: C-Compiler, gs Postscript emulator, pbmutils
Copying-policy: GPL
End
APS filter 为列表伫列为了一个 if filter, 使你的印表机指令集可以解译很多
常见的档案格式. 例如: text, PostScript, dvi, gif, and others.
6.2 Magic-filter
B.A.McCawley 的 magic-filter package 做的事与 APSfilter 很像, 但它是用
bash 写的, 你可能比较容易把它改成适合你用的.The LSM entry:
Version: 0.4
Description: Bash scripts to simplify the task of configuring lpd to
auto-detect file types using /etc/magic. (As advertised in the
printing-HOWTO).
This package uses existing filters so it only prints file types for
which one already has filters (or compressed versions
thereof). Alterative magic filter approches are described in the
printing-HOWTO.
Keywords: lpd, /etc/magic, printing, filter
Author: B.A.McCauley@bham.ac.uk (Brian McCauley)
Maintained-by: B.A.McCauley@bham.ac.uk
Primary-site: tsx-11.mit.edu pub/linux/sources/usr.bin
magic-filter-0.4.tar.gz 5709
Copying-policy: GNU GPL
7. Serial printers under lpd lpd 下的序列印表机
7.1 Setting up in printcap
Lpd 在 /etc/printcap 中提供了 5 个属性让你控制序列印表机的设定. 看看
printcap man page 中关於 br#, fc#, xc#, fs#, xs# 的部分. The last four of these
attributes are bitmaps indicating the settings for use the port. br# 属性控制 baud rate,
例: `br#9600'.
将 stty 的设定转成 printcap flag 的设定很容易, 如果你有需要的话, 请看
stty 的 man page.
利用 stty 来设定印表机埠的方式, 现在我们可以用 cat 来将档案印出. 下面
是我用 'stty -a' 所显 示我的印表机埠的状态:
dina:/usr/users/andy/work/lpd/lpd# stty -a < /dev/ttyS2
speed 9600 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
lnext = ^V; min = 1; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr
-igncr -icrnl ixon -ixoff -iuclc -ixany -imaxbel
-opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0
bs0 vt0 ff0
-isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase
-tostop -echoprt -echoctl -echoke
和开机时 initialized 的方式不同的地方仅在 -clocal, -crtscts, 和 ixon. 你的埠
可能和我的不太一样, 端看你的印表机用什麽样的 flow control 而定.
现在你已设好你的 stty 了, 在我的状态下, 我用 'cat file > /dev/ttyS2' 将档案
送到印表机. 看一下 /usr/src/linux/include/linux/termios.h, 这里面包含了一些
#defines 和 structs(你该将此档印出来 (你正如此做, 对吧?)看看), 请找到下面
这一段:
/* c_cflag bit meaning */
#define CBAUD 0000017
This section lists the meaning of the fc# and fs# bits. You will notice that the names
there (after the baud rates) match up with one of the lines of stty output. Didn't I say this
was going to be easy?
Note which of those settings are preceded with a - in your stty output. Sum up all
those numbers (they are octal). This represents the bits you want to clear, so the result is
your fc# capability. Of course, remember that you will be setting bits directly after you
clear, so you can just use `fc#0177777' (I do).
Now do the same for those settings (listed in this section) which do not have a - before
them in your stty output. In my example the important ones are CS8 (0000060), HUPCL
(0002000), and CREAD (0000200). Also note the flags for your baud rate (mine is
0000015). Add those all up, and in my example you get 0002275. This goes in your fs#
capability (`fs#02275' works fine in my example).
Do the same with set and clear for the next section of the include file, "c_lflag bits". In
my case I didn't have to set anything, so I just use `xc#0157777' and `xs#0'.
7.2 Older serial printers that drop characters
Jon Luckey points out that some older serial printers with ten-cent serial interfaces and
small buffers really mean stop when they say so with flow control. He found that
disabling the FIFO in his Linux box's 16550 serial port with setserial corrected the
problem of dropped characters.
8. Vendor Solutions
This section is, by definition, incomplete. Feel free to send in details of your favourite
distribution.
8.1 RedHat 2.x
RedHat has a GUI printer administration tool which can add remote printers and
printers on local devices. It lets you choose a ghostscript-supported printer type and
Unix device file to print to, then installs a print queue in /etc/printcap and writes a short
PostScript-and-ascii magic filter based around gs and nenscript. This solution works
fairly well, and is trivial to setup for common cases.
8.2 Other Distributions
Please send me info on what other distributions do.
9. How to print to a printer over the network 如何由网路印表机列印
lpd 的一个特徵就是它支援连在不同机器上的网路印表机.
9.1 To a Unix/lpd host
如果你允许远端机器利用你的印表机列印, 那你首先要将那台机器加入
/etc/hosts.equiv 或 /etc/hosts.lpd 里(注意在 hosts.equiv 里的机器有其他的用途,
请确定你在这里加入每一台机器的用途), 你也可以只让远端机器利用 rs 这个
属性来使用你的印表机, 详情请看 lpd 的 man page.
如果要利用别人的印表机来列表, 请确定你在 /etc/printcap 中加入了下面几
行:
# REMOTE djet500
lp|dj|deskjet:\
:sd=/var/spool/lpd/dj:\
:rm=machine.out.there.com:\
:rp=printername:\
:lp=/dev/null:\
:sh:
请注意, 在本地端 lpd 仍管著一个 spool 的目录. 如果远端机器太忙或是离
线了, 列表工作就会暂存在这个 spool 目录中, 直到它可以送出去为止.
9.2. To a Win95, WinNT, LanManager, or Samba printer
利用 smbclient (附於 samba 套件中), 我们可以直接将 lpd queue 透过以
TCP/IP 为基底的 SMB print 列印出来. Samba 包含了一个叫 smbprint 的 script
可以做到. 最简单的做法是. 你将一个特定印表机的设定档放到 spool 的目录
中, 然後安装 smbprint script.
The /etc/printcap entry goes like this:
lp|remote-smbprinter:\
:lp=/dev/null:sh:\
:sd=/var/spool/lpd/lp:\
:if=/usr/local/sbin/smbprint:
你必须阅读 smbprint script 中的文件以获得更多资讯.
9.3. To a NetWare Printer
在 ncpfs 套件中有一个 nprint 的工具, 为 NetWare 提供与 smbprint 一样的
功能. 你可以在 <ftp://linux01.gwdg.de/pub/ncpfs/> 抓到 ncpfs. From the LSM
entry for version 0.16:
With ncpfs you can mount volumes of your netware server
under Linux. You can also print to netware print queues and
spool netware print queues to the Linux printing system. You
need kernel 1.2.x or 1.3.54 and above. ncpfs does NOT work
with any 1.3.x kernel below 1.3.54.
To make nprint work via lpd, you write a little shell script to print stdin on the
NetWare printer, and install that as the if for an lpd print queue. You'll get something
like:
sub2|remote-NWprinter:\
:lp=/dev/null:sh:\
:sd=/var/spool/lpd/sub2:\
:if=/var/spool/lpd/nprint-script:
9.4. To an EtherTalk (Apple) printer
I would assume that the netatalk package includes something like nprint and smbclient.
Someone let me know if this can be done!
9.5. To an HP or other ethernet printer
HPs and some other printers come with an ethernet interface which you can print
directly to using lpd. You should follow the instructions that came with your printer or
its network adaptor, but in general, such printers are "running" lpd, and provide one or
more queues which you can print to. An HP, for example, might work with a printcap
like:
lj-5|remote-hplj:\
:lp=/dev/null:sh:\
:sd=/var/spool/lpd/lj-5:\
:rm=printer.name.com:rp=raw:
In a large scale environment, especially a large environment where some printers do
not support PostScript, it may be useful to establish a dedicated print server to which all
machines print and on which all ghostscript jobs are run.
9.6. Running an if for remote printers
lpd 奇怪的地方是 if 在远瑞的 printer 上不会动, 如果你发现你必须用到 if,
you can do so by setting up a double queue and requeueing the job. 例如下面这个范
例:
lj-5:remote-hplj:\
:lp=/dev/null:sh:\
:sd=/var/spool/lpd/lj-5:\
:if=/usr/lib/lpd/filter-lj-5:
lj-5-remote:lp=/dev/null:sh:rm=printer.name.com:\
:rp=raw:sd=/var/spool/lpd/lj-5-raw:
in light of this filter-lj-5 script:
#!/bin/sh
gs <options> -q -dSAFER -sOutputFile=- - | \
lpr -Plj-5-remote -U$5
The -U option to lpr only works if lpr is run as daemon, and it sets the submitter's
name for the job in the resubmitted queue correctly. You should probably use a more
robust method of getting the username, since in some cases it is not argument 5. See
the man page for printcap
10. How to print to a fax machine.
10.1. Using a faxmodem
有一大堆可让你收发 fax 的程式等著你用, 其中最复杂的一个是 Sam Leffler
的 HylaFax, 可在 ftp.sgi.com 找到. It supports all sorts of things from multiple
modems to broadcasting.
另一个有用的程式(也许比HylaFax好用些)是 efax, 一个很简单的送 fax 的程
式. The getty program mgetty can receive faxes (and even do voicemail on some
modems!).
10.2. Using the Remote Printing Service
有些地方可能提供你这种服务---将你想印(或FAX)的东东 e-mail 过去. 他们
可支援一些好格式(例如: PostScript), 虽然范围可能无法遍及全球, 但这仍是一
项很有用的服务. 如果想知道更多关於远方列印服务的资讯, 请看FAQ
<http://www.town.hall.org/fax/faq.html>.
11. How to generate something worth printing.
Here we get into a real rat's-nest of software. 基本上, Linux 可以跑四种不同的二元
档, Linux, iBCS, Win16 (with dosemu and, someday, with Wine), and Mac/68k (with
Executor). 在这我只讨论 Linux 和一般的 UNIX software. 没提到的有
WordPerfect for SCO, 和一些其它在 Linux's iBCS 下跑得很好的商业文书处理
software.
以 Linux 本身来说, 可以选择的软体几乎都是一般 unix 上的软体.
11.1. Markup languages
大部分的标示语言都适用於大型或可重覆的专案上, 你必须控制好文字的输
出, 使之一致. 想用标示语言做出一个好看的的画面还真令人伤脑筋...
nroff
这是 unix 上第一个标示语言, Man pages 通常就是使用 *roff 巨集的格
式; 很多人信任它, 但对我而言, nroff 却有一些不必要的神秘难懂的语法. 而且
对现代的工作而言, 它可能有点贫乏了. 由於这是个知名的格式, 你可以用
groff 直接将 man pages 排版成 postscript 的格式. 利用man -t foo | lpr 指令可以
做到.
TeX
TeX, 和 LaTeX 巨集, 也是 unix 上很常用的标示语言, 技术性文件通
常都用 LaTeX 写成, 因为它使 layout issues 变得很单纯, 而且它也是少数较佳
的支援数学符号的文书处理系统. TeX 的输出格式是 dvi, 可用 dvips 或 dvilj
将之转成 PostScript 或 Hewlett Packard 的 PCL 格式.
SGML
There is at least one free sgml parser available for Unix and Linux; it forms the
basis of Linuxdoc-SGML's homegrown document system. It can support other
DTD'S, as well.
HTML
有人说简单的专案写成 HTML 然後用 netscape 印出就好了, I disagree,
but YMMV.
11.2. WYSIWYG
所视即所得的文书处理 software 的软体好像很缺乏耶...随便写一些, 如果我
有遗漏的请让我知道.
Lyrix
Lyrix is a front-end to LaTeX which looks very promising.
The Andrew User Interface System
AUIS includes ez, a WYSIWYG-style editor with most basic word processor
features, HTML capabilities, and full MIME email and newsgroup support.
12. Ghostscript
Ghostscript, 一个在 Linux printing 中很重要的程式, 用来处理 PostScript 的列
印. 一般 unix 下的此类程式大概都要 $100~300 不等, 但此程式却是 free 的
(不可思议), 并且能将 PostScript 转成你印表机可接受的语言, 如果你觉得使用
lpd filter 太麻烦了, 那它可使你轻易地拥有一台模拟可印 PostScritp 的印表
机喔 !
Ghostscript 有二种格式, 商业版的 Ghostscript 叫 Aladdin Ghostscript, 可以免费
的为个人使用, 但不能随著商业的 linux 套件发行. 现在的 Ghostscript 可以处
理 Adobe Acrobat's Portable Document Format 了, 以前不行 !
Free 版的 Ghostscript 是 GNU Ghostscript, 是一个早期较简易的 Aladdin
Ghostscript 版本,(Kudos to Aladdin for this arrangement; more software vendors
should support free software in this way).
Ghostscript 最主要的缺点是它的字型, 是由 bitmap 产生的. 但是还好, 你可以
从很多地方取得商业上授权的字型, 因为 Ghostscript 可读取 Adobe type 1 的
字型. 所以你可以用 Acrobat PDF reader 的字型, 或用 Adobe's ATM 的字型等
等.
当你使用 gs 的时候, 请注意将 file access 的选项关了(-dSAFER), PostScript 是
一个多功能的语言, 一个写得不好的 PostScript 程式可能会让你很头痛.
13. On-screen previewing of printable things
几乎所有你要印的东东都可以在营幕上预视喔!
13.1. PostScript
Ghostscript 在 X11 下有个很好的 PostScript 预视软体叫 Ghostview. 此软体
的最新版本也可以看 PDF 的格式.
13.2. TeX dvi
TeX DeVice 在 X11 下借由 xdvi 来预视. 目前的 xdvi 已叫做 ghostscript.
也有一个在 VT100 下的软体叫 dgvt. 在 Linux 下须有 svgalib 来预视.
14. Credits
The smbprint information is from an article by Marcel Roelofs
<marcel@paragon.nl>.
The nprint information for using Netware printers was provided by
Michael Smith <mikes@bioch.ox.ac.uk>.
The serial printers under lpd section is from Andrew Tefft
<teffta@engr.dnet.ge.com>.
--
※ 来源:.紫 丁 香 bbs.hit.edu.cn.[FROM: 202.118.244.16]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:208.988毫秒