转贴
本文将介绍目前在大部分Linux系统中正在使用的打印系统,以及一些Unix打印的核心概念,并展望一下未来Linux打印系统的发展。
Linux打印原理
首先需要了解的是,打印在Unix世界的演化中总是围绕着PostScript页面描述语言展开的。该语言是由Adobe公司开发的,它是一个成熟的、用于描述一个文档每一页面内容的程序语言。如今很多打印机中都有一个嵌入式的PostScript解释器,它负责使用PostScript将页面在打印纸上再现出来。现在,所有桌面Linux应用程序都有一个打印选项,可以生成PostScript数据来打印整页的文档。
这种方法和其它面向桌面的操作系统有很大的不同,也正是它让Unix打印落下了不易使用的名声。在Windows和Mac OS中有整合得非常好的API供应用程序使用,通常情况下都可以为打印机提供一个接口,以让应用程序不用关心设备的具备细节。此外,打印API通常也是和图形API整合在一起,并且可用于在屏幕上显示。这其中部分功能已经在X11中实现了。
大部分Unix系统是提交任务至队列中,并且希望它能够正确地打印出来。但是并没有一种统一的收集打印机信息或工作状态的方法,这严重影响了那些需要提供打印能力的Linux应用程序。
在Linux中,虽然PostScript是产生打印文档的事实上的标准,但打印机本身却并不需要知道PostScript,因为这需要使用到相对比较昂贵的技术。在一般情况下,尤其是在低端打印机中,PostScript数据要被翻译成打印机本地的页面描述语言。这是通过使用一个特殊的转换过滤器来完成的。一般而言,一个过滤器实际上就是一个特殊的程序,它可以处理输入的数据,并且输出经过加工的数据。现在,Linux打印系统中使用着各种不同的过滤器:转换过滤器、I/O过程器(负责将数据传送至设备)、处理过滤器(转换文档数据)。
打印系统的基础是一个假脱机程序(Spooler)。它可以管理打印任务队列,而一个队列通常和一个打印机相关联,并且用户提交的任务都是按照先进先出的原则来处理的。当一个打印任务被处理时,任务中的数据在送达打印机前一般都要通过一定数量的过滤器。Unix打印假脱机程序有很多种形式,在此将关注目前在Linux系统中使用广泛的几种形式。
BSD LPD打印系统
正如其名字所显示的,该打印系统源自于伯克利的Unix发行版。LPD(行式打印机后台程序)现在仍然是很多其它打印系统的基础。虽然LPD设计之初是用于一次只能打印一行的行式打印机的,不过它也可以用于整页打印的打印机。
BSD是用于完整的Linux发行版(比如Slackware等)的第一个打印系统。现在,仍然有很多发行版(Debian、Slackware)还会带有这种假脱机打印程序,当然一般都是和下文提到的、更新的打印系统一起发行的。现在,仍然还有很多种BSD假脱机程序正在被使用着。
BSD打印系统实际只是一个假脱机程序,这也使得其核心的功能仅限于队列任务。它由一个后台程序(lpd)及一些位于/etc目录下的配置文件组成,在这些配置文件中有着队列和属性的一些定义。在相应的目录下,还有一系列基本的用于提交、删除和处理任务使用的命令(lpd、lprm、lpc)。
队列的定义是在/etc/printcap文件中完成的,一个典型的有关打印机的描述段落如下所示:
# Sample queue definition for BSD LPD
lp|printer1:
:sd=/var/spool/lpd/lp:
:lp=/dev/lp0:
:if=/usr/sbin/somefilter:
:mx#0:
:sh:
每一个描述段落都定义了一个队列,这样就可能会有若干个队列指向同一台物理打印机。一个队列也可以有几个别名,在上述例子中,队列lp就有一个“printer1”的别名。打印任务可以送至这些打印机名中的任何一个,并且都将被置于同一个队列之中。一般情况下,lp会被做为缺省的队列。
任务是通过lpr命令提交至假脱机程序的,一个特定的队列可以通过-P参数来指定,比如:lpr -Pprinter1 /path/to/some/file已经被提交,但是还没有被处理的任务可以通过lprm从队列中删除。任务ID号及各种状态信息都可以通过运行lpq命令来获取。
BSD LPR是非常重要的,因为它也定义了LPD网络协议,而该协议是用于提交任务至远程LPD后台程序的,并且它允许Unix工作站实现一个打印服务器的功能。现在,所有的网络打印机都支持这个协议。由于它使用范围非常广泛,所有其它打印系统都要求至少可以和其它的LPD后台程序进行会话。
下面是如何在printcap文件中定义一个远程队列的例子。在这个例子中,任务将会被即时传送至远程监控程序的队列之中,并且不会在本地机进行处理。
# Sample queue definition for a remote LPD queue on a client
remote:
:sd=/var/spool/lpd/remote:
:rm=printserver.domain.tld:
:rp=queue:
:mx#0:
rm属性指明了远程LPD服务器的地址,rp属性则是任务将被送达的服务器队列的名字。在/etc/lpd.hosts中,可以定义允许主机将打印任务转发至本地LPD后台程序之中。
LPD协议传送数据被分成两个部分。首先会生成一个描述任务的控制文件,并且传送该文件。该控制文件包含有源用户、文件名和所有与工作相关的信息。接着就会传送数据文件,它的格式完全取决于目前正在使用的打印语言。
LPRng打印系统
虽然BSD提供了基本的Unix打印假脱机程序,但功能还是非常有限。现在有好几个项目正在致力于改进BSD打印系统,以使其具有更好的可配置性和更佳的灵活性。目前使用较广、较有影响力的基于BSD的打印系统是LPRng(LPR Next Generation),其创始人是Patrick Powell。该系统实际上重写了原来的BSD LPR系统,但原有概念都保留了下来。
虽然LPRng保留了printcap文件的格式,但是它还引入了一些新的属性以使配置过程更加灵活。过滤器定义可以被独立出来,并且还可以定义真正的I/O过滤器。用户也可以通过在本地机主目录下编写printcap文件来定义自己的队列。
LPRng还提供了模拟Unix System V风格的打印命令(lp、lpstat等)。随LPRng发行的还有IFHP过滤器,它可以用在队列中,用于自动转换一些数据格式(比如打印ASCⅡ文本或图像)。
通用Unix打印系统(CUPS)
CUPS是一个相对比较新的项目,它由Easy Software公司发起。它的设计一切从头开始,其目的就是要代替由BSD衍生出来的打印系统,并且整合了很多正在形成的标准和技术。CUPS取得了很大的成功,以至于最近苹果公司也将其作为MacOS X 10.2(Jaguar)新的标准打印系统。
CUPS使用的是IPP(网络打印协议)标准,这是从HTTP中衍生出来的IETF协议。CUPS后台程序可以接受IPP请求,并且将其作为和客户端应用程序进行通信的主要方法。作为一个Internet协议,IPP使得在广域网上配置打印服务器变得非常容易。CUPS也支持其它可以和打印机进行通信的流行协议,因此也可以将其作为一个连接不支持IPP协议打印机的一个桥梁。和其所基于的HTTP协议一样,IPP也可以通过使用认证和SSL连接来加强安全性。CUPS本身都支持这些功能,也就是说它可以进行安全打印。
CUPS采用的另外一个标准是PPD(PostScript Printer Definition)文件格式,这是Adobe另外一个用于PostScript打印机的标准。
CUPS还采用了很多过滤器用于传送数据至打印机的方法。与BSD类的假脱机程序不同的是,这是通过一种更加智能的方式来完成的。下面是在CUPS中可用的部分过滤器:
1.后端过滤器。它可以提供最终数据进行传送的端点。这些过滤器可用于并口、TCP/IP套接字连接、LPD和其它端点的连接。
2.文档转换过滤器。该过滤器是作为CUPS一个标准配置一起发行的。它可以转换图像、ASCⅡ文本、PDF文件和HP-GL/2矢量文档至PostScript。
3.接口过滤器。它可以将文档从PostScript转换至其它过渡的文件格式。
和其它的打印系统一样,为了能够在非PostScript打印机上正确打印,翻译过滤器也是必须的。CUPS允许PPD文件记述用于将文档换成设备本地语言的过滤器,比如:
*cupsFilter: "application/vnd.cups-raster 0 rastertohp"
这是用于HP Deskjet打印机的一个PPD文件。它的意思是rastertohp程序(这是一个过滤器,通过位于/usr/lib/cups/filter)将把MIME数据类型的文件“application/vnd.cups-raster”作为输入,并且将其转换成可直接送至打印机的格式,在此就是HP PCL数据。
CUPS可以进行打印机分类,该功能最初用于System V打印系统中。它可以将打印机按组“分类”,并且自动执行负载均衡功能。一个分类可以将任务传送至一个正常的队列中,一旦任务提交,就会被分配给第一个可用的打印机来执行打印任务。
CUPS一个非常有用的功能就是可以自动进行网络配置。通过广播协议,所有位于同一个局域网的CUPS监控程序都可以相互通信,某一服务器上的队列配置可以被浏览,并可用于其它的系统之上。CUPS也可以为那些位于不同服务器上却有着同样名字的打印机提供一个“默认分类”,并自动为其提供负载平衡。CUPS也支持LSP(服务定位协议),该协议可以发送广播以表明自己已经在线。
在客户端,CUPS有LPD类和System V类的接口,这就意味着它可以提供lpr、lpq、lp、lpstat等系统命令。对于IPP客户端和CUPS监控程序进行通信的过程来说,所有这些命令都是非常重要的。
CUPS还有一个基于Web的系统管理界面,可以直接通过Web浏览器进行配置和管理,或者检查打印机的状态。这显然要比使用命令或直接通过编辑/etc/cups/printers.conf文件来定义队列要直观得多。
CUPS打印不需要将输出格式限制在PostScript。虽然其它一些打印系统也不一定有这样的限制,但是CUPS却将它做得更容易。前面我们已经看到了用于CUPS的PPD文件中是如何指定一个转换过滤器的,以及这些内容如何包含在MIME中。CUPS广泛使用了MIME类型来决定打印机间任务提交和最终数据之间的数据流。过滤器可以在*.convs文件(通常位于/etc/cups)中定义,该文件可以描述每一个过滤器程序作为接收输入的数据类型及作为输出的数据类型。对于一给定类型的任务,CUPS会聪明地在一个过滤器链中做出决定。
应用程序接口
在Unix世界里,PostScript语言仍然是主要用于打印的接口。所有主要的应用程序都会输出通用的PostScript页面,而这些PostScript经过打印系统处理后再被打印出来。这显然有很大的局限性,因为应用程序并没有一种统一的、查询打印功能或获知任务是否被正确打印的途径。有少量的应用程序可以使用PPD文件来访问打印机功能,不过StarOffice和OpenOffice并不包含在内。
现在情况还是有所改观。比如,CUPS提供了一个基本的C API,它可以让应用程序更简单地和打印系统进行整合。这个API包含了通过IPP和CUPS监控程序进行通信的功能,以及读取和解析PPD文件的功能,这样,应用程序就具备了收集打印机详细信息的能力。但对于应用程序开发人员来说还有很大的局限性,因为它只能在CUPS和类似的IPP服务器上工作。
在软件方面,为了使打印更加容易,现在GNOME和KDE桌面项目都包含了一个中间层,分别是KDEPrint和GNOME。这些框架的目的是通过抽出基本的打印系统,为应用程序提供一个统一的API。
Linux打印系统的未来
与几年前相比,随着更多、更高级打印系统的出现,情况已有了很大改观,也得到了HP、IBM等公司的关注,它们也努力致力于推进这个基础架构发展。
此外,FSG(自由标准组织)正在进行着一个名为OpenPrinting的项目。据称该项目是为Linux定义下一代打印系统的基础架构,目前其聚集了很多业内的专家。该工作组正在定义API和标准,以迅速提升Linux在与竞争者角逐时的竞争力。
Myiozzdoc 于 2005-10-25 00:12:07发表:
好文
artiomgy 于 2005-09-25 00:21:28发表:
不错,是好文呀
thej 于 2005-08-08 10:15:23发表:
支持
中国人 于 2005-07-22 00:12:58发表:
支持
ming 于 2005-06-02 11:22:11发表:
好好研究研究