diff options
author | Xin LI <delphij@FreeBSD.org> | 2005-04-06 11:30:56 +0000 |
---|---|---|
committer | Xin LI <delphij@FreeBSD.org> | 2005-04-06 11:30:56 +0000 |
commit | c9a87111c2dd420148f5279f3d7868c30a561792 (patch) | |
tree | d09ba3e34d4da3df7f32d41bfbc6e76a1c1d8662 /zh_CN.GB2312/books/handbook | |
parent | e86dcd96b4ee38678b3481281ad71e3fa2653471 (diff) |
Notes
Diffstat (limited to 'zh_CN.GB2312/books/handbook')
-rw-r--r-- | zh_CN.GB2312/books/handbook/printing/chapter.sgml | 3502 |
1 files changed, 3286 insertions, 216 deletions
diff --git a/zh_CN.GB2312/books/handbook/printing/chapter.sgml b/zh_CN.GB2312/books/handbook/printing/chapter.sgml index 5f5917ba96..347d0e2083 100644 --- a/zh_CN.GB2312/books/handbook/printing/chapter.sgml +++ b/zh_CN.GB2312/books/handbook/printing/chapter.sgml @@ -2,7 +2,7 @@ The FreeBSD Documentation Project The FreeBSD Simplified Chinese Project - Original Revision: 1.88 + Original Revision: 1.93 $FreeBSD$ --> @@ -181,14 +181,14 @@ <para>要想在<application>LPD</application>打印池 系统上使用打印机, 您需要 - 设置打印机硬件和 + 设置打印机硬件和 <application>LPD</application>软件。 这个 文档描述了这两级设置: </para> <itemizedlist> <listitem> <para>参见<link linkend="printing-simple">简单打印机 - 设置</link>来了解怎样连接一个打印机, 告诉 + 设置</link>来了解怎样连接一个打印机, 告诉 <application>LPD</application>怎样与 它通讯, 并且打印纯文本到 打印机。 </para> @@ -207,7 +207,7 @@ <title>简单打印机设置</title> <para>这部分讲解怎样配置打印机硬件和 - <application>LPD</application>使之与打印机配合。 + <application>LPD</application>使之与打印机配合。 讲解的基础知识有: </para> <itemizedlist> @@ -219,14 +219,14 @@ <listitem> <para><link linkend="printing-software">软件 - 设置</link>部分将讲解怎样配置 + 设置</link>部分将讲解怎样配置 <application>LPD</application>打印池的配置 文件 (<filename>/etc/printcap</filename>)。 </para> </listitem> </itemizedlist> <para>如果您正在设置一台通过网络协议 - 接收数据来打印而不是通过串行或者并行界面的打印机, + 接收数据来打印而不是通过串行或者并行界面的打印机, 参见<link linkend="printing-advanced-network-net-if">使用 网络数据流界面的打印机</link>。 </para> @@ -234,7 +234,7 @@ 设置</quote>, 但还是相当复杂的。 使打印机 配合和<application>LPD</application> 打印池在计算机上正常运转是最难的 - 部分。 一旦您的打印机可以正常工作后,那些高级选项, 比如报文页和记帐, + 部分。 一旦您的打印机可以正常工作后,那些高级选项, 比如报文页和记帐, 是相当简单的。 </para> <sect3 id="printing-hardware"> @@ -282,7 +282,7 @@ <para><emphasis>并行</emphasis>界面使用 计算机上的并口来发送数据到 打印机。 并行接口在计算机上也已经非常普遍 - 而且速度高于 RS232 串行界面。 + 而且速度高于 RS232 串行界面。 电缆非常容易买到, 但很难手工 制作。 并行接口通常没有 通讯选项, 这使得 @@ -304,7 +304,7 @@ <listitem> <para>USB 接口, 即通用串行 总线, 可以达到比并口和串口 - 高很多的速度。 而电缆简单又便宜。 + 高很多的速度。 而电缆简单又便宜。 USB 用来打印比串口和并口 更有优势, 但是 &unix; 系统不能很好的支持它。 避免这个问题的方法就是购买一台 @@ -333,7 +333,7 @@ <para>&postscript; 任务 事实上由程序发送给打印机; 但它并不进行打印 - 而是直接将结果返回给计算机。 + 而是直接将结果返回给计算机。 &postscript; 也采取双向通讯来将打印中的问题 报告给计算机, 比如 &postscript; 程序中的错误 或者打印机卡纸。 这些信息对于用户来说也许是非常 @@ -345,19 +345,19 @@ 的两个值相减就可以得到该用户要付多少 纸钱。 </para> </sect4> - + <sect4 id="printing-parallel"> <title>并口</title> <para>用并口连接打印机需要用 - Centronics 电缆把打印机与计算机连接起来。 + Centronics 电缆把打印机与计算机连接起来。 具体说明指导应该在打印机, 计算机的说明书上有, 或者 干脆两个上面都有。 </para> - <para>记住您用的计算机上的哪个并口。 - 第一个并口在 FreeBSD 上叫 <filename>/dev/ppc0</filename> + <para>记住您用的计算机上的哪个并口。 + 第一个并口在 FreeBSD 上叫 <filename>/dev/ppc0</filename> ; 第二个叫 <filename>/dev/ppc1</filename>, 依此 - 类推。 打印机设备也用同样的方法命名: + 类推。 打印机设备也用同样的方法命名: <filename>/dev/lpt0</filename> 是连接在第一个并口 上的打印机, 依此类推。 </para> </sect4> @@ -393,8 +393,8 @@ </listitem> <listitem> - <para>一些特殊的打印机需要的<emphasis>串行打印机</emphasis> 电缆, - 是一种和非调制解调器电缆类似的电缆, + <para>一些特殊的打印机需要的<emphasis>串行打印机</emphasis> 电缆, + 是一种和非调制解调器电缆类似的电缆, 只是一些信号还是送到了另一端, 而 不是直接在连接头儿内短路。 </para> </listitem> @@ -403,15 +403,15 @@ <indexterm><primary>baud rate</primary></indexterm> <indexterm><primary>parity</primary></indexterm> <indexterm><primary>flow control protocol</primary></indexterm> - <para>当然, 您还得为打印机设置通讯参数。 - 一般是通过打印机面板上的按钮或者 DIP + <para>当然, 您还得为打印机设置通讯参数。 + 一般是通过打印机面板上的按钮或者 DIP 开关进行设置。 在计算机和打印机上都选择它们所支持的最高 <literal>波特</literal> (每秒多少比特, 有时也叫 - <emphasis>波特率</emphasis>) 的传输速率。 - 选择7或者8个数据位; 选择不校验, + <emphasis>波特率</emphasis>) 的传输速率。 + 选择7或者8个数据位; 选择不校验, 偶校验或者奇校验; 选择1个或2个停止位。 还要选择流量 控制协议: 无, XON/XOFF (也叫做 - <quote>in-band</quote> 或 <quote>软件</quote>) 流量控制。 + <quote>in-band</quote> 或 <quote>软件</quote>) 流量控制。 记住您的软件配置中的参数也要设成上面的 数值。 </para> </sect4> @@ -421,7 +421,7 @@ <title>软件设置</title> <para>这部分描述了要使用FreeBSD系统中的 - <application>LPD</application> 打印池进行打印所需的软件设置。 + <application>LPD</application> 打印池进行打印所需的软件设置。 </para> <para>包括这几个步骤: </para> @@ -443,14 +443,14 @@ </step> <step> - <para>测试操作系统是否能够发送数据到打印机。 + <para>测试操作系统是否能够发送数据到打印机。 <link linkend="printing-testing">检测打印机 联机状况</link> 部分会告诉您要怎样 做。 </para> </step> <step> - <para>为 <application>LPD</application> 设置与打印机匹配的参数则 + <para>为 <application>LPD</application> 设置与打印机匹配的参数则 通过修改 <filename>/etc/printcap</filename> 这个文件来完成。 这章后面 的部分将讲解如何来完成设置。 </para> @@ -461,12 +461,12 @@ <title>配置内核</title> <para>操作系统的内核为了使某些特殊设备工作需要重新 - 编译。 打印机所用的串口、 + 编译。 打印机所用的串口、 并口就属于那些特殊设备。 因此, 可能需要 - 添加对串口或并口的支持, + 添加对串口或并口的支持, 如果内核并没有配置它们的话。 </para> - <para>要想知道您现在使用的内核是否支持串口, + <para>要想知道您现在使用的内核是否支持串口, 输入: </para> <screen>&prompt.root; <userinput>grep sio<replaceable>N</replaceable> /var/run/dmesg.boot</userinput></screen> @@ -480,7 +480,7 @@ sio2: type 16550A</screen> <para>则说明您现在使用的内核支持串口。 </para> - <para>要想知道您现在使用的内核是否支持并口, + <para>要想知道您现在使用的内核是否支持并口, 输入: </para> <screen>&prompt.root; <userinput>grep ppc<replaceable>N</replaceable> /var/run/dmesg.boot</userinput></screen> @@ -488,11 +488,11 @@ sio2: type 16550A</screen> <para>其中 <replaceable>N</replaceable> 是并口的 编号, 同样从0开始。 如果得到类似 下面的输出: </para> - + <screen>ppc0: <Parallel port> at port 0x378-0x37f irq 7 on isa0 ppc0: SMC-like chipset (ECP/EPP/PS2/NIBBLE) in COMPATIBLE mode ppc0: FIFO with 16/16/8 bytes threshold</screen> - + <para>那么您现在使用的内核支持并口。 </para> <para>您可能必须为了使操作系统支持您打印机需要的串口或 @@ -501,7 +501,7 @@ ppc0: FIFO with 16/16/8 bytes threshold</screen> <para>要增加对串口的支持, 参见 内核配置这部分。 要增加对并口的支持, 除了参见 - 上面提到的那部分之外, <emphasis>还要</emphasis> 参见下面的 + 上面提到的那部分之外, <emphasis>还要</emphasis> 参见下面的 部分。 </para> </sect4> </sect3> @@ -527,7 +527,7 @@ ppc0: FIFO with 16/16/8 bytes threshold</screen> <procedure> <step> - <para>使用 &man.su.1; 命令切换到 <username>root</username> 帐号。 + <para>使用 &man.su.1; 命令切换到 <username>root</username> 帐号。 在出现提示的时候输入 <username>root</username> 帐号的密码。 </para> </step> @@ -567,14 +567,14 @@ ppc0: FIFO with 16/16/8 bytes threshold</screen> <para>在使用并口时, 您可以选择 让 FreeBSD 用中断方式还是轮询方式来 与打印机通讯。 在 - FreeBSD 4.X and 5.X 上, 通用的打印机驱动 (&man.lpt.4;) + FreeBSD 4.X and 5.X 上, 通用的打印机驱动 (&man.lpt.4;) 使用 &man.ppbus.4; 系统, 它由 &man.ppc.4; 驱动来控制端口芯片。 </para> <itemizedlist> <listitem> <para><emphasis>中断</emphasis> 方式是 - GENERIC 核心的默认方式。 在这种方式下, + GENERIC 核心的默认方式。 在这种方式下, 操作系统占用一条中断请求线来检测什么时候 打印机做好接收数据的准备。 </para> </listitem> @@ -587,16 +587,16 @@ ppc0: FIFO with 16/16/8 bytes threshold</screen> </listitem> </itemizedlist> - <para>中断方式速度通常会快一些, + <para>中断方式速度通常会快一些, 但却占用了一条宝贵的中断请求线。 一些新出的 HP 打印机 - 不能正常的工作在中断模式下, - 是由于一些定时问题 (还没正确的理解) + 不能正常的工作在中断模式下, + 是由于一些定时问题 (还没正确的理解) 造成的。 这些打印机需要使用轮询方式。 您应该使用 任何一种方式, 只要它能正常工作就行。 一些打印机虽然在两种模式下都可以 工作, 但在中断模式下会慢的要命。 </para> <para>您可以用以下两种方法设定通讯模式: 通过 - 配置内核或者使用 &man.lptcontrol.8; + 配置内核或者使用 &man.lptcontrol.8; 这个程序。 </para> <para><emphasis>要通过配置内核的方法设置 @@ -607,12 +607,12 @@ ppc0: FIFO with 16/16/8 bytes threshold</screen> <para>修改内核配置文件。 找到 一个叫 <literal>ppc0</literal> 的记录。 如果您想要设置的是 第二个并口, 那么用 <literal>ppc1</literal> - 代替。 使用第三个并口的时候用 <literal>ppc2</literal> 代替, + 代替。 使用第三个并口的时候用 <literal>ppc2</literal> 代替, 依此类推。 </para> <itemizedlist> <listitem> - <para>如果您想要使用中断方式, 在 FreeBSD 4.X 下的方法是指定一个 + <para>如果您想要使用中断方式, 在 FreeBSD 4.X 下的方法是指定一个 <literal>irq</literal> : </para> <programlisting>device ppc0 at isa? irq <replaceable>N</replaceable></programlisting> @@ -648,10 +648,10 @@ ppc0: FIFO with 16/16/8 bytes threshold</screen> <programlisting>hint.ppc.0.irq="<replaceable>N</replaceable>"</programlisting> - <para>在 + <para>在 FreeBSD 5.X 下, 有时上面的方法并不能使并口工作在轮询方式。 大多数 情况是由于 &man.acpi.4; 驱动造成的, 它 - 可以自动侦测到设备并将其挂载到系统上, 但也因此, + 可以自动侦测到设备并将其挂载到系统上, 但也因此, 它控制着打印机端口的访问模式. 您 得检查 &man.acpi.4; 的配置来 解决这个问题。 </para> @@ -704,7 +704,7 @@ ppc0: FIFO with 16/16/8 bytes threshold</screen> 发送到打印机上。 分别独立调试打印机的通讯和打印池系统 会更简单。 </para> - <para>我们为了测试打印机,将发送一些文本给它。 一个叫 &man.lptest.1; + <para>我们为了测试打印机,将发送一些文本给它。 一个叫 &man.lptest.1; 的程序能胜任这项工作, 它可以让打印机立即打印出程序发给它的 字符: 它在每行打出 可以打印的 96 个 ASCII 字符。 </para> @@ -720,7 +720,7 @@ ppc0: FIFO with 16/16/8 bytes threshold</screen> (Is this thing working?) show showpage</programlisting> - <para>可以把上面这段 &postscript; 代码写进一个文件里, + <para>可以把上面这段 &postscript; 代码写进一个文件里, 并且像下面部分的例子里那样 使用。 </para> @@ -729,7 +729,7 @@ showpage</programlisting> <para>上面的小程序是基于 &postscript; 写成的, 而不是惠普 的 PCL 。 尽管 PCL 拥有强大的功能, 比如 - 您可以在打印纯文本的同时夹带着特殊的命令。 + 您可以在打印纯文本的同时夹带着特殊的命令。 &postscript; 不能直接打印纯文本, 所以 这类打印机语言是我们要特殊照顾的 对象。 </para> @@ -777,7 +777,7 @@ showpage</programlisting> <para>然后, 一行一行的 <emphasis>输入</emphasis> 输入 这段程序。 因为在按下 <literal>换行</literal> 或者 - <literal>回车</literal> 之后, 这一行就不能再修改了。 + <literal>回车</literal> 之后, 这一行就不能再修改了。 当您输入完 这段程序之后, 按 <literal>CONTROL+D</literal>, 或者其他 @@ -830,23 +830,23 @@ showpage</programlisting> <indexterm><primary>parity</primary></indexterm> <para>其中 <replaceable>port</replaceable> 是 串口的设备节点 (<literal>ttyd0</literal>, - <literal>ttyd1</literal>, 等等。 ), + <literal>ttyd1</literal>, 等等。 ), <replaceable>bps-rate</replaceable> 是 - 与打印机通讯时使用的波特, + 与打印机通讯时使用的波特, <replaceable>parity</replaceable> 是通讯时打印机要求 的校验方法 (either <literal>even</literal>, - <literal>odd</literal>, <literal>none</literal>, or + <literal>odd</literal>, <literal>none</literal>, or <literal>zero</literal>)。 </para> - <para>这儿有一个串口打印机的例子, - 它连接在第三个串口上, 速度为 19200 波特, + <para>这儿有一个串口打印机的例子, + 它连接在第三个串口上, 速度为 19200 波特, 不进行校验: </para> <programlisting>printer:dv=/dev/ttyd2:br#19200:pa=none</programlisting> </step> <step> - <para>用 &man.tip.1; 连接打印机。 + <para>用 &man.tip.1; 连接打印机。 输入: </para> <screen>&prompt.root; <userinput>tip printer</userinput></screen> @@ -854,7 +854,7 @@ showpage</programlisting> <para>如果没能成功, 则要再次修改 <filename>/etc/remote</filename> 这个文件, 并且试试用 <filename>/dev/cuaa<replaceable>N</replaceable></filename> - 代替 + 代替 <filename>/dev/ttyd<replaceable>N</replaceable></filename>。 </para> </step> @@ -872,12 +872,12 @@ showpage</programlisting> <listitem> <para>如果打印机支持 &postscript; 或者其他 打印机语言, 则发送一段小程序到 - 打印机。 一行一行的输入程序, 必须 + 打印机。 一行一行的输入程序, 必须 <emphasis>非常仔细</emphasis> 因为像退格 或者其他编辑键也许对打印机来说有它的 意义。 您同样也需要按一个特殊的 文件结束键, 让打印机知道它已经 - 接收了整个程序。 对于 &postscript; + 接收了整个程序。 对于 &postscript; 打印机, 按 <literal>CONTROL+D</literal>。 </para> <para>或者, 您同样也可以把程序存储在一个文件里 @@ -886,7 +886,7 @@ showpage</programlisting> <screen>&prompt.user; <userinput>><replaceable>file</replaceable></userinput></screen> <para>其中 <replaceable>file</replaceable> 是 - 包含要发送程序的文件名。 在 + 包含要发送程序的文件名。 在 &man.tip.1; 发送这个文件之后, 按代表 文件结束的键。 </para> </listitem> @@ -911,7 +911,7 @@ showpage</programlisting> 打印机。 </para> <para>配置 <application>LPD</application> 要修改 - <filename>/etc/printcap</filename> 这个文件。 + <filename>/etc/printcap</filename> 这个文件。 <application>LPD</application> 打印池系统 在每次打印池被使用的时候都会读取这个文件, 所以对这个文件 的修改会立即生效。 </para> @@ -920,7 +920,7 @@ showpage</programlisting> <primary>printers</primary> <secondary>capabilities</secondary> </indexterm> - <para> &man.printcap.5; 这个文件的格式很简单。 + <para>&man.printcap.5; 这个文件的格式很简单。 您可以用您最喜欢的文本编辑器来修改 <filename>/etc/printcap</filename> 这个文件。 这种格式和其他的 像 @@ -933,9 +933,9 @@ showpage</programlisting> <procedure> <step> - <para>为打印机起一个名字 ( 和一些方便的别名 ) + <para>为打印机起一个名字 ( 和一些方便的别名 ) , 然后把它们写进文件 - <filename>/etc/printcap</filename> ; 参见 + <filename>/etc/printcap</filename> ; 参见 <link linkend="printing-naming">Naming the Printer</link> 这章来得到更多的关于起名的帮助。 </para> </step> @@ -984,7 +984,7 @@ showpage</programlisting> </procedure> <note> - <para>基于打印机语言的打印机, 比如 &postscript; 打印机, + <para>基于打印机语言的打印机, 比如 &postscript; 打印机, 不能直接打印纯文本。 简单的设置方法在上面 提到并且下面的部分也要讨论, 假如您正在 安装这样一台只能打印它明白的文件的 @@ -994,7 +994,7 @@ showpage</programlisting> <para>用户总是希望他们能在任何一个安装在他们系统的打印机上打印 纯文本。 使用 <application>LPD</application> 接口的程序也通常这样 - 希望。 + 希望。 如果您正在安装这样一台打印机, 并且想要它能打印 基于它支持的打印机语言的任务 <emphasis> 并且 </emphasis> 还可以打印纯文本的任务, 那么强烈建议您在上面提到 @@ -1008,32 +1008,30 @@ showpage</programlisting> <sect4 id="printing-naming"> <title>命名打印机</title> - <para>第一步 ( 简单 ) 就是给打印机起一个名字。 - 您是按功能起名字还是干脆起个古怪的名字都没有关系, + <para>第一步 ( 简单 ) 就是给打印机起一个名字。 + 您是按功能起名字还是干脆起个古怪的名字都没有关系, 因为您可以给打印机设置许多的 别名。 </para> <para>在 <filename>/etc/printcap</filename> 里至少有一个打印机必须指定, 别名是 - <literal>lp</literal>. 这是默认的打印机名。 + <literal>lp</literal>. 这是默认的打印机名。 如果用户既没有 <envar>PRINTER</envar> 环境 变量, 也没有在任何 - <application>LPD</application> 命令的命令行中指定打印机名, + <application>LPD</application> 命令的命令行中指定打印机名, 则 <literal>lp</literal> 将是默认 要使用的打印机。 </para> - <para>还有, 我们通常把最后一个别名设置成 - 能完全描述打印机的名字, 包括厂家 - 和型号。 </para> + <para>还有, 我们通常把最后一个别名设置成能完全描述打印机的名字, + 包括厂家和型号。 </para> - <para>一旦您选好了名字或者一些别名, 把它们 - 放进文件 <filename>/etc/printcap</filename> 里。 打印机的 - 名字应该从最左边的一列写起。 用 - 竖杠来隔开每个别名, 并且在最后一个别名后面 - 加上一个冒号。 </para> + <para>一旦您选好了名字或者一些别名, 把它们放进文件 + <filename>/etc/printcap</filename> 里。 + 打印机的名字应该从最左边的一列写起。 用竖杠来隔开每个别名, + 并且在最后一个别名后面加上一个冒号。 </para> <para>在下面的例子中, 我们从一个基本的 - <filename>/etc/printcap</filename> 开始, 它只定义了两台打印机 + <filename>/etc/printcap</filename> 开始, 它只定义了两台打印机 (一台 Diablo 630 行式打印机和一台 Panasonic KX-P4455 &postscript; 激光打印机 ):</para> @@ -1046,13 +1044,13 @@ bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:</programlisting> <para>在这个例子中, 第一台打印机被命名为 <literal>rattan</literal> 并且设置了 - <literal>line</literal>, <literal>diablo</literal>, - <literal>lp</literal>, 和 <literal>Diablo 630 Line + <literal>line</literal>, <literal>diablo</literal>, + <literal>lp</literal>, 和 <literal>Diablo 630 Line Printer</literal> 这几个别名。 因为它被设置了 <literal>lp</literal> 这个别名, 所以它是默认打印机。 第二台 - 被命名为 <literal>bamboo</literal>, 并且设置了 - <literal>ps</literal>, <literal>PS</literal>, - <literal>S</literal>, <literal>panasonic</literal>, 和 + 被命名为 <literal>bamboo</literal>, 并且设置了 + <literal>ps</literal>, <literal>PS</literal>, + <literal>S</literal>, <literal>panasonic</literal>, 和 <literal>Panasonic KX-P4455 PostScript v51.4</literal> 这几个别名。 </para> </sect4> @@ -1063,7 +1061,7 @@ bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:</programlisting> <secondary>header pages</secondary> </indexterm> - <para> <application>LPD</application> 打印池系统默认 + <para><application>LPD</application> 打印池系统默认 会为每个任务打印 <emphasis>报头页</emphasis>。 报头页 包含了发送这个任务的用户, 发送这个任务 @@ -1099,14 +1097,14 @@ bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ <indexterm><primary>print jobs</primary></indexterm> <para>下一步设置就是要建立一个 - <emphasis>打印池目录</emphasis>, 一个在任务被打印完 + <emphasis>打印池目录</emphasis>, 一个在任务被打印完 之前存放任务的目录, 也有很多其他 的打印池系统所用到的文件存在里面。 </para> <para>由于打印池目录的变量本质, 通常 把这些目录安排在 <filename>/var/spool</filename> 下。 您也没有必要去 - 备份打印池目录里的内容。 + 备份打印池目录里的内容。 重新建立它们只要简单的使用 &man.mkdir.1; 命令。 </para> <para>通常, 我们习惯将目录名起成和 @@ -1115,7 +1113,7 @@ bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ <screen>&prompt.root; <userinput>mkdir /var/spool/<replaceable>printer-name</replaceable></userinput></screen> - <para>然而, 如果您有很多网络打印机, + <para>然而, 如果您有很多网络打印机, 您可能想要把这些打印池目录放在一个单独的 您专门为使用 <application>LPD</application> 打印而准备的目录里。 我们 @@ -1132,7 +1130,7 @@ bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ 性, 您可能想保护相应的打印池目录, 使它们 不能被公开访问。 打印池 目录应该被daemon用户拥有, 用户daemon和daemon组拥有读写和 - 搜索的权限, 并且其他用户没有。 + 搜索的权限, 并且其他用户没有。 我们将用我们的两台打印机作为例子:</para> <screen>&prompt.root; <userinput>chown daemon:daemon /var/spool/lpd/rattan</userinput> @@ -1161,7 +1159,7 @@ bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ 用TAB键缩进一次, 写不开需要换行在最后加上反 斜杠。 </para> - <para>如果您没用 + <para>如果您没用 <literal>sd</literal> 标记指定打印池目录, 打印池系统会将 <filename>/var/spool/lpd</filename> 目录作为默认目录。 </para> </sect4> @@ -1173,14 +1171,14 @@ bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ <filename>/dev</filename> 目录下增加设备节点</link> 章节中, 我们确定了使用 <filename>/dev</filename> 目录中的哪个节点来让 FreeBSD 与打印机 - 通讯。 现在, 我们来告诉 + 通讯。 现在, 我们来告诉 <application>LPD</application> 这个 信息。 当打印池系统有任务需要打印, 它 将为过滤程序(负责传送数据到打印机)打开 指定的设备。 </para> - <para>用 <literal>lp</literal> 标记在 <filename>/etc/printcap</filename> 里列出 <filename>/dev</filename> - 下的设备节点 + <para>用 <literal>lp</literal> 标记在 <filename>/etc/printcap</filename> 里列出 <filename>/dev</filename> + 下的设备节点 。</para> <para>在我们的例子中, 假设打印机 @@ -1200,9 +1198,9 @@ bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :lp=/dev/ttyd5:</programlisting> <para>如果您没在您的 <filename>/etc/printcap</filename> 文件中 - 用 <literal>lp</literal> 标记指定设备节点, + 用 <literal>lp</literal> 标记指定设备节点, <application>LPD</application> 将默认使用 <filename>/dev/lp</filename> - 。 + 。 <filename>/dev/lp</filename> 目前在 FreeBSD 中不存在。 </para> @@ -1220,10 +1218,10 @@ bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ <secondary>serial</secondary> </indexterm> - <para>对于连在串口上的打印机, <application>LPD</application> - 可以为发送数据到打印机的过滤程序设置好波特率, + <para>对于连在串口上的打印机, <application>LPD</application> + 可以为发送数据到打印机的过滤程序设置好波特率, 校验, 和其他串口通讯参数 - 。 这是有利的, + 。 这是有利的, 因为:</para> <itemizedlist> @@ -1251,10 +1249,10 @@ bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ <listitem> <para>设置设备的通讯速度为 - <replaceable>bps-rate</replaceable>, 这里 - <replaceable>bps-rate</replaceable> 可以为 50, 75, 110, - 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, - 19200, 38400, 57600, or 115200 比特每秒.</para> + <replaceable>bps-rate</replaceable>, 这里 + <replaceable>bps-rate</replaceable> 可以为 50, 75, 110, + 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, + 19200, 38400, 57600, or 115200 比特每秒。</para> </listitem> </varlistentry> @@ -1263,7 +1261,7 @@ bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ <listitem> <para>设置已打开的中端设备的选项 - 。 &man.stty.1; 将详细 + 。 &man.stty.1; 将详细 讲述可用的选项。 </para> </listitem> </varlistentry> @@ -1274,18 +1272,18 @@ bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ 将设备的特性设置成在 <literal>ms#</literal> 标记后指定的那样。 特别是 <literal>parenb</literal>, - <literal>parodd</literal>, <literal>cs5</literal>, - <literal>cs6</literal>, <literal>cs7</literal>, - <literal>cs8</literal>, <literal>cstopb</literal>, - <literal>crtscts</literal>, 和 <literal>ixon</literal> + <literal>parodd</literal>, <literal>cs5</literal>, + <literal>cs6</literal>, <literal>cs7</literal>, + <literal>cs8</literal>, <literal>cstopb</literal>, + <literal>crtscts</literal>, 和 <literal>ixon</literal> 这些模式, 它们在 &man.stty.1; 手册中有详细说明。 </para> <para>我们举个例子来添加我们连在第6个串口上的 - 打印机。 我们将设波特为38400。 至于模式, - 我们将用 <literal>-parenb</literal> 设置成不校验, - 用 <literal>cs8</literal> 设置成8位字符, - 用 <literal>clocal</literal> 设置成不要调制解调器控制, + 打印机。 我们将设波特为38400。 至于模式, + 我们将用 <literal>-parenb</literal> 设置成不校验, + 用 <literal>cs8</literal> 设置成8位字符, + 用 <literal>clocal</literal> 设置成不要调制解调器控制, 用 <literal>crtscts</literal> 设置成硬件流量控制: </para> <programlisting>bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ @@ -1302,7 +1300,7 @@ bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ <para>我们现在准备告诉 <application>LPD</application> 使用什么文本过滤器 - 给打印机发送任务。 <emphasis> 文本过滤器</emphasis>, + 给打印机发送任务。 <emphasis> 文本过滤器</emphasis>, 也叫 <emphasis> 输入过滤器</emphasis>, 是一个 在 <application>LPD</application> 有一个任务要发给 打印机时运行的程序。 当 <application>LPD</application> @@ -1318,18 +1316,18 @@ bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ <para>对于简单的打印机设置, 文本过滤器可以仅仅是一段 执行 <command>/bin/cat</command> 的 shell 脚本来 - 发送任务到打印机。 + 发送任务到打印机。 FreeBSD 还提供了一个叫做 <filename>lpf</filename> 的过滤器, 它可以处理退格和下划线来 - 使那些可能不能很好处理这类字符流的打印机正常工作。 + 使那些可能不能很好处理这类字符流的打印机正常工作。 而且, 当然, 您可以用任何其他的 您想用的过滤程序。 <command>lpf</command> 过滤器在 <link linkend="printing-advanced-lpf">lpf: 一个文本 过滤器</link> 这节将有详细描述。 </para> - <para>首先, 我们来写一段叫做 - <filename>/usr/local/libexec/if-simple</filename> 的简单 + <para>首先, 我们来写一段叫做 + <filename>/usr/local/libexec/if-simple</filename> 的简单 shell 脚本作为文本过滤器。 用您熟悉的文本编辑器将下面的内容放进 这个文件: </para> @@ -1348,9 +1346,9 @@ exit 2</programlisting> <screen>&prompt.root; <userinput>chmod 555 /usr/local/libexec/if-simple</userinput></screen> <para>然后用 - <literal>if</literal> 标记在 + <literal>if</literal> 标记在 <filename>/etc/printcap</filename> 里告诉 LPD 使用这个脚本。 我们将仍然为 - 一直作为例子的这两台打印机在 + 一直作为例子的这两台打印机在 <filename>/etc/printcap</filename> 里增加这个标记: </para> <programlisting># @@ -1366,17 +1364,16 @@ bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :if=/usr/local/libexec/if-simple:</programlisting> <note> - <para>一份 <filename>if-simple</filename> 脚本 - 的拷贝可以在 <filename - role="directory">/usr/share/examples/printing</filename> - 这个目录中找到。 </para> + <para><filename>if-simple</filename> 脚本的副本可以在 <filename + class="directory">/usr/share/examples/printing</filename> + 目录中找到。</para> </note> </sect4> <sect4> <title>开启 <application>LPD</application></title> - <para>&man.lpd.8; 在 <filename>/etc/rc</filename> 中被运行, + <para>&man.lpd.8; 在 <filename>/etc/rc</filename> 中被运行, 它是否被运行由 <literal>lpd_enable</literal> 这个变量控制。 这个 变量默认是 <literal>NO</literal>。 如果您还没有修改 , 那么增加这行: </para> @@ -1388,17 +1385,17 @@ bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ <screen>&prompt.root; <userinput>lpd</userinput></screen> </sect4> - + <sect4 id="printing-trying"> <title>测试</title> - <para>现在已经基本完成了 - <application>LPD</application> 的基本设置。 - 但不幸的是, 还不是庆祝的时候, + <para>现在已经基本完成了 + <application>LPD</application> 的基本设置。 + 但不幸的是, 还不是庆祝的时候, 因为我们还需要测试设置并且修正所有的 问题。 要测试设置, 尝试打印一些东西。 要 - 用 <application>LPD</application> 系统打印, 您可以 - 使用 &man.lpr.1; 命令, + 用 <application>LPD</application> 系统打印, 您可以 + 使用 &man.lpr.1; 命令, 它可以提交一个任务来打印。 </para> <para>您可以联合使用 &man.lpr.1; 和 the &man.lptest.1; @@ -1412,16 +1409,16 @@ bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ <para>输入: </para> <screen>&prompt.root; <userinput>lptest 20 5 | lpr -P<replaceable>printer-name</replaceable></userinput></screen> - + <para>其中 <replaceable>printer-name</replaceable> 是 在 <filename>/etc/printcap</filename> 中指定的打印机的一个名字 ( 或者一个别名) 。 要测试默认 打印机, 输入 &man.lpr.1; 不带任何 <option>-P</option> - 选项。 同样, 如果您正在测试一台使用 + 选项。 同样, 如果您正在测试一台使用 &postscript; 的打印机, 发送一个 &postscript; 程序到打印机而不是 使用 &man.lptest.1;。 您可以把程序放在一个 - 文件里, 然后输入: <command>lpr - <replaceable>file</replaceable></command>.</para> + 文件里, 然后输入: <command>lpr + <replaceable>file</replaceable></command>。</para> <para>对于一台 &postscript; 打印机, 您应该得到那段程序的 结果。 而如果您使用的 &man.lptest.1;, 则您得到的 @@ -1435,7 +1432,7 @@ $%&'()*+,-./01234567 <para>要更进一步的测试打印机, 尝试下载一些大的 程序 (为基于特定语言的打印机 ) 或者运行 - &man.lptest.1; 并使用不同的参数。 比如, + &man.lptest.1; 并使用不同的参数。 比如, <command>lptest 80 60</command> 将生成 60 行 每行 80 个字符。 </para> @@ -1446,252 +1443,3325 @@ $%&'()*+,-./01234567 </sect3> </sect2> </sect1> - + <sect1 id="printing-advanced"> - <title>Advanced Printer Setup ** 翻译进行中 **</title> - - <para></para> + <title>高级设置</title> + + <para>这部分将描述用来打印特别格式文件, + 页眉, 通过网络打印, 以及对打印机使用限制和 + 记帐。 </para> <sect2 id="printing-advanced-filter-intro"> - <title>Filters ** 翻译进行中 **</title> + <title>过滤器</title> <indexterm> <primary>printing</primary> <secondary>filters</secondary> </indexterm> - - <para></para> + + <para>尽管 <application>LPD</application> 处理网络协议, + 任务排队, 访问控制, + 和打印的其他方面, 但大部分 <emphasis>实际</emphasis> + 工作还是由 <emphasis>过滤器</emphasis>。 过滤器是 + 一种与打印机通讯并且处理设备依赖和特殊需要的 + 程序。 在简单打印机设置这节里, + 我们安装了一个纯文本过滤器 — 一个应该可以用在大多数 + 打印机上的极简单的过滤器 ( <link + linkend="printing-textfilter">安装 + 文本过滤器</link>)。</para> + + <para>然而, 为了进行格式转换, 打印 + 记帐, 适应特殊的打印机, 等等, + 您需要明白过滤器是怎样工作的。 + 在根本上过滤器负责处理这些方面。 + 但坏消息是大多数时候 + <emphasis>您</emphasis> 必须自己提供过滤器。 好消息 + 是很多过滤器通常都已经有了; 当没有的时候, 它们 + 通常也是很好写的。 </para> + + <para>FreeBSD 也提供了一个过滤器, + <filename>/usr/libexec/lpr/lpf</filename>, 可以让大多数可以打印纯文本的 + 打印机工作。 ( 它处理文件里的退格和 + 跳格, 并且进行记帐, 但这基本就是它所有能做的了。 ) + 这里还有几个过滤器和过滤器组件在 FreeBSD + Ports Collection 里。 </para> + + <para>这是在这节里您将找到的内容: </para> + + <itemizedlist> + <listitem> + <para><link linkend="printing-advanced-filters">过滤器是怎样 + 工作的</link>, 设法给出一个过滤器在打印过程中的 + 大致角色。 您应该阅读这节来理解 + 在 <application>LPD</application> 使用过滤器时 + <quote> 表面上看不到 </quote> 的事情。 这个知识 + 能够帮您预期 + 并调试您在为每个打印机安装越来越多的过滤器 + 时可能遇到的问题。 </para> + </listitem> + + <listitem> + <para><application>LPD</application> 默认每个打印机都能 + 打印 + 纯文本。 这就出现一个问题在 &postscript; (或者基于其他 + 语言的打印机) 以及所有无法直接打印纯文本的打印机。 + <link + linkend="printing-advanced-if-conversion">让 + &postscript; 打印机适应纯文本任务 </link> 这节将告诉您 + 要解决这个问题应该做些什么。 如果您使用一台 + &postscript; 打印机, 那么您应该阅读这个小节。 </para> + </listitem> + + <listitem> + <para>&postscript; 对于许多程序来说都是一个非常受欢迎的输出格式。 + 一些人甚至直接写 &postscript; 代码。 但不幸的是, + &postscript; 打印机非常昂贵。 <link + linkend="printing-advanced-ps">模拟 &postscript; 在 + 非 &postscript; 打印机上</link> 这节将告诉您怎样进一步修改 + 打印机的文本过滤器, 使得一台 <emphasis>非 &postscript;</emphasis> 打印机接受 + 并打印 &postscript; 数据。 如果 + 您没有 &postscript; 打印机, 那么您应该阅读这个小节。 </para> + </listitem> + + <listitem> + <para><link + linkend="printing-advanced-convfilters">转换 + 过滤器</link> 这节讲述了一个自动把 + 指定格式文件, 比如图像或排版数据, + 转换成您打印机可以理解的格式。 在阅读了这节 + 之后, 您应该可以设置好您的打印机使得用户可以 + 输入 <command>lpr -t</command> 来打印带有不同宏定义库的文本, 或者用 + <command>lpr -d</command> 来打印 &tex; DVI 数据, 用 <command>lpr + -v</command> 来打印光栅图像数据, 等等。 我推荐您 + 阅读这节。 </para> + </listitem> + + <listitem> + <para><link linkend="printing-advanced-of">输出 + 过滤器</link> 这节讲述了这个不是经常使用的 + <application>LPD</application>: + 的功能-输出过滤器。 除非您要打印页眉 (见 <link + linkend="printing-advanced-header-pages">页眉</link> 这节 ), + 您或许可以完全跳过这节。 </para> + </listitem> + + <listitem> + <para><link linkend="printing-advanced-lpf">lpf: 一个文本 + 过滤器</link> 描述了 <command>lpf</command>, 一个 FreeBSD 自带的相当 + 完整而又简单的文本过滤器, 可以使用在行式打印机 (和那些担当行式打印机功能的激光 + 打印机 ) 上。 如果 + 您需要一个快速的方法来让打印机统计打印纯文本的工作量 + , 或者您有一台遇到退格字符就冒烟的打印机 + , 您应该考虑 + <command>lpf</command> 。 </para> + </listitem> + </itemizedlist> + + <note> + <para>您可以在 <filename + class="directory">/usr/share/examples/printing</filename> + 目录中找到下面将提到的那些脚本的副本。</para> + </note> <sect3 id="printing-advanced-filters"> - <title>How Filters Work ** 翻译进行中 **</title> + <title>过滤器是怎样工作的</title> + + <para>前面说过, 过滤器是一个被 + <application>LPD</application> 启动, 用来处理与打印机通讯过程中设备依赖的部分 + 的可执行程序。 </para> + + <para>当 <application>LPD</application> 想要打印 + 一个任务中的文件, 它启动一个过滤器 + 程序。 它把要打印的文件设置成过滤器的标准输入, + 标准输出设置成打印机, 并且把错误信息定向到 + 错误日志文件 (在 <literal>lf</literal> + 标识里指定, 默认在 <filename>/etc/printcap</filename>, 或者 + <filename>/dev/console</filename> 文件里 )。 </para> + + <indexterm> + <primary><command>troff</command></primary> + </indexterm> + <para>过滤器被 <application>LPD</application> 启动, 并且 + 过滤器的参数依赖于 + <filename>/etc/printcap</filename> 文件中所列出的和 + 用户为任务用 + &man.lpr.1; 命令所指定的。 例如, 如果用户输入 + <command>lpr -t</command>, <application>LPD</application> 会 + 启动 troff 过滤器, 即在 + 目标打印机的 <literal>tf</literal> 标签里所列出的过滤器。 + 如果用户想要打印纯文本, 它将会启动 + <literal>if</literal> ***过滤器 ( 这是通常的情况: 参见 <link + linkend="printing-advanced-of">输出过滤器</link> 来得到 + 细节 ) 。 </para> + + <para>在 + <filename>/etc/printcap</filename> 文件中, 您可以指定三种过滤器: </para> + + <itemizedlist> + <listitem> + <para>The <emphasis> 文本过滤器 </emphasis>, 在 <application>LPD</application> 文档中也叫做 + <emphasis> 输入过滤器 </emphasis> + , 处理 + 常规的文本打印。 可以把它想象成默认过滤器。 + <application>LPD</application> + 默认每台打印机都可以打印纯文本, + 而文本过滤器的任务就是来搞定退格、跳格, + 或者其他在某种打印机上容易错误的特殊字符。 如果您 + 所在的环境对打印机的使用情况进行 + 记帐, 那么文本过滤器必须也对打印进行统计, + 统计通常是通过对打印的行数进行计数然后与打印机所支持的每页的行数做比较后 + 得出的。 文本过滤器 + 的启动命令为: + + <cmdsynopsis> + <command>filter-name</command> + <arg>-c</arg> + <arg choice="plain">-w<replaceable>width</replaceable></arg> + <arg choice="plain">-l<replaceable>length</replaceable></arg> + <arg choice="plain">-i<replaceable>indent</replaceable></arg> + <arg choice="plain">-n <replaceable>login</replaceable></arg> + <arg choice="plain">-h <replaceable>host</replaceable></arg> + <arg choice="plain"><replaceable>acct-file</replaceable></arg> + </cmdsynopsis> + + where + + <variablelist> + <varlistentry> + <term><option>-c</option></term> + + <listitem> + <para>当任务用 <command>lpr + -l</command> 这个命令提交时出现 </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><replaceable>width</replaceable></term> + + <listitem> + <para>这里取您在 <filename>/etc/printcap</filename> 文件中指定的 <literal>pw</literal> (页 + 宽) 标签的值, 默认为 132。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><replaceable>length</replaceable></term> + + <listitem> + <para>这里取您的 <literal>pl</literal> (页 + 长) 标签的值, 默认为 66</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><replaceable>indent</replaceable></term> + + <listitem> + <para>这里是来自 <command>lpr + -i</command> 命令的总缩进量, 默认为 0</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><replaceable>login</replaceable></term> + + <listitem> + <para>这里是正在打印文件的 + 用户名 </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><replaceable>host</replaceable></term> + + <listitem> + <para>这里是提交打印任务的 + 主机名 </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><replaceable>acct-file</replaceable></term> + + <listitem> + <para>这里是来自 + <literal>af</literal> 变量中指定的用于记帐的文件名。</para> + </listitem> + </varlistentry> + </variablelist> + </para> + </listitem> - <para></para> + <indexterm> + <primary>printing</primary> + <secondary>filters</secondary> + </indexterm> + <listitem> + <para><emphasis> 转换过滤器 </emphasis> 将一个特定 + 的文件格式转换成另一种打印机能够理解并且将内容打印出来的格式. + 例如 , ditroff 格式的排版数据就是无法直接打印的, + 但您可以安装一个转换过滤器来将 ditroff 文件转换成 + 一种打印机可以理解并打印的 + 形式. 参考 <link + linkend="printing-advanced-convfilters"> 转换 + 过滤器 </link> 这一节来了解更多细节. 如果您需要对打印进行 + 记帐, 那么转换过滤器也必须完成记帐工作. + 转换过虑器的启动命令为: + + <cmdsynopsis> + <command>filter-name</command> + <arg + choice="plain">-x<replaceable>pixel-width</replaceable></arg> + <arg choice="plain">-y<replaceable>pixel-height</replaceable></arg> + <arg choice="plain">-n <replaceable>login</replaceable></arg> + <arg choice="plain">-h <replaceable>host</replaceable></arg> + <arg choice="plain"><replaceable>acct-file</replaceable></arg> + </cmdsynopsis> + + <replaceable>pixel-width</replaceable> 的值来自 + <literal>px</literal> 标签 (默认为 0), + <replaceable>pixel-height</replaceable> 的值来自 + <literal>py</literal> 标签 (默认为 0)。</para> + </listitem> + + <listitem> + <para><emphasis> 输出过滤器 </emphasis> 仅在没有文本过滤器 + 时, 或者报头页被打开时使用. 就我的 + 经验而言, 输出过滤器是很少用到的. 在<link + linkend="printing-advanced-of"> 输出过滤器 </link> 这节中会 + 介绍它们. 启动输出过滤器的命令行只有两个参数: + + <cmdsynopsis> + <command>filter-name</command> + <arg choice="plain">-w<replaceable>width</replaceable></arg> + <arg choice="plain">-l<replaceable>length</replaceable></arg> + </cmdsynopsis> + + <option>-w</option> 和 + <option>-l</option> 参数的意义和文本过滤器中的一样。</para> + </listitem> + </itemizedlist> + + <para>过滤器也应该在 <emphasis> 退出</emphasis> 时给出下面的 + 几种退出状态:</para> + + <variablelist> + <varlistentry> + <term>exit 0</term> + + <listitem> + <para>过滤器已经成功的打印了文件. </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>exit 1</term> + + <listitem> + <para>过滤器打印失败了, 但想要 + <application>LPD</application> 来 + 试着再打印一次. 如果过滤器返回了这个状态, <application>LPD</application> + 将重新启动一个过滤器。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>exit 2</term> + + <listitem> + <para>过滤器打印失败并且不想要 + <application>LPD</application> 重试. + <application>LPD</application> 将放弃这个文件。</para> + </listitem> + </varlistentry> + </variablelist> + + <para>文本过滤器随 FreeBSD 一起发布, + 文件名为 <filename>/usr/libexec/lpr/lpf</filename>, 它利用 + 页宽和页长参数来决定何时发送送纸指令 + 和为打印记帐的方法. 它使用登陆名, 主机名, + 和记帐文件参数来生成记帐记录。</para> + + <para>如果您想购买过滤器, 要注意它是否是 LPD-兼容的. + 如果是, 则它们必须支持上面提到的那些参数. + 如果您打算编写普通的过滤器程序, 则同样需要让它们 + 支持上面那些参数和退出状态码。</para> </sect3> - + <sect3 id="printing-advanced-if-conversion"> - <title>Accommodating Plain Text Jobs on &postscript; Printers - ** 翻译进行中 **</title> + <title>在 &postscript; 打印机上打印纯文本任务 </title> <indexterm><primary>print jobs</primary></indexterm> - <para></para> + <para>如果您是您的计算机和 &postscript; (或者 + 其他语言的) 打印机的唯一用户, + 而且您不打算发送纯文本到打印机且不打算使用程序里那些会发送纯文本到打印机的功能的话, + 那么您完全不需要再关心这节的内容。</para> + + <para>但是, 如果 &postscript; 和纯文本的任务都需要发送到打印机, + 那么就需要对打印机进行设置了。 要完成工作, + 我们需要一个文本过滤器来检测到达的任务是纯文本的还是 &postscript; + 格式的。 所有 &postscript; 的任务必须以 + <literal>%!</literal> ( 对于其他打印机语言, 参见打印机的文档) + 开头。 如果任务的头两个字符是这两个, + 就代表这是 &postscript; 格式的, 并且可以直接略过任务剩余的部分。 + 如果任务开头的两个字符不是这两个, 那么过滤器将把文本转换成 + &postscript; 并打印结果。</para> + + <para>我们怎样去做?</para> + + <indexterm> + <primary>printers</primary> + <secondary>serial</secondary> + </indexterm> + <para>如果你有一台串行打印机, 一个好办法就是安装 + <command>lprps</command>. <command>lprps</command> + 是一个可以与打印机进行双向通信 &postscript; + 打印机过滤器。 它用打印机传来的详细信息来更新打印机的状态文件, + 所以用户和管理员可以准确的看到打印机处在什么样的状态 (比如 + <errorname>缺墨</errorname> 或者 <errorname>卡纸</errorname>)。 + 但更重要的是, 它包含了一个叫做 <command>psif</command> + 的程序, 它可以检测接收到的文件是否是纯文本的, 并且将使用 + <command>textps</command> 命令 ( 也是由 + <command>lprps</command> 提供的程序) 转换文本到 &postscript;。 然后它会用 + <command>lprps</command> 将任务发送到打印机。</para> + + <para><command>lprps</command> 可以在 FreeBSD Ports Collection + (详见 <link linkend="ports">The Ports Collection</link>) 中找到。 + 您当然可以自己获取, 构建并安装它。 在安装之后 + <command>lprps</command>, 只需指定 + <command>psif</command> 这个程序的路径, 这也是包含在 + <command>lprps</command> 中的一个程序。 如果您已经用 ports 安装好了 + <command>lprps</command>, 将下面的内容添加到 + <filename>/etc/printcap</filename> 文件中 &postscript; + 打印机的记录部分中:</para> + + <programlisting>:if=/usr/local/libexec/psif:</programlisting> + + <para>同时还需要指定 <literal>rw</literal> 标签来告诉 + <application>LPD</application> 使用读-写模式打开打印机。</para> + + <para>如果您有一台并行的 &postscript; 打印机 (因此不能与打印机进行 + <command>lprps</command> 需要的双向通信), 可以使用下面这段 shell + 脚本来充当文本过滤器:</para> + + <programlisting>#!/bin/sh +# +# psif - Print PostScript or plain text on a PostScript printer +# Script version; NOT the version that comes with lprps +# Installed in /usr/local/libexec/psif +# + +IFS="" read -r first_line +first_two_chars=`expr "$first_line" : '\(..\)'` + +if [ "$first_two_chars" = "%!" ]; then + # + # PostScript job, print it. + # + echo "$first_line" && cat && printf "\004" && exit 0 + exit 2 +else + # + # Plain text, convert it, then print it. + # + ( echo "$first_line"; cat ) | /usr/local/bin/textps && printf "\004" && exit 0 + exit 2 +fi</programlisting> + + <para>在上面的脚本中, <command>textps</command> + 命令是一个独立安装的程序用来将纯文本转换成 &postscript;。 + 您可以使用任何您喜欢的文本到 &postscript; 转换程序。 + FreeBSD Ports Collection (详见 <link linkend="ports">Ports Collection</link>) + 中包含了一个功能非常完整的文本到 &postscript; 的转换程序, 它叫做 + <literal>a2ps</literal>。</para> </sect3> - + <sect3 id="printing-advanced-ps"> - <title>Simulating &postscript; on Non &postscript; Printers ** 翻译进行中 **</title> + <title>模拟 &postscript; 在非 &postscript; 打印机上</title> <indexterm> <primary>PostScript</primary> <secondary>emulating</secondary> </indexterm> <indexterm> <primary>Ghostscript</primary></indexterm> - <para></para> + <para>&postscript; 高质量排版和打印的 <emphasis>de facto</emphasis> + 标准。 而 &postscript; 也是一个 + <emphasis> 昂贵 </emphasis> 的标准。 幸好, Aladdin + 开发了一个和 &postscript; 类似的叫做 + <application>Ghostscript</application> 的程序可以用在 FreeBSD 上。 + Ghostscript 可以读取大多数 &postscript; 的文件并处理其中的页面交给多种设备, + 包括许多品牌的非 + PostScript 打印机。 通过安装 Ghostscript 并使用一个特殊的文本过滤器, + 则可以使一台非 &postscript; 打印机用起来就像真的 &postscript; 打印机一样。</para> + + <para>Ghostscript 也包括在 FreeBSD Ports Collection 中, + 如果您想要从这里安装。 您同样可以很容易地获取, 构建, 并安装它。</para> + + <para>要模拟 &postscript;, 文本过滤器要检测是否要打印一个 + &postscript; 文件。 如果不是, 那么过滤器将直接将文件发送到打印机; + 否则, 它会用 Ghostscript 先将文件转换成打印机可以理解的格式。</para> + + <para>这里有一个例子: 下面的脚本是一个针对 + Hewlett Packard DeskJet 500 打印机的文本过滤器。 对于其他打印机, + 替换 <command>gs</command> (Ghostscript) 命令中的 <option>-sDEVICE</option> 参数 + 就可以了。 (输入 <command>gs + -h</command> 来获得当前安装的 Ghostscript 所支持的设备列表。)</para> + + <programlisting>#!/bin/sh +# +# ifhp - Print Ghostscript-simulated PostScript on a DeskJet 500 +# Installed in /usr/local/libexec/ifhp + +# +# Treat LF as CR+LF (to avoid the "staircase effect" on HP/PCL +# printers): +# +printf "\033&k2G" || exit 2 + +# +# Read first two characters of the file +# +IFS="" read -r first_line +first_two_chars=`expr "$first_line" : '\(..\)'` + +if [ "$first_two_chars" = "%!" ]; then + # + # It is PostScript; use Ghostscript to scan-convert and print it. + # + /usr/local/bin/gs -dSAFER -dNOPAUSE -q -sDEVICE=djet500 \ + -sOutputFile=- - && exit 0 +else + # + # Plain text or HP/PCL, so just print it directly; print a form feed + # at the end to eject the last page. + # + echo "$first_line" && cat && printf "\033&l0H" && +exit 0 +fi + +exit 2</programlisting> + + <para>最后, 需要告知 <application>LPD</application> + 所使用的过滤器, 通过 <literal>if</literal> 标签完成:</para> + + <programlisting>:if=/usr/local/libexec/ifhp:</programlisting> + + <para>您可以输入 <command>lpr plain.text</command> 和 + <filename>lpr whatever.ps</filename>, 它们都应该可以成功打印。</para> </sect3> - + <sect3 id="printing-advanced-convfilters"> - <title>Conversion Filters ** 翻译进行中 **</title> + <title>转换过滤器 </title> + + <para>在完成了 <link + linkend="printing-simple"> 打印机简单设置 </link> 这节中所描述的内容之后, 头一件事 + 恐怕就是为你喜爱的格式的文件安装转换过滤器了 (除了纯 ASCII 文本)。</para> + + <sect4> + <title>为什么安装转换过滤器?</title> + <indexterm> + <primary>&tex;</primary> + <secondary>printing DVI files</secondary> + </indexterm> + + <para>转换过滤器使打印众多格式的文件变得很容易。 + 比如, 假设我们大量使用 &tex; + 排版系统, 并且有一台 &postscript; 打印机。 + 每次从 &tex; 生成一个 DVI 文件, + 我们都不能直接打印它直到我们将 DVI 文件转换成 &postscript;。 + 转换的命令应该是下面的样子:</para> + + <screen>&prompt.user; <userinput>dvips seaweed-analysis.dvi</userinput> +&prompt.user; <userinput>lpr seaweed-analysis.ps</userinput></screen> + + <para>通过安装 DVI 文件的转换过滤器, 我们可以跳过每次手动转换这一步, 而让 + <application>LPD</application> 来完成这个步骤。 + 现在, 每次要打印 DVI 文件, 我们只需要一步就可以打印它:</para> + + <screen>&prompt.user; <userinput>lpr -d seaweed-analysis.dvi</userinput></screen> + + <para>我们要 <application>LPD</application> 转换 DVI 文件是通过指定 + <option>-d</option> 选项完成的。 <link + linkend="printing-lpr-options-format">格式和转换 + 选项</link> 这一节列出了所有的转换选项。</para> + + <para>对于每种想要打印机支持的转换, + 首先要安装 <emphasis> 转换过滤器 </emphasis> 然后在 + <filename>/etc/printcap</filename> 中指定它的路径。 + 在简单打印设置中, 转换过滤器类似于文本过滤器 + (详见 <link linkend="printing-textfilter"> 安装文本过滤器 </link>) + 不同的是它不是用来打印纯文本, + 而是将一个文件转换成打印机能够理解的格式。</para> + </sect4> + + <sect4> + <title>我应该安装哪个转换过滤器?</title> + + <para>您应该安装您希望使用的转换过滤器。 + 如果要打印很多 DVI 数据, 就需要 DVI 转换过滤器; + 如果有大量的 troff 数据, + 就应该安装 troff 过滤器。</para> + + <para>下面的表格总结了可以与 + <application>LPD</application>配合 + 工作的过滤器, 以及它们在 + <filename>/etc/printcap</filename>文件中的变量名, 还有如何在 + <command>lpr</command>命令中调用它们:</para> + + <informaltable frame="none" pgwide="1"> + <tgroup cols="3"> + <thead> + <row> + <entry>文件类型</entry> + <entry>在<filename>/etc/printcap</filename>文件中的变量名</entry> + <entry>在<command>lpr</command>命令中调用使用的参数</entry> + </row> + </thead> + + <tbody> + <row> + <entry>cifplot</entry> + <entry><literal>cf</literal></entry> + <entry><option>-c</option></entry> + </row> + + <row> + <entry>DVI</entry> + <entry><literal>df</literal></entry> + <entry><option>-d</option></entry> + </row> + + <row> + <entry>plot</entry> + <entry><literal>gf</literal></entry> + <entry><option>-g</option></entry> + </row> + + <row> + <entry>ditroff</entry> + <entry><literal>nf</literal></entry> + <entry><option>-n</option></entry> + </row> + + <row> + <entry>FORTRAN text</entry> + <entry><literal>rf</literal></entry> + <entry><option>-f</option></entry> + </row> + + <row> + <entry>troff</entry> + <entry><literal>tf</literal></entry> + <entry><option>-f</option></entry> + </row> + + <row> + <entry>raster</entry> + <entry><literal>vf</literal></entry> + <entry><option>-v</option></entry> + </row> + + <row> + <entry>plain text</entry> + <entry><literal>if</literal></entry> + <entry>none, <option>-p</option>, or + <option>-l</option></entry> + </row> + </tbody> + </tgroup> + </informaltable> + + <para>在例子中, <command>lpr -d</command>就是指 + 打印机需要在<filename>/etc/printcap</filename>文件中 + <literal>df</literal>变量所指的过滤器。</para> + + <indexterm><primary>FORTRAN</primary></indexterm> + <para>不管别人怎么说, 像 FORTRAN 的文本 + 和 plot 这些格式已经基本不用了。 所以在您的机器上, + 就可以安装其他的过滤器来替换这些参数原有的意义。 + 例如, 假设想要能直接打印 + Printerleaf 文件 (由 Interleaf desktop + publishing 程序生成), 而且不打算打印 plot 文件, + 就可以安装一个 Printerleaf 转换过滤器并且用 + <literal>gf</literal> 变量指定它。 然后就可以告诉您的用户使用 + <command>lpr -g</command> 就可以 <quote>打印 Printerleaf + 文件。</quote></para> + </sect4> + + <sect4> + <title>安装转换过滤器</title> + + <para>以为安装的转换过滤器不是 FreeBSD 基本系统的一部分, + 所以它们可能是在 + <filename>/usr/local</filename> 目录下。 通常目录 + <filename>/usr/local/libexec</filename> 是保存它们的地方, + 因为它们通常是通过 + <application>LPD</application> 运行的; + 普通用户没有并不需要直接运行它们。</para> + + <para>要启用一个转换过滤器, 只需要在 + <filename>/etc/printcap</filename> + 文件中为目标打印机中合适的变量赋上过滤器所在的路径。</para> + + <para>在接下来的例子当中, 我们将为 + 一台叫做 <literal>bamboo</literal> 的打印机添加一个转换过滤器。 + 下面是这个例子的 <filename>/etc/printcap</filename> 文件, + 其中使用新变量 <literal>df</literal> 来为打印机 + <literal>bamboo</literal> 设置转换过滤器.</para> + + <programlisting># +# /etc/printcap for host rose - added df filter 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:\ + :lp=/dev/ttyd5:ms#-parenb cs8 clocal crtscts:rw:\ + :if=/usr/local/libexec/psif:\ + :df=/usr/local/libexec/psdf:</programlisting> + + <para>这里的 DVI 过滤器是一段 shell 脚本, 名字叫做 + <filename>/usr/local/libexec/psdf</filename>。 + 下面是它的代码:</para> + + <programlisting>#!/bin/sh +# +# psdf - DVI to PostScript printer filter +# Installed in /usr/local/libexec/psdf +# +# Invoked by lpd when user runs lpr -d +# +exec /usr/local/bin/dvips -f | /usr/local/libexec/lprps "$@"</programlisting> + + <para>这段脚本以过滤器模式运行 <command>dvips</command> (参数 + <option>-f</option> ) 并从标准输入读取要打印的任务。 + 然后运行 &postscript; 文本过滤器 + <command>lprps</command> (详见 <link + linkend="printing-advanced-if-conversion">在 + &postscript; 打印机上打印纯文本任务</link> 这一节), 并且带着 + <application>LPD</application> + 传给脚本的全部参数。 <command>lprps</command> + 将利用这些参数来为打印进行记帐。</para> + </sect4> + + <sect4> + <title>更多转换过滤器应用实例</title> + + <para>因为安装转换过滤器的步骤并不是固定的, + 所以这里会多给出一些例子。 + 在以后的安装配置过程中可以以这些例子为参考。 + 甚至如果合适的话, 可以完全照搬过去。</para> + + <para>这段例子中的脚本是一个 + Hewlett Packard LaserJet III-Si + 打印机的光栅格式数据 (实际上也就是 GIF 文件):</para> + + <programlisting>#!/bin/sh +# +# hpvf - Convert GIF files into HP/PCL, then print +# Installed in /usr/local/libexec/hpvf + +PATH=/usr/X11R6/bin:$PATH; export PATH +giftopnm | ppmtopgm | pgmtopbm | pbmtolj -resolution 300 \ + && exit 0 \ + || exit 2</programlisting> + + <para>它的工作原理就是将 GIF 文件转换成 portable anymap, + 再转换成 portable graymap, 然后再转换成 + portable bitmap, 最后再转换成 LaserJet/PCL- 兼容的数据。</para> + + <para>下面是为打印机配置上上述过滤器的 <filename>/etc/printcap</filename> + 文件:</para> + + <programlisting># +# /etc/printcap for host orchid +# +teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\ + :lp=/dev/lpt0:sh:sd=/var/spool/lpd/teak:mx#0:\ + :if=/usr/local/libexec/hpif:\ + :vf=/usr/local/libexec/hpvf:</programlisting> + + <para>下面的脚本是一个在名叫 + <literal>bamboo</literal> 的这台 &postscript; + 打印机上打印用 groff 排版软件生成的 troff 数据的打印过滤器:</para> + + <programlisting>#!/bin/sh +# +# pstf - Convert groff's troff data into PS, then print. +# Installed in /usr/local/libexec/pstf +# +exec grops | /usr/local/libexec/lprps "$@"</programlisting> + + <para>上面这段脚本还是用 <command>lprps</command> + 来与打印机进行通讯。 如果打印机是接在并口上的, + 那么就应该使用下面的这段脚本:</para> + + <programlisting>#!/bin/sh +# +# pstf - Convert groff's troff data into PS, then print. +# Installed in /usr/local/libexec/pstf +# +exec grops</programlisting> + + <para>这里是我们要启用过滤器需要在 + <filename>/etc/printcap</filename> 里增加的内容:</para> + + <programlisting>:tf=/usr/local/libexec/pstf:</programlisting> + + <para>下面的例子也许会让许多 FORTRAN 老手羞愧。 + 它是一个 FORTRAN- 文本 的过滤器, 能在任意一台 + 可以打印纯文本的打印机上使用。 我们将为打印机 + <literal>teak</literal> 安装这个过滤器:</para> + + <programlisting>#!/bin/sh +# +# hprf - FORTRAN text filter for LaserJet 3si: +# Installed in /usr/local/libexec/hprf +# + +printf "\033&k2G" && fpr && printf "\033&l0H" && + exit 0 +exit 2</programlisting> + + <para>然后我们要在 + <filename>/etc/printcap</filename> 中为打印机能够 + <literal>teak</literal> 启用这个过滤器添加下面的内容:</para> + + <programlisting>:rf=/usr/local/libexec/hprf:</programlisting> + + <para>最后, 再给出一个有些复杂的例子。 我们将给以前介绍过的 + <literal>teak</literal> 这台激光打印机添加一个 DVI + 过滤器。 首先, 最容易的部分: 更新 + <filename>/etc/printcap</filename> 加入 DVI + 过滤器的路径:</para> + + <programlisting>:df=/usr/local/libexec/hpdf:</programlisting> + + <para>现在, 该困难的部分了: 编写过滤器。 为了实现过滤器, 我们需要一个 + DVI-到-LaserJet/PCL 转换程序。 FreeBSD Ports + Collection (详见 <link linkend="ports">Ports Collection</link> 这一节) + 中有一个包: <command>dvi2xx</command> 是这个包的名称。 + 安装这个包就会得到我们需要的程序, + <command>dvilj2p</command> , 它可以将 DVI 数据转换成 LaserJet IIp, + LaserJet III, 和 LaserJet 2000 兼容的数据。</para> + + <para><command>dvilj2p</command> 使得过滤器 + <command>hpdf</command> 变得十分复杂, 因为 + <command>dvilj2p</command> 不能读取标准输入。 + 它需要从文件中读取数据。 更糟糕的是, 这个文件的名字必须以 + <filename>.dvi</filename> 结尾。 所以使用 + <filename>/dev/fd/0</filename> 作为标准输入是有问题的。 + 我们可以通过连接 (符号连接) 来解决这个问题。 连接一个临时的文件名 + (一个以 <filename>.dvi</filename> 结尾的文件名) + 到 <filename>/dev/fd/0</filename>, 从而强制 + <command>dvilj2p</command> 从标准输入读取。</para> + + <para>现在迎面而来的是另外一个问题, 我们不能使用 + <filename>/tmp</filename> 存放临时连接。 符号连接是被用户和组 + <username>bin</username> 拥有的。 而过滤器则是以 + <username>daemon</username> 用户运行的。 + 并且 <filename>/tmp</filename> 目录设置了 sticky 位。 + 所以过滤器只能建立符号连接, + 但它不能在用完之后清除掉这些连接。 + 因为它们属于不同的用户。</para> + + <para>所以过滤器将在当前工作目录下建立符号连接, + 即打印池目录 (用变量 + <literal>sd</literal> 在 + <filename>/etc/printcap</filename> 中指定)。 + 这是一个非常好的让过滤器完成它工作的地方, + 特别还是因为 (有时) 这个目录比起 + <filename>/tmp</filename> 来有更多的可用磁盘空间。</para> + + <para>最后, 给出过滤器的代码:</para> + + <programlisting>#!/bin/sh +# +# hpdf - Print DVI data on HP/PCL printer +# Installed in /usr/local/libexec/hpdf + +PATH=/usr/local/bin:$PATH; export PATH + +# +# Define a function to clean up our temporary files. These exist +# in the current directory, which will be the spooling directory +# for the printer. +# +cleanup() { + rm -f hpdf$$.dvi +} + +# +# Define a function to handle fatal errors: print the given message +# and exit 2. Exiting with 2 tells LPD to do not try to reprint the +# job. +# +fatal() { + echo "$@" 1>&2 + cleanup + exit 2 +} + +# +# If user removes the job, LPD will send SIGINT, so trap SIGINT +# (and a few other signals) to clean up after ourselves. +# +trap cleanup 1 2 15 + +# +# Make sure we are not colliding with any existing files. +# +cleanup + +# +# Link the DVI input file to standard input (the file to print). +# +ln -s /dev/fd/0 hpdf$$.dvi || fatal "Cannot symlink /dev/fd/0" + +# +# Make LF = CR+LF +# +printf "\033&k2G" || fatal "Cannot initialize printer" + +# +# Convert and print. Return value from dvilj2p does not seem to be +# reliable, so we ignore it. +# +dvilj2p -M1 -q -e- dfhp$$.dvi - <para></para> +# +# Clean up and exit +# +cleanup +exit 0</programlisting> + </sect4> <sect4 id="printing-advanced-autoconv"> - <title>Automated Conversion: an Alternative to Conversion - Filters ** 翻译进行中 **</title> + <title>自动转换: 一种替代转换过滤器的方法</title> + + <para>以上这些转换过滤器基本上建成了您的打印环境, + 但也有不足就是必须由用户来指定 + (在 &man.lpr.1; 命令行中) 要使用哪一个过滤器。 + 如果您的用户不是对计算机很在行, + 那么选用过滤器将是一件麻烦的事情。 + 更糟的是, 当过滤器设定的不正确时, + 过滤器被用在了不它对应类型的文件上, + 打印机也许会喷出上百张纸。</para> - <para></para> + <para>比只安装转换过滤器更好的方法, + 就是让文本过滤器 (因为它是默认的过滤器) + 来检测要打印文件的类型, + 然后自动运行正确的转换过滤器。 像 + <command>file</command> 这样的工具可以给我们一定的帮助。 当然, + 要区分开 + <emphasis>有些</emphasis> 文件的类型还是有困难的 — 而且, 当然, + 您可以仅为它们提供转换过滤器。</para> + + <indexterm><primary>apsfilter</primary></indexterm> + <indexterm> + <primary>printing</primary> + <secondary>filters</secondary> + <tertiary>apsfilter</tertiary> + </indexterm> + <para>FreeBSD Ports Collection 包含了一个可以自动进行转换的文本过滤器, + 名字叫做 <command>apsfilter</command> 。 + 它可以检测出纯文本, &postscript;, 和 DVI 格式的文件, + 并且运行相应的转换过滤器, 然后打印。</para> </sect4> </sect3> <sect3 id="printing-advanced-of"> - <title>Output Filters ** 翻译进行中 **</title> - - <para></para> + <title>输出过滤器</title> + + <para><application>LPD</application> 打印池系统还支持一种我们还没有讨论过的过滤器: + 输出过滤器。 + 输出过滤器只是用来打印纯文本的, 类似于文本过滤器, + 但简化了许多地方。 如果您正在使用输出过滤器而不是文本过滤器, + 那么:</para> + + <itemizedlist> + <listitem> + <para><application>LPD</application> 为整个任务启动一个输出过滤器, + 而不是为任务中的每个文件都启动一次。</para> + </listitem> + + <listitem> + <para><application>LPD</application> 不会提供任务中文件开始和结束的信息给输出过滤器。</para> + </listitem> + + <listitem> + <para><application>LPD</application> 不会提供用户名或者主机名给过滤器, + 所以它是无法做打印记帐的。 + 事实上它只有两个参数:</para> + + <cmdsynopsis> + <command>过滤器-名字</command> + <arg choice="plain">-w<replaceable>宽度</replaceable></arg> + <arg choice="plain">-l<replaceable>长度</replaceable></arg> + </cmdsynopsis> + + <para><replaceable>宽度</replaceable> 来自于 + <literal>pw</literal> 变量, 而 + <replaceable>length</replaceable> 来自于 + <literal>pl</literal> 变量, + 这些值都是实际问题中给打印机设置的。</para> + </listitem> + </itemizedlist> + + <para>不要让输出过滤器的简化所耽误。 + 如果想要输出过滤器完成让任务中的每个文件都重新开始一页打印是 + <emphasis>不可能</emphasis> 的。 请使用文本过滤器 + (也叫输入过滤器); 详见 <link + linkend="printing-textfilter">安装文本过滤器</link> 。 + 此外, 实际上, 输出过滤器 <emphasis>更复杂</emphasis> , + 它要检查发给它的字节流中是否有特殊的标志字符, + 并且给自己发送信号来代替 + <application>LPD</application> 的。</para> + + <para>可是, 如果打算要报头页或者需要发送控制字符或者其他的初始化字符串来完成打印报头页, + 那么输出过滤器则是 <emphasis>必需的</emphasis> 。 + (但是它也是 + <emphasis>无用的</emphasis> 如果打算对打印的用户计费, 因为 + <application>LPD</application> 不会给输出过滤器任何用户或者主机的信息。)</para> + + <para>在一台单个的打印机上, <application>LPD</application> + 同时允许输出过滤器、 文本过滤器和其他的过滤器。 + 在某些情况下, <application>LPD</application> 将仅会启动输出过滤器来打印报头页 (详见 <link + linkend="printing-advanced-header-pages">报头页</link>)。 + 然后 <application>LPD</application> 会要求输出过滤器 <emphasis>自己停止运行</emphasis> , + 它发送给过滤器两个字节: ASCII 031跟着一个 + ASCII 001。 当输出过滤器看见这两个字节 + (031, 001), 它应该通过发送 <literal>SIGSTOP</literal> + 信号来停止自己的运行。 当 + <application>LPD</application> + 已经运行好了其他的过滤器, 它会通过给输出过滤器发送 <literal>SIGCONT</literal> 信号来让输出过滤器重新运行。</para> + + <para>如果仅有一个输出过滤器而 <emphasis>没有</emphasis> + 文本过滤器, 并且 <application>LPD</application> 正在处理一个纯文本任务, + <application>LPD</application> 会使用输出过滤器来完成这个任务。 + 像以前运行一样, + 输出过滤器会按顺序打印任务中的文件, + 而不会插入送纸或其他进纸的命令, 但这也许并 + <emphasis>不是</emphasis> 您想要的结果。 在大多数情况下, + 您还是需要一个文本过滤器。</para> + + <para><command>lpf</command> 这个我们前面介绍过的文本过滤器程序, + 也可以用来做输出过滤器。 如果需要使用快速且混乱的输出过滤器, + 但又不想写字节检测和信号发送代码, + 那么试试 <command>lpf</command>。 + <command>lpf</command> 也可以包含在一个 shell 脚本中来处理任何打印机可能需要的初始化代码。</para> </sect3> <sect3 id="printing-advanced-lpf"> - <title><command>lpf</command>: a Text Filter ** 翻译进行中 **</title> - - <para></para> + <title><command>lpf</command>: 一个文本过滤器</title> + + <para><filename>/usr/libexec/lpr/lpf</filename> 这个程序包含在 + FreeBSD 的二进制程序中, 它是一个文本过滤器 (输入过滤器)。 + 它可以缩排输出 (用 <command>lpr + -i</command> 命令提交的任务), 可以打印控制字符禁止断页 + 用 <command>lpr -l</command> 提交的任务), + 可以调整任务中退格和制表符打印的位置, 还可以对打印进行记帐。 + 它同样可以像输出过滤器一样工作。</para> + + <para><command>lpf</command> 适用于很多打印环境。 + 尽管它本身没有向打印机发送初始化代码的功能, + 但写一个 shell + 脚本来完成所需的初始化并执行 + <command>lpf</command> 是很容易的。</para> + + <indexterm><primary>page accounting</primary></indexterm> + <indexterm> + <primary>accounting</primary> + <secondary>printer</secondary> + </indexterm> + <para>为了让 <command>lpf</command> 可以正确的进行打印记帐, + 那么需要 <filename>/etc/printcap</filename> 中的 <literal>pw</literal> 和 <literal>pl</literal> 变量都填入正确的值。 + 它用这些值来测定一页能打印多少文本, + 并计算出任务有多少页。 + 想得到更多关于打印记帐的信息, 请参见 <link + linkend="printing-advanced-acct">对打印机使用进行记帐</link>。</para> </sect3> </sect2> <sect2 id="printing-advanced-header-pages"> - <title>Header Pages ** 翻译进行中 **</title> + <title>报头页</title> - <para></para> + <para>如果您有 <emphasis>很多</emphasis> 用户, 他们正在使用各式各样的打印机, + 那么您允许要考虑一下把 <emphasis>报头页</emphasis> 当作一个必要的麻烦了。</para> + + <indexterm> + <primary>banner pages</primary> + <see>header pages</see> + </indexterm> + <indexterm><primary>header pages</primary></indexterm> + <para>报头页, 也叫 <emphasis>banner</emphasis> 或者 + <emphasis>burst 页</emphasis>, 可以用来辨别打印出的文件是谁打印的。 + 它们通常用大号的粗体字母打印出来, + 也可能用装饰线围绕四周, 所以在一堆打印出的文件中, + 突出的显示了这个文件属于哪个用户的哪个任务。 + 这可以让用户快速的找到他们的任务。 而报头页一个明显的缺点就是, + 在每个任务中都要有一张或者几张纸作为报头页印出来, + 可是它们的有用的地方只发挥几分钟的作用, + 最后它们会被放进回收站或者扔进垃圾堆。 + (注意报头页只是一个任务一个, 而不是任务中的每个文件都有一个, + 所以可能对纸张还不算很浪费。)</para> + + <para><application>LPD</application> 系统可以自动为您的打印提供报头页, + <emphasis>如果</emphasis> 您的打印机可以直接打印纯文本。 + 如果您的打印机是一台 &postscript; 打印机, + 您将需要一个外部的程序来生成报头页; 详见 <link + linkend="printing-advanced-header-pages-ps">在 &postscript; 打印机上打印报头页</link>。</para> <sect3 id="printing-advanced-header-pages-enabling"> - <title>Enabling Header Pages ** 翻译进行中 **</title> + <title>打开报头页</title> + + <para>在 <link linkend="printing-simple">简单打印设置</link> + 这节, 我们通过在 <filename>/etc/printcap</filename> 文件中指定 + <literal>sh</literal> (<quote>禁止报头页</quote>) 来把报头页功能关掉了。 + 要重新为打印机开启报头页功能, + 只需要删除掉 <literal>sh</literal>。</para> - <para></para> + <para>听起来很容易, 不是么?</para> + + <para>是的。 您 <emphasis>可能</emphasis> 不得不让输出过滤器来给打印机发送初始化字符串。 + 下面是一个用在 Hewlett Packard PCL-兼容打印机上的输出过滤器的例子:</para> + + <programlisting>#!/bin/sh +# +# hpof - Output filter for Hewlett Packard PCL-compatible printers +# Installed in /usr/local/libexec/hpof + +printf "\033&k2G" || exit 2 +exec /usr/libexec/lpr/lpf</programlisting> + + <para>用 + <literal>of</literal> 变量指定输出过滤器的路径。 参见 <link + linkend="printing-advanced-of">输出过滤器</link> 这一节来得到更多信息。</para> + + <para>下面是一个为我们以前介绍的叫做 <literal>teak</literal> + 的打印机配置的 <filename>/etc/printcap</filename> 文件; + 在配置当中我们开启了报头页并且加入了上述的打印过滤器:</para> + + <programlisting># +# /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:</programlisting> + + <para>现在, 当用户再发任务给打印机 <literal>teak</literal> 的时候, + 每个任务都会有一个报头页。 如果用户想要花时间来寻找他们自己打印的文件, + 那么他们可以通过 + <command>lpr -h</command> 命令来提交任务; 参考 <link + linkend="printing-lpr-options-misc">报头页选项</link> + 这一节来得到更多关于 &man.lpr.1; 的选项。</para> + + <note> + <para><application>LPD</application> 在报头页之后发出一个换纸字符。 + 如果您的打印机使用一个不同的字符或者字符串当作退纸指令, + 在 <filename>/etc/printcap</filename> 中用 <literal>ff</literal> + 变量指定即可。</para> + </note> </sect3> <sect3 id="printing-advanced-header-pages-controlling"> - <title>Controlling Header Pages ** 翻译进行中 **</title> + <title>控制报头页</title> - <para></para> + <para>通过启用报头页, <application>LPD</application> + 将生成出一个 <emphasis>长报头</emphasis>, + 一整页的大字母, 标着用户, 主机和任务名。 + 下面是一个例子 (kelly 打印了用主机 + <hostid>rose</hostid> 打印了一个叫做 outline 的任务):</para> + + <programlisting> 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 + k k e e l l y yy + k k eeee lll lll yyy y + y + y y + yyyy + + + ll + t l i + t l + oooo u u ttttt l ii n nnn eeee + o o u u t l i nn n e e + o o u u t l i n n eeeeee + o o u u t l i n n e + o 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</programlisting> + + <para><application>LPD</application> 会附加一个换页符在这段文本之后, + 所以任务会在新的一页上开始 + (除非设置了 <literal>sf</literal> (禁止换纸) + 在 <filename>/etc/printcap</filename> + 文件里目标打印机的记录中)。</para> + + <para>如果您喜欢, <application>LPD</application> + 可以生成一个 <emphasis>短报头</emphasis>; + 指定 <literal>sb</literal> (短 banner) + 在文件 <filename>/etc/printcap</filename> 中。 + 报头页就会看起来像下面这样:</para> + + <programlisting>rose:kelly Job: outline Date: Sun Sep 17 11:07:51 1995</programlisting> + + <para>同样是默认的, <application>LPD</application> + 也是先打印报头页, 然后才是任务。 + 要想反过来, 在 <filename>/etc/printcap</filename> + 中指定 <literal>hl</literal> (最后报头) 。</para> </sect3> <sect3 id="printing-advanced-header-pages-accounting"> - <title>Accounting for Header Pages ** 翻译进行中 **</title> - - <para></para> + <title>为带报头页的任务记帐</title> + + <para>使用 <application>LPD</application> + 内置的报头页会在进行打印记帐的时候产生一种特殊情况: + 报头页肯定是 + <emphasis>免费</emphasis> 的。</para> + + <para>为什么?</para> + + <para>因为输出过滤器是仅有的一个在打印报头页时能进行记帐的外部程序, + 但却没有提供给它任何 <emphasis>用户或者主机</emphasis> + 的信息或者记帐文件, 所以它无法知道谁应该为打印机的使用付费。 + 如果仅仅是 + <quote>增加一页</quote> 给文本过滤器或者其他过滤器 + (它们有用户和主机的信息) 是不够的, 因为 + 用户可以用 <command>lpr -h</command> 命令跳过报头页。 + 他还是需要为自己并没有打印的报头页付钱。 + 基本上, <command>lpr -h</command> 是明知用户的首选, + 但也不能强制让别人使用它。</para> + + <para>让每个过滤器生成自己的报头页 + (因此可以为它们计费) 是 <emphasis>仍然不够的</emphasis>。 + 如果用户想要用 <command>lpr -h</command> + 命令禁止报头页, 它们将仍然印出报头页并且为它们付费。 + 因为 <application>LPD</application> + 不会把 + <option>-h</option> 这个参数传给任何过滤器。</para> + + <para>这样, 您该怎么办呢?</para> + + <para>您可以:</para> + + <itemizedlist> + <listitem> + <para>认可 <application>LPD</application> 的这个问题, + 并且免费提供报头页打印。</para> + </listitem> + + <listitem> + <para>安装一个替代 <application>LPD</application> 的软件, + 比如 + <application>LPRng</application>。 参考 + <link linkend="printing-lpd-alternatives">替换标准的打印池软件</link> + 来得到更多关于可以替代 <application>LPD</application> 的软件的信息。 + </para> + </listitem> + + <listitem> + <para>写一个 <emphasis>聪明的</emphasis> 输出过滤器。 + 通常, 输出过滤器不应该去完成除了初始化打印机或者进行一些简单字符转换以外的任何事情。 + 它适合完成报头页和纯文本任务 + (当没有文本 (输入) 过滤器时)。 + 但是, 如果有文本过滤器为纯文本任务服务, + 那么 <application>LPD</application> 将仅为打印报头页启动输出过滤器。 + 而且, 这个输出过滤器可以理解报头页里 + <application>LPD</application> 生成的信息, + 然后决定哪位用户和主机应该为报头页付费。 + 这种方法仅有的问题是输出过滤器仍然不知道应该使用什么记帐文件 + (<literal>af</literal> 变量的内容并没有被传递过来), + 但是如果您有一个众所周知的记帐文件, + 就可以直接把文件名写进输出过滤器。 + 为了简化解释报头的步骤, + 我们定义 <literal>sh</literal> (短报头) 变量在 + <filename>/etc/printcap</filename> 文件中。 + 但这些还是太麻烦了, + 而且用户也更喜欢让他们免费打印报头页的慷慨的系统管理员。</para> + </listitem> + </itemizedlist> </sect3> <sect3 id="printing-advanced-header-pages-ps"> - <title>Header Pages on &postscript; Printers ** 翻译进行中 **</title> + <title>在 &postscript; 打印机上打印报头页</title> + + <para>像上面描述的那样,<application>LPD</application> + 可以生成一个纯文本的报头页来适应多种打印机。 + 当然, &postscript; 不能直接打印纯文本, + 所以 <application>LPD</application> 没什么用—或者说大多时候是这样。</para> + + <para>一个显而易见的方法来得到报头页就是让每个转换过滤器和文本过滤器都来生成报头页。 + 这些过滤器应该用用户名和主机的参数来生成一个相对应的报头页。 + 这种方法的缺点就是用户总是打印出报头页, + 无论他们是否用 <command>lpr + -h</command> 命令来提交的任务。</para> + + <para>让我们来深入深入的研究一下这个方法。 + 下面的脚本输入三个参数 + (用户登陆名, 主机名, 和任务名) + 然后生成一个简单的 &postscript; 报头页:</para> + + <programlisting>#!/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 + +# +# Check arguments +# +if [ $# -ne 3 ]; then + echo "Usage: `basename $0` <user> <host> <job>" 1>&2 + exit 1 +fi - <para></para> +# +# Save these, mostly for readability in the PostScript, below. +# +user=$1 +host=$2 +job=$3 +date=`date` + +# +# Send the PostScript code to stdout. +# +exec cat <<EOF +%!PS + +% +% Make sure we do not interfere with user's job that will follow +% +save + +% +% Make a thick, unpleasant border around the edge of the paper. +% +$border $border moveto +$page_width $border 2 mul sub 0 rlineto +0 $page_height $border 2 mul sub rlineto +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 +($user) show + +% +% Now show the boring particulars +% +/Helvetica findfont 14 scalefont setfont +/y 200 def +[ (Job:) (Host:) (Date:) ] { +200 y moveto show /y y 18 sub def } +forall + +/Helvetica-Bold findfont 14 scalefont setfont +/y 200 def +[ ($job) ($host) ($date) ] { + 270 y moveto show /y y 18 sub def +} forall + +% +% That is it +% +restore +showpage +EOF</programlisting> + + <para>现在, 每个转换过滤器和文本过滤器都能调用这段脚本来生成报头页, + 然后打印用户的任务。 + 下面是我们早些时候在这个文档中提到的 + DVI 转换过滤器, 被修改之后来生成一个报头页:</para> + + <programlisting>#!/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" +[ "$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</programlisting> + + <para>过滤器是怎样解释参数列表来决定用户名和主机名的。 + 解释的方法对于其他转换过滤器来说也是一样的。 + 尽管文本过滤器需要输入的参数有些小的不同, + (参见 <link + linkend="printing-advanced-filters">过滤器是怎样工作的</link>)。</para> + + <para>像我们以前提到的那样, 上面的配置, 尽管相当简单, + 关掉了 <quote>禁止报头页</quote> 的选项 + (<option>-h</option> 选项) 在 <command>lpr</command> 中。 + 如果用户想要保护树木 (或者是几便士, 如果你对打印报头页收费的话), + 它还不能完成这件事情, 因为每个过滤器都要为每个任务打印一个报头页。</para> + + <para>要允许用户对于每个任务都可以关闭报头页, + 您需要使用在 <link + linkend="printing-advanced-header-pages-accounting">为报头页记帐</link> + 这节中介绍的那种技巧: + 写一个输出过滤器来解释 LPD- 生成的报头页并且生成一个 &postscript; 的版本。 + 如果用户用 + <command>lpr -h</command> 命令提交任务, 那么 + <application>LPD</application> 将不会生成报头页, + 并且输出过滤器也不会生成报头页。 + 否则, 输出过滤器将从 + <application>LPD</application> 读取文本, + 然后发送适当的报头页的 &postscript; 编码给打印机。</para> + + <para>如果您有的是一台连在串口上的 &postscript; 打印机, + 您可以使用 <command>lprps</command> 里的一个输出过滤器, + <command>psof</command> , 它可以完成上述任务。 但注意 + <command>psof</command> 不对报头页计费。</para> </sect3> </sect2> <sect2 id="printing-advanced-network-printers"> - <title>Networked Printing ** 翻译进行中 **</title> + <title>网络打印</title> <indexterm> <primary>printers</primary> <secondary>network</secondary> </indexterm> <indexterm><primary>network printing</primary></indexterm> - <para></para> + <para>FreeBSD 支持网络打印: 发送任务给远程打印机。 + 网络打印通常指两种不同的方式:</para> + + <itemizedlist> + <listitem> + <para>访问一台连接在远程主机上的打印机。 + 在一台主机上安装一台常规的串行或并行打印机。 + 然后, 设置 <application>LPD</application> + 来通过网络访问其他主机上的打印机。 + 具体见 <link + linkend="printing-advanced-network-rm">安装在远程主机上的打印机</link> + 这节。</para> + </listitem> + + <listitem> + <para>访问一台直接连接在网络上的打印机。 + 打印机另有一个网络接口 (或者替代常规的串口或者并口)。 + 这样的打印机可能像下面这样工作:</para> + + <itemizedlist> + <listitem> + <para>它或许可以理解 <application>LPD</application> + 的协议, 并且甚至可以接收远程主机发来的任务排进队列。 + 这样, 它就像一个普通的主机运行着 + <application>LPD</application> 一样。 做在 + <link linkend="printing-advanced-network-rm">安装在远程主机上的打印机</link> + 里介绍的步骤, 可以设置好这样的打印机。</para> + </listitem> + + <listitem> + <para>它或许支持网络数据流。 + 这样, 把打印机 <quote>接</quote> 在一台网络上的主机上, + 由这台主机负责安排任务并发送任务到打印机。 + 参见 <link + linkend="printing-advanced-network-net-if">带网络数据流接口的打印机</link> + 这节来得到更多安装这类打印机的建议。</para> + </listitem> + </itemizedlist> + </listitem> + </itemizedlist> <sect3 id="printing-advanced-network-rm"> - <title>Printers Installed on Remote Hosts ** 翻译进行中 **</title> + <title>安装在远程主机上的打印机</title> + + <para><application>LPD</application> 打印池系统内建了对给其他也运行着 + <application>LPD</application> (或者是与 + <application>LPD</application> 兼容的) 的主机发送任务的功能。 + 这个功能使您可以在一台主机上安装打印机, + 并让它可以在其他主机上访问。 这个功能同样适用在那些有网络接口并且可以理解 + <application>LPD</application> 协议的打印机上。</para> + + <para>要开启这种远程打印的功能, 首先在一台主机上安装打印机, 就是 + <emphasis>打印主机</emphasis>, 可以使用在 + <link linkend="printing-simple">简单打印机设置</link> + 这节中简单设置的方法。 高级的设置可以参考 <link + linkend="printing-advanced">高级打印机设置</link> 这节中你需要的部分。 + 一定要测试一下打印机, 看看它是不是所有您开启的 + <application>LPD</application> 的功能都正常工作。 + 同样确定 + <emphasis>本地主机</emphasis> 允许使用 <emphasis>远程主机</emphasis> 上的 + <application>LPD</application> + 服务 (参见 <link + linkend="printing-advanced-restricting-remote">限制远程打印机任务</link>)。</para> + + <indexterm> + <primary>printers</primary> + <secondary>network</secondary> + </indexterm> + <indexterm><primary>network printing</primary></indexterm> + <para>如果您正在使用一台带网络接口并与 + <application>LPD</application> 兼容的打印机, 那么我们那下面讨论中的 + <emphasis>打印主机</emphasis> + 就是打印机本身, 而 + <emphasis>打印机名</emphasis> 就是您为打印机配置的名字。 + 参考随打印机和/或者打印机-网络接口供给的文档。</para> + + <tip> + <para>如果您正使用惠普的 Laserjet, + 则打印机名 <literal>text</literal> 将自动地为您完成 LF 到 + CRLF 的转换, 因而也就不需要 + <filename>hpif</filename> 脚本了。</para> + </tip> + + <para>然后, 在另外一台你想要访问打印机的主机上的 + <filename>/etc/printcap</filename> 文件中加入它们的记录, + 像下面这样:</para> + + <orderedlist> + <listitem> + <para>可以随意给这个记录起名字。 简单起见, + 您可以给打印主机使用相同的名字或者别名。</para> + </listitem> + + <listitem> + <para>保留 <literal>lp</literal> 变量为空, + (<literal>:lp=:</literal>)。</para> + </listitem> + + <listitem> + <para>建立一个打印池目录并且用 + <literal>sd</literal> 变量指明它的位置。 <application>LPD</application> + 将把任务存储在这里在它们被送到打印主机之前。</para> + </listitem> + + <listitem> + <para>在 + <literal>rm</literal> 变量中放入打印主机的名字。</para> + </listitem> + + <listitem> + <para>在 + <literal>rp</literal> 中放入打印主机上打印机的名字。</para> + </listitem> + </orderedlist> + + <para>就是这样。 不需要列出转换过滤器, + 页面大小, 或者其他的一些东西在 + <filename>/etc/printcap</filename> 文件中。</para> + + <para>这有一个例子。 主机 <hostid>rose</hostid> 有两台打印机, + <literal>bamboo</literal> 和 <literal>rattan</literal>。 + 我们要让主机 <hostid>orchid</hostid> 的用户可以使用这两台打印机。 + 下面是 <filename>/etc/printcap</filename> 文件, 用在主机 + <hostid>orchid</hostid> (详见 <link + linkend="printing-advanced-header-pages-enabling">开启报头页</link>) + 上的。 文件中已经有了打印机 + <literal>teak</literal> 的记录; 我们在主机 + <hostid>rose</hostid> 上增加了两台打印机:</para> + + <programlisting># +# /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:\ + :if=/usr/local/libexec/ifhp:\ + :vf=/usr/local/libexec/vfhp:\ + :of=/usr/local/libexec/ofhp: - <para></para> +# +# 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:</programlisting> + + <para>然后, 我们只需要在主机 + <hostid>orchid</hostid> 上建立一个打印池目录:</para> + + <screen>&prompt.root; <userinput>mkdir -p /var/spool/lpd/rattan /var/spool/lpd/bamboo</userinput> +&prompt.root; <userinput>chmod 770 /var/spool/lpd/rattan /var/spool/lpd/bamboo</userinput> +&prompt.root; <userinput>chown daemon:daemon /var/spool/lpd/rattan /var/spool/lpd/bamboo</userinput></screen> + + <para>现在, 主机 <hostid>orchid</hostid> 上的用户可以打印到 + <literal>rattan</literal> 和 <literal>bamboo</literal> 了。 如果, + 比如, 一个用户在主机 <hostid>orchid</hostid> 上输入了 + + <screen>&prompt.user; <userinput>lpr -P bamboo -d sushi-review.dvi</userinput></screen> + + <application>LPD</application> 系统在主机 <hostid>orchid</hostid> + 上会复制这个任务到打印池目录 + <filename>/var/spool/lpd/bamboo</filename> 并且记下这是一个 + DVI 任务。 当主机 <hostid>rose</hostid> 上的打印机 + <literal>bamboo</literal> 的打印池目录有空间的时, 这两个 + <application>LPDs</application> 系统将会传输这个文件到主机 + <hostid>rose</hostid> 上。 文件将排在主机 <hostid>rose</hostid> + 的队列中知道最终被打印出来。 它将被从 DVI 转换成 + &postscript; (因为 <literal>bamboo</literal> 是一台 &postscript; 打印机) 在主机 + <hostid>rose</hostid>。</para> </sect3> <sect3 id="printing-advanced-network-net-if"> - <title>Printers with Networked Data Stream Interfaces ** 翻译进行中 **</title> + <title>带有网络数据流接口的打印机</title> + + <para>通常, 当您为打印机购买了一块网卡, + 可以得到两个版本: 一个是模拟打印池 (贵一些的版本), + 或者一个只发送数据给打印机就像在使用串口或者并口一样 + (便宜一些的版本)。 + 这节讲述如何使用这个便宜一些的版本。 要得到贵一些版本的更多信息, + 参见前面章节 <link + linkend="printing-advanced-network-rm">安装在远程主机上的打印机</link>。</para> + + <para><filename>/etc/printcap</filename> 文件的格式让您指定使用哪个串口或并口, + 并且还要指定 (如果您正在使用串口), + 使用多快的波特, 是否使用流量控制, + 为制表符延迟, 转换换行, 等等。 + 但是没有一种方法指定一个连接到一台正在监听 TCP/IP 的或者其他网络接口的打印机。</para> + + <para>要发送数据到网络打印机, 需要开发一个通讯程序, + 它可以被文本或者转换过滤器调用。 + 下面是一些例子: 脚本 + <command>netprint</command> 将标准输入的所有数据发送到一个连在网络上的打印机。 + 我们将打印机的名字作为第一个参数, 端口号跟在后面作为第二个参数, 传给 + <command>netprint</command> 。 + 注意它只支持单向通讯 (FreeBSD 到打印机); + 很多网络打印机支持双向通讯, 并且这是您可能利用到的 + (得到打印机状态, 进行打印记帐, 等等的时候。)。</para> + + <programlisting>#!/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]; + +require 'sys/socket.ph'; + +($ignore, $ignore, $protocol) = getprotobyname('tcp'); +($ignore, $ignore, $ignore, $ignore, $address) + = gethostbyname($printer_host); + +$sockaddr = pack('S n a4 x8', &AF_INET, $printer_port, $address); - <para></para> +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;</programlisting> + + <para>然后我们就可以在多种过滤器里使用这个脚本了。 加入我们有一台 + Diablo 750-N 行式打印机联在网络上。 打印机在 5100 端口上接收要打印的数据。 + 打印机的主机名是 + scrivener 。 这里是为这个打印机写的文本过滤器:</para> + + <programlisting>#!/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</programlisting> </sect3> </sect2> <sect2 id="printing-advanced-restricting"> - <title>Restricting Printer Usage ** 翻译进行中 **</title> + <title>限制使用打印机</title> <indexterm> <primary>printers</primary> <secondary>restricting access to</secondary> </indexterm> - <para></para> + <para>这节将讲述关于限制打印机使用的问题。 + <application>LPD</application> 系统让您可以控制谁可以访问打印机, + 无论本地或是远程的, + 是否他们可以打印机多份拷贝, 任务可以有多大, + 和打印机能有多大的队列。</para> <sect3 id="printing-advanced-restricting-copies"> - <title>Restricting Multiple Copies ** 翻译进行中 **</title> + <title>限制多份拷贝</title> + + <para><application>LPD</application> 系统使用户要打印文件的多份拷贝变得容易。 + 用户可以用 <command>lpr -#5</command> + (举例) 来提交打印任务, 则会将任务中每个文件都打印五份拷贝。 + 这是不是一件很棒的事情呢。</para> + + <para>如果您感觉多份拷贝会对打印机造成不必要的磨损和损耗, + 您可以屏蔽掉 &man.lpr.1; 的 <option>-#</option> 选项, + 通过增加 <literal>sc</literal> 变量在 + <filename>/etc/printcap</filename> 文件里。 当用户用 + <option>-#</option> 选项提交任务时, 他们将看到:</para> + + <screen>lpr: multiple copies are not allowed</screen> - <para></para> + + <para>注意当为一台远程打印机设置的时候 (参见 + <link linkend="printing-advanced-network-rm">安装在远程主机上的打印机</link>) + 这一节, 您同时还需要增加 + <literal>sc</literal> 变量在远程主机的 + <filename>/etc/printcap</filename> 文件中, + 否则用户将还是可以在其他主机上提交多份拷贝的任务。</para> + + <para>下面是一个例子。 这个是 + <filename>/etc/printcap</filename> 文件在主机 + <hostid>rose</hostid> 上。 打印机 <literal>rattan</literal> + 非常轻闲, 所以我们将允许多份拷贝, 但是激光打印机 + <literal>bamboo</literal> 则有些忙, 所以我们禁止多份拷贝, + 通过增加 <literal>sc</literal> + 变量:</para> + + <programlisting># +# /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:ms#-parenb cs8 clocal crtscts:rw:\ + :if=/usr/local/libexec/psif:\ + :df=/usr/local/libexec/psdf:</programlisting> + + <para>现在, 我们还需要增机 <literal>sc</literal> 变量在主机 + <hostid>orchid</hostid> 的 + <filename>/etc/printcap</filename> 文件中 (顺便我们也禁止打印机 + <literal>teak</literal> 多份打印) :</para> + + <programlisting># +# /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:\ + :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:</programlisting> + + <para>通过使用 <literal>sc</literal> 变量, 我们阻止了 + <command>lpr -#</command> 命令的使用, 但仍然没有禁止用户多次运行 + &man.lpr.1; , + 或者多次提交任务中同样的文件, + 像下面这样:</para> + + <screen>&prompt.user; <userinput>lpr forsale.sign forsale.sign forsale.sign forsale.sign forsale.sign</userinput></screen> + + <para>这里有很多种方法可以阻止这种行为 (包括忽略它), + 并且是免费的。</para> </sect3> <sect3 id="printing-advanced-restricting-access"> - <title>Restricting Access to Printers ** 翻译进行中 **</title> + <title>限制对打印机的访问</title> + + <para>您可以控制谁可以打印到哪台打印机通过 &unix; + 的组机制和文件 <filename>/etc/printcap</filename> 中的 + <literal>rg</literal> 变量。 + 只要把可以访问打印机的用户放进适当的组中, + 然后在 + <literal>rg</literal> 变量中写上组的名字。</para> + + <para>非这组的用户 (包括 <username>root</username>) + 将会得到这样的问候: + + <errorname>lpr: Not a member of the restricted group</errorname> + + 如果他们试图打印到被限制的打印机。</para> + + <para>像使用 <literal>sc</literal> (禁止多份拷贝) + 变量一样, 您需要指定 <literal>rg</literal> 在远程 + 同样对打印机有访问限制的主机上, 如果您感觉 + 合适的话 (参考 <link + linkend="printing-advanced-network-rm">安装在远程主机上的打印机</link> 这一节)。</para> + + <para>比如, 我们将让任何人都可以访问打印机 + <literal>rattan</literal>, 但只有在 + <literal>artists</literal> 组中的人可以使用打印机 <literal>bamboo</literal>。 + 这里是类似的主机 <hostid>rose</hostid> 上的 + <filename>/etc/printcap</filename> 文件:</para> + + <programlisting># +# /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: - <para></para> +bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ + :sh:sd=/var/spool/lpd/bamboo:sc:rg=artists:\ + :lp=/dev/ttyd5:ms#-parenb cs8 clocal crtscts:rw:\ + :if=/usr/local/libexec/psif:\ + :df=/usr/local/libexec/psdf:</programlisting> + + <para>Let us leave the other example + <filename>/etc/printcap</filename> file (for the host + <hostid>orchid</hostid>) alone. Of course, anyone on + <hostid>orchid</hostid> can print to <literal>bamboo</literal>. It + might be the case that we only allow certain logins on + <hostid>orchid</hostid> anyway, and want them to have access to the + printer. Or not.</para> + + <note> + <para>这里每台仅能有一个限制的组。</para> + </note> </sect3> <sect3 id="printing-advanced-restricting-sizes"> - <title>Controlling Sizes of Jobs Submitted ** 翻译进行中 **</title> + <title>控制提交的任务大小</title> <indexterm><primary>print jobs</primary></indexterm> - <para></para> + <para>如果您有很多用户访问打印机, + 可能需要对用户可以提交的文件尺寸设置一个上限。 + 毕竟, 文件系统中打印池目录的空间是有限的, + 您需要保证这里有空间来存放其他用户的任务。</para> + + <indexterm> + <primary>print jobs</primary> + <secondary>controlling</secondary> + </indexterm> + <para><application>LPD</application> 允许限制任务中文件的最大字节数, + 通过使用 + <literal>mx</literal> 变量。 单位为 + <literal>BUFSIZ</literal> 块, 每块 1024 字节。 + 如果在这个变量中放入 0 值, + 将没有文件大小的限制; 然而, 就算没有指定 + <literal>mx</literal> 变量, + 那么默认值 1000 块将被使用。</para> + + <note> + <para>这个限制是对于任务中 <emphasis>文件</emphasis> 的, + 而 <emphasis>不是</emphasis> 任务总共的大小。</para> + </note> + + <para><application>LPD</application> 不会拒绝比限制大小大的文件。 + 但它是将限制大小以内的部分排入队列, + 并且打印出来的只有这些。 剩下的部分将被丢弃。 + 这个行为是否正确还需讨论。</para> + + <para>让我们来为例子打印机 + <literal>rattan</literal> 和 <literal>bamboo</literal> 增加限制。 + 由于那些艺术家的 &postscript; 文件可能会很大, + 我们将限制大小为 5 兆字节。 我们将不对纯文本行式打印机做限制:</para> + + <programlisting># +# /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: + +# +# 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:ms#-parenb cs8 clocal crtscts:rw:\ + :if=/usr/local/libexec/psif:\ + :df=/usr/local/libexec/psdf:</programlisting> + + <para>同样, 限制只对本地用户起作用。 + 如果远程设置了限制, 远程用户将不会受到这些限制。 + 您也需要指定 <literal>mx</literal> + 变量在远程主机的 <filename>/etc/printcap</filename> 文件中。 + 参见 <link + linkend="printing-advanced-network-rm">安装在远程主机上的打印机</link> + 这一节来得到更多有关远程打印的信息。</para> + + <para>这里还有一种限制远程任务大小的方法; + 参见 <link + linkend="printing-advanced-restricting-remote">限制远程打印机任务</link>。</para> </sect3> <sect3 id="printing-advanced-restricting-remote"> - <title>Restricting Jobs from Remote Printers ** 翻译进行中 **</title> - - <para></para> + <title>限制远程打印机任务</title> + + <para><application>LPD</application> 打印池系统提供了多种方法来限制从远程主机提交的任务: </para> + + <variablelist> + <varlistentry> + <term>主机限制</term> + + <listitem> + <para>您可以控制本地 + <application>LPD</application> 接收哪台远程主机发来的请求, + 通过 <filename>/etc/hosts.equiv</filename> 文件和 + <filename>/etc/hosts.lpd</filename> 文件。 + <application>LPD</application> 查看是否到来的任务请求来自被这两个文件中列出的主机。 + 如果没有, <application>LPD</application> + 会拒绝这个请求。</para> + + <para>这些文件的格式非常简单: 每行一个主机名。 + 注意 + <filename>/etc/hosts.equiv</filename> 文件也被 + &man.ruserok.3; 协议使用, 并影响着 + &man.rsh.1; and &man.rcp.1; 等程序, 所以要小心。</para> + + <para>举个例子, 下面是 + <filename>/etc/hosts.lpd</filename> 文件在主机 + <hostid>rose</hostid> 上:</para> + + <programlisting>orchid +violet +madrigal.fishbaum.de</programlisting> + + <para>意思是主机 <hostid>rose</hostid> 将接收来自 + <hostid>orchid</hostid>, <hostid>violet</hostid>, + 和 <hostid role="fqdn">madrigal.fishbaum.de</hostid> 的请求。 + 如果任何其他的主机试图访问主机 <hostid>rose</hostid> 的 + <application>LPD</application>, 任务将被拒绝。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>大小限制</term> + + <listitem> + <para>您可以控制打印池目录需要保留多少空间。 + 建立一个叫做 + <filename>minfree</filename> 的文件在打印池目录下为本地打印机。 + 在这个文件中插入一个数字来代表多少磁盘块数 (512 字节) + 的剩余空间来接收远程任务。</para> + + <para>这让您可以保证远程用户不会填满您的文件系统。 + 您也可以用它来给本地用户一个优先: + 他们可以在磁盘剩余空间低于 + <filename>minfree</filename> + 文件中的指定值后仍然可以提交任务。 + + <para>比如, 让我们增加一个 <filename>minfree</filename> + 文件为打印机 <literal>bamboo</literal>。 我们检查 + <filename>/etc/printcap</filename> 文件来找到这个打印机的打印池目录; + 这里是打印机 <literal>bamboo</literal> + 的记录:</para> + + <programlisting>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:ms#-parenb cs8 clocal crtscts:rw:mx#5000:\ + :if=/usr/local/libexec/psif:\ + :df=/usr/local/libexec/psdf:</programlisting> + + <para>打印池目录在 <literal>sd</literal> + 变量中给出。 我们设置 3 兆字节 (6144 磁盘块) + 为文件系统上必须存在的总共剩余空间, 让 + <application>LPD</application> 可以接受远程任务:</para> + + <screen>&prompt.root; <userinput>echo 6144 > /var/spool/lpd/bamboo/minfree + </userinput></screen> + </listitem> + </varlistentry> + + <varlistentry> + <term>用户限制</term> + + <listitem> + <para>您可以控制哪些远程用户可以打印到本地打印机, 通过指定 + <literal>rs</literal> 变量在 + <filename>/etc/printcap</filename> 文件中。 当 + <literal>rs</literal> 出现在一个本地打印机的记录中时, + <application>LPD</application> 将接收来自远程主机 + <emphasis> 并 </emphasis> 在本地有同样登陆名的用户提交的任务。 + 否则, <application>LPD</application> 会拒绝这个任务。</para> + + <para>这个功能在一个 (比如) 有许多部门共享一个网络的环境中特别有用, + 并且有些用户可以越过部门的边界。 + 通过为他们在您的系统上建立帐号, + 他们可以他们自己的部门的系统里使用您的打印机。 + 如果 <emphasis>只</emphasis> 允许他们您的打印机, + 而不是您的计算机资源, 您可以给他们 + <quote>象征</quote> 帐户, 不带主目录并且设置一个没用的 + shell , 比如 <filename>/usr/bin/false</filename>。</para> + </listitem> + </varlistentry> + </variablelist> </sect3> </sect2> <sect2 id="printing-advanced-acct"> - <title>Accounting for Printer Usage ** 翻译进行中 **</title> + <title>对打印机使用记帐</title> <indexterm> <primary>accounting</primary> <secondary>printer</secondary> </indexterm> - <para></para> + <para>当然, 你需要对打印付费。 为什么不? 纸张和墨水都需要花钱的。 + 并且这里还有维护的费用 — 打印机是由很多部件组装成的, + 并且零件会坏掉。 您可以检查您的打印机, + 使用形式, 和维护费用来得出每页 + (或者每尺, 每米, 或者每什么) 的费用。 现在, + 您怎样启动打印记帐呢?</para> + + <para>好了, 坏消息是 <application>LPD</application> + 打印池系统在这个部分没有提供很多帮助。 + 记帐是一个对使用的打印机的种类, + 打印的格式, 和 + <emphasis>您的</emphasis> 在对打印机的使用计费的需求依赖性很高的。</para> + + <para>要实现记帐, 您必须更改打印机的文本过滤器 + (对纯文本任务记费) 和转换过滤器 + (对其他格式的文件计费), 要统计页数或者查询打印了多少页的话。 + 您不可以通过使用简单的输出过滤器来逃脱计费, + 因为它不能进行记帐。 参见 <link + linkend="printing-advanced-filter-intro">过滤器</link> 这节。</para> + + <para>通常, 有两种方法来进行记帐:</para> + + <itemizedlist> + <listitem> + <para><emphasis>定期记帐</emphasis> 是更常用的方法, + 可能因为它更简单。 无论合适何人打印一个任务, + 过滤器都将记录用户名, 主机名, 和打印的页数到一个记帐文件。 + 每个月, 学期, 年, 或者任何您想设定的时间段, + 收集这些不同打印机上的记帐文件, + 按用户对打印的页数进行结算, 并对使用进行付费。 + 然后删掉所有记录文件, 开始一个新的计费周期。</para> + </listitem> + + <listitem> + <para><emphasis>实时记帐</emphasis> 不太常用, + 可能因为它比较难。 + 这种方法让过滤器对用户的打印进行实时的记帐。 + 像磁盘配额, 记帐是实时的。 + 您可以组织用户打印当他们的帐户超额的时候, + 并且可能提供一种方法让用户检查并调整他们的 + <quote>打印配额。</quote> 但这个方法需要一些数据库代码来跟踪用户和他们的配额。</para> + </listitem> + </itemizedlist> + + <para><application>LPD</application> 打印池系统对两种方法都支持且很简单: + 所以您需要提供过滤器 + (大多数时候), 还要提供记帐代码。 + 但这好的方面是: 您可以有非常灵活的记帐方法。 + 比如, 您可以选择使用阶段记帐还是实时记帐。 + 您可以选择记录哪些信息: + 用户名, 主机名, 任务类型, 打印页数, + 使用了多少平方尺的纸, 任务打印了多长时间, 等等。 + 您可以通过修改过滤器来存储这些信息。</para> <sect3> - <title>Quick and Dirty Printer Accounting ** 翻译进行中 **</title> + <title>快速并且混乱的打印记帐</title> + + <para>FreeBSD 包含两个可以让您立刻可以建立起简单的阶段记帐的程序。 + 它们是文本过滤器 + <command>lpf</command>, 在 <link + linkend="printing-advanced-lpf">lpf: 一个文本过滤器</link> 这节中描述, 和 + &man.pac.8;, 一个收集并统计打印机记帐文件中记录的程序。</para> + + <para>像在前面章节提到的过滤器一样 + (<link linkend="printing-advanced-filters">过滤器</link>), + <application>LPD</application> + 启动文本或者转换过滤器并在过滤器命令行里带上记帐文件的名字。 + 过滤器可以使用这个参数知道该往哪写记帐记录。 + 这个文件的名字来自于 + <literal>af</literal> 变量在 + <filename>/etc/printcap</filename> 文件里, 并且如果没有指定绝对路径, + 则默认是相对于打印池目录的。</para> + + <para><application>LPD</application> 启动 <command>lpf</command> + 带着页宽和页长的参数 + (通过 <literal>pw</literal> 和 <literal>pl</literal> + 变量)。 <command>lpf</command> 使用这些参数来判定将使用多少张纸。 + 在文件发送到打印机之后, + 它就会在记帐文件中写入记录。 + 记录像下面这个样子:</para> + + <programlisting>2.00 rose:andy +3.00 rose:kelly +3.00 orchid:mary +5.00 orchid:mary +2.00 orchid:zhang</programlisting> + + <para>您应该让每个打印机都使用一个独立的记帐文件, 像 + <command>lpf</command> 就没有内建文件锁逻辑, + 这样两个 <command>lpf</command> 可能会发生彼此记录混合的情况, + 如果它们同时要在同一个文件写入内容的时候。 + 一个最简单的保证每个打印机都使用一个独立的记帐文件的方法就是将 + <literal>af=acct</literal> 写在 <filename>/etc/printcap</filename> 文件中。 + 然后, 每个打印机的记帐文件都会在这台打印机的打印池目录中, + 文件的名字叫做 <filename>acct</filename>。</para> + + <para>当您准备对用户的打印进行收费时, 运行 + &man.pac.8; 程序。 只要转换到要收集信息的这台打印机的打印池目录, + 然后输入 <literal>pac</literal> 。 + 您将会得到一个美元计费的摘要像下面这样:</para> + + <screen> 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</screen> + + <para>这些时 &man.pac.8; 需要的参数:</para> + + <variablelist> + <varlistentry> + <term><option>-P<replaceable>打印机</replaceable></option></term> + + <listitem> + <para>哪台 <replaceable>打印机</replaceable> 要结帐。 + 这个选项仅在用 + <literal>af</literal> 变量在 + <filename>/etc/printcap</filename> 文件中指定了绝对路径的情况下起作用。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><option>-c</option></term> + + <listitem> + <para>以金额来排序输出来代替以用户名字字母排序。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><option>-m</option></term> + + <listitem> + <para>忽略记帐文件中的主机名。 带上这个选项, + 用户 <username>smith</username> 在主机 + <hostid>alpha</hostid> 上与同样的用户 + <username>smith</username> 在主机 <hostid>gamma</hostid> 上一样。 + 不带这个选项的话, 他们则是不同的用户。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><option>-p<replaceable>单价</replaceable></option></term> + + <listitem> + <para>使用 <replaceable>price</replaceable> + 作为每页或每尺美元的单价来替代 + <literal>pc</literal> 变量指定的单价在 + <filename>/etc/printcap</filename> 文件中, 或者两分 (默认)。 + <replaceable>price</replaceable> + 可以用一个浮点数来指定。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><option>-r</option></term> + + <listitem> + <para>反向排序。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><option>-s</option></term> + + <listitem> + <para>建立一个记帐摘要文件, + 并且截短记帐文件。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><replaceable>名字</replaceable> + <replaceable>…</replaceable></term> + + <listitem> + <para>只打印指定 + <replaceable>名字</replaceable> 用户的记帐信息。</para> + </listitem> + </varlistentry> + </variablelist> + + <para>在 &man.pac.8; 默认产生的摘要中, + 可以看到在不同主机上的每个用户打印了多少页。 + 如果在您这里, 主机不考虑 (因为用户可以使用任何主机), + 运行 <command>pac -m</command>, + 来得到下面的摘要:</para> + + <screen> 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</screen> + - <para></para> + <para>要以美元计算应付钱数, + &man.pac.8; 指定 <literal>pc</literal> 变量在 + <filename>/etc/printcap</filename> 文件中 (默认是 200, 或者 2 分每页). + 这个参数的单位是百分之一分, + 在这个变量中指定每页或者每尺的价格。 + 您可以覆盖这个值当运行 &man.pac.8; 带着参数 + <option>-p</option> 的时候。 参数 <option>-p</option> + 的单位是美元, 而不是百分之一分。 + 例如, + + <screen>&prompt.root; <userinput>pac -p1.50</userinput></screen> + + 设定每页的价格是 1 美元 5 美分。 + 您可以通过这个选项来达到目标利润。</para> + + <para>最终, 运行 <command>pac -s</command> 将存储这些信息在一个记帐文件里, + 文件名和打印机帐户的名字相同, + 但是带着 <literal>_sum</literal> + 的后缀。 然后截短记帐文件。 + 当您再次运行 &man.pac.8; 的时候, 它再次读取记帐文件来得到初始的总计, + 然后在记帐文件中增加信息。</para> </sect3> <sect3> - <title>How Can You Count Pages Printed? ** 翻译进行中 **</title> - - <para></para> + <title>怎样对打印的页数进行计数?</title> + + <para>为了进行远程的精确记帐, + 需要判断一个任务将会消耗多少张纸。 + 这是打印记帐问题的关键。</para> + + <para>对于纯文本任务, 这个问题不是太难解决: + 对任务中的行数进行计数然后与打印机支持的每页行数进行比较。 + 别忘了也对添印的行, 或者很长的逻辑上的一行但在打印机上会折成两行的这类进行记帐。</para> + + <para>文本过滤器 <command>lpf</command> (在 <link + linkend="printing-advanced-lpf">lpf:一个文本过滤器</link> 这节中介绍) + 会在记帐时考虑这些问题。 + 如果正在编写一个可以进行记帐的文本过滤器, + 您可能需要查看 <command>lpf</command> 的源代码。</para> + + <para>怎样处理其他格式的文件?</para> + + <para>好, 对于 DVI- 到 -LaserJet 或者 DVI- 到 -&postscript; 转换, + 可以让您的过滤器输出诊断信息, 关于 + <command>dvilj</command> 或者 <command>dvips</command> 命令, + 并且看到多少页被转换了。 您也许可以对于其他类型的文件和转换程序进行类似操作。</para> + + <para>但是这些方法的弱点就是事实上打印机并不是打印了所有的页。 + 比如, 卡纸, 缺墨, + 或者炸掉了 — 但用户还是要为没有打印的部分付钱。</para> + + <para>您该怎样做?</para> + + <para>只有一条 <emphasis>肯定</emphasis> 的方法来进行 + <emphasis>精确</emphasis> 的记帐。 购买一台可以告诉您它使用了多少纸的打印机, + 并且将它连接到串口或者网络上。 + 几乎所有 &postscript; 打印机都支持这个小功能。 + 其他制造厂或其他型号也可以有这个功能 (比如 Imagen + 激光网络打印机)。 为这些打印机更改过滤器使它在打印完每个任务之后接收纸张用量, + 并 <emphasis>仅</emphasis> 基于这个值进行记帐。 + 不需要计算行数, + 也不需要容易出错的文件检查。</para> + + <para>当然, 您也总是可以大方的使打印免费。</para> </sect3> </sect2> </sect1> <sect1 id="printing-using"> - <title>Using Printers ** 翻译进行中 **</title> + <title>使用打印机</title> <indexterm> <primary>printers</primary> <secondary>usage</secondary> </indexterm> - <para></para> + <para>这节将讲述如何使用在 + FreeBSD 下设置好的打印机。 下面是一个用户级命令的总览:</para> + + <variablelist> + <varlistentry> + <term>&man.lpr.1;</term> + + <listitem> + <para>打印任务</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>&man.lpq.1;</term> + + <listitem> + <para>检查打印队列</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>&man.lprm.1;</term> + + <listitem> + <para>从打印机的队列中移除任务</para> + </listitem> + </varlistentry> + </variablelist> + + <para>这里还有一个管理命令, &man.lpc.8; , + 在 <link linkend="printing-lpc"> 管理 + <application>LPD</application> + 打印池</link> 这节中描述, 用来控制打印机和它们的队列。</para> + + <para> &man.lpr.1;, &man.lprm.1;, and &man.lpq.1; + 这三个命令都接受 <option>-P + <replaceable>printer-name</replaceable></option> 选项来指定对哪个打印机 / 队列进行操作, + 在 + <filename>/etc/printcap</filename> 文件中列出的打印机。 这允许您提交, + 删除, 并检查任务在多个打印机上。 如果您不使用 + <option>-P</option> 选项, 那么这些命令会使用在 + 环境变量 <envar>PRINTER</envar> 中指定的打印机。 + 最终, 如果您也没有 <envar>PRINTER</envar> 这个环境变量, + 这些命令的默认值是叫做 <literal>lp</literal> 的这台打印机。</para> + + <para>从此以后, 术语 <emphasis>默认打印机</emphasis> + 就是指 <envar>PRINTER</envar> 环境变量中指定的这台, + 或者叫做 <literal>lp</literal> 的这一台当没有环境变量 + <envar>PRINTER</envar> 的时候。</para> <sect2 id="printing-lpr"> - <title>Printing Jobs ** 翻译进行中 **</title> + <title>打印任务</title> + + <para>要打印文件, 输入:</para> - <para></para> + <screen>&prompt.user; <userinput>lpr <replaceable>filename</replaceable> <replaceable>...</replaceable></userinput></screen> + + <indexterm><primary>printing</primary></indexterm> + <para>这个命令会打印所有列出的文件到默认打印机。 + 如果没有列出文件, &man.lpr.1; 会从标准输入读取打印数据。 + 比如, 这个命令打印一些重要的系统文件:</para> + + <screen>&prompt.user; <userinput>lpr /etc/host.conf /etc/hosts.equiv</userinput></screen> + + <para>要选择一个指定的打印机, 输入:</para> + + <screen>&prompt.user; <userinput>lpr -P <replaceable>printer-name</replaceable> <replaceable>filename</replaceable> <replaceable>...</replaceable></userinput></screen> + + <para>这个例子打印一个当前目录的长长的列表到叫做 + <literal>rattan</literal> 的这台打印机:</para> + + <screen>&prompt.user; <userinput>ls -l | lpr -P rattan</userinput></screen> + + <para>因为没有为 + &man.lpr.1; 命令列出文件, <command>lpr</command> 从标准输入读入数据, + 在这里是 <command>ls + -l</command> 命令的输出。</para> + + <para> &man.lpr.1; 命令同样可以接受多种控制格式的选项, + 应用文件转换, 生成多份拷贝, 等等。 + 要得到更多信息, 参考 <link + linkend="printing-lpr-options">打印选项</link> 这节。</para> </sect2> <sect2 id="printing-lpq"> - <title>Checking Jobs ** 翻译进行中 **</title> + <title>检查任务</title> <indexterm><primary>print jobs</primary></indexterm> - <para></para> + <para>当使用 &man.lpr.1; 进行打印时, 您希望打印的所有数据被放在一起打包成了一个 + <quote>打印任务</quote>, 它被发送到 + <application>LPD</application> 打印池系统。 + 每台打印机都有一个任务队列, + 并且您的任务在队列中等待其他用户的其他任务打印。 + 打印机按照先来先印的规则打印这些任务。</para> + + <para>要显示默认打印机的队列, 输入 &man.lpq.1; 。 + 要指定打印机, 使用 <option>-P</option> 选项。 + 例如, 命令 + + <screen>&prompt.user; <userinput>lpq -P bamboo</userinput></screen> + + 会显示打印机 <literal>bamboo</literal> 的队列。 + 下面是命令 <command>lpq</command> + 输出的一个例子:</para> + + <screen>bamboo is ready and printing +Rank Owner Job Files Total Size +active kelly 9 /etc/host.conf, /etc/hosts.equiv 88 bytes +2nd kelly 10 (standard input) 1635 bytes +3rd mary 11 ... 78519 bytes</screen> + + <para>这里显示了队列中有三个任务在 <literal>bamboo</literal> 中。 + 第一个任务, 用户 kelly 提交的, 标识 <quote>任务编号</quote> + 9。 每个要打印的任务都会获得一个不同的任务编号。 + 大多时候可以忽略这个任务编号, 但在您需要取消任务时会用到这个号码; + 参考 <link + linkend="printing-lprm">移除任务</link> 这节得到更多信息。</para> + + <para>编号为 9 的任务包含了两个文件; 在 + &man.lpr.1; 命令行中指定的多个文件被看作是一个单个的任务。 + 它是当前激活的任务 (注意这个词 <literal>激活</literal> + 在 <quote>Rank</quote> 这列下面), 意思是打印机当前正在打印那个任务。 + 第二个任务包含了标准输入传给 + &man.lpr.1; 命令的数据。 + 第三个任务来自用户 <username>mary</username>; , + 它是一个比较大的任务。 她要打印的文件的路径名太长了, + 所以 &man.lpq.1; 命令只显示了三个点。</para> + + <para> &man.lpq.1; 输出的头一行也很有用: + 它告诉我们打印机正在做什么 (或者至少是 + <application>LPD</application> 认为打印机应该正在做的)。</para> + + <para> &man.lpq.1; 命令同样支持 <option>-l</option> 选项来生成一个详细的长列表。 + 下面是一个 + <command>lpq -l</command> 命令的例子:</para> + + <screen>waiting for bamboo to become ready (offline ?) +kelly: 1st [job 009rose] + /etc/host.conf 73 bytes + /etc/hosts.equiv 15 bytes + +kelly: 2nd [job 010rose] + (standard input) 1635 bytes + +mary: 3rd [job 011rose] + /home/orchid/mary/research/venus/alpha-regio/mapping 78519 bytes</screen> </sect2> <sect2 id="printing-lprm"> - <title>Removing Jobs ** 翻译进行中 **</title> + <title>移除任务</title> + + <para>如果您对一个打印任务改变了主意, + 可以用 &man.lprm.1; 将任务从队列中删除。 通常, 您甚至可以用 + &man.lprm.1; 命令来移除一个当前激活的任务, 但是任务的一部分或者所有还是可能打印出来。</para> + + <para>要从默认打印机中移除一个任务, 首先使用 + &man.lpq.1; 找到任务编号。 然后输入:</para> + + <screen>&prompt.user; <userinput>lprm <replaceable>job-number</replaceable></userinput></screen> + + <para>要从指定打印机中删除任务, 增加 + <option>-P</option> 选项。 下面的命令会删除编号为 + 10 的任务从 <literal>bamboo</literal> 这台打印机:</para> + + <screen>&prompt.user; <userinput>lprm -P bamboo 10</userinput></screen> + + <para> &man.lprm.1; 命令有一些快捷方式:</para> + + <variablelist> + <varlistentry> + <term>lprm -</term> + + <listitem> + <para>删除所有属于您的任务 (默认打印机的)。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>lprm <replaceable>user</replaceable></term> + + <listitem> + <para>删除所有属于用户 + <replaceable>user</replaceable> 的任务 (默认打印机的)。 + 超级用户可以删除用户的任务; 您只可以删除自己的任务。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>lprm</term> + + <listitem> + <para>命令行中不带任务编号, 任务名, 或者 <option>-</option> + 选项, &man.lprm.1; 会删除默认打印机上当前激活的任务, + 如果它属于你。 超级用户可以删除任务激活的任务。</para> + </listitem> + </varlistentry> + </variablelist> - <para></para> + <para>使用参数 <option>-P</option> 和上面的快捷方式来用指定打印机替代默认打印机。 + 例如, 下面的命令会删除当前用户在打印机 + <literal>rattan</literal> 队列中的所有任务:</para> + + <screen>&prompt.user; <userinput>lprm -P rattan -</userinput></screen> + + <note> + <para>如果您正工作在一个网络环境中, &man.lprm.1; + 将只允许在提交任务的主机上删除任务, + 甚至是同一台打印机也可以在其他主机上使用时。 + 下面的命令证明了这个:</para> + + <screen>&prompt.user; <userinput>lpr -P rattan myfile</userinput> +&prompt.user; <userinput>rlogin orchid</userinput> +&prompt.user; <userinput>lpq -P rattan</userinput> +Rank Owner Job Files Total Size +active seeyan 12 ... 49123 bytes +2nd kelly 13 myfile 12 bytes +&prompt.user; <userinput>lprm -P rattan 13</userinput> +rose: Permission denied +&prompt.user; <userinput>logout</userinput> +&prompt.user; <userinput>lprm -P rattan 13</userinput> +dfA013rose dequeued +cfA013rose dequeued + </screen> + </note> </sect2> <sect2 id="printing-lpr-options"> - <title>Beyond Plain Text: Printing Options ** 翻译进行中 **</title> + <title>超越纯文本:打印选项</title> - <para></para> + <para> &man.lpr.1; 支持许多控制文本格式的参数, + 转换图形和其他格式文件, + 生成多份拷贝, 处理任务, 等等。 + 这一节将描述这些选项。</para> <sect3 id="printing-lpr-options-format"> - <title>Formatting and Conversion Options ** 翻译进行中 **</title> + <title>格式与转换选项</title> + + <para>下面的 &man.lpr.1; 参数控制任务中文件的格式。 + 使用这些参数, 如果任务不含纯文本, + 或者您想让纯文本通过 + &man.pr.1; 格式化。</para> + + <indexterm><primary>&tex;</primary></indexterm> + <para>例如, 下面的命令打印一个 DVI 文件 (来自 + &tex; 排版系统) 文件名为 <filename>fish-report.dvi</filename> + 到打印 <literal>bamboo</literal>:</para> + + <screen>&prompt.user; <userinput>lpr -P bamboo -d fish-report.dvi</userinput></screen> + + <para>这些选项应用到任务中的每个文件, 所以您不能混合 + (说) DVI 和 ditroff 文件在同一个任务中。 替代的方法是, + 用独立的任务提交这些文件, 使用不同的转换选项给不同的任务。</para> + + <note> + <para>所有这些选项除了 <option>-p</option> 和 + <option>-T</option> 都需要转换过滤器安装给目标打印机。 + 例如, <option>-d</option> 选项需要 + DVI 转换过滤器。 参考 <link + linkend="printing-advanced-convfilters">转换过滤器</link> + 这节得到更多细节。</para> + </note> + + <variablelist> + <varlistentry> + <term><option>-c</option></term> + + <listitem> + <para>打印 cifplot 文件。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><option>-d</option></term> + + <listitem> + <para>打印 DVI 文件。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><option>-f</option></term> + + <listitem> + <para>打印 FORTRAN 文本文件。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><option>-g</option></term> + + <listitem> + <para>打印 plot 数据。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><option>-i <replaceable>number</replaceable></option></term> + + <listitem> + <para>缩进 <replaceable>number</replaceable> 列; + 如果没有指定 <replaceable>number</replaceable>, + 则缩进 8 列。 这个选项仅可以工作在某些过滤器上。</para> - <para></para> + <note> + <para>不要在选项 <option>-i</option> 和数字之间加入空格。</para> + </note> + </listitem> + </varlistentry> + + <varlistentry> + <term><option>-l</option></term> + + <listitem> + <para>打印文字数据, + 包括控制字符。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><option>-n</option></term> + + <listitem> + <para>打印 ditroff (无设备依赖 troff) 数据。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>-p</term> + + <listitem> + <para>打印之前用 &man.pr.1; 格式化纯文本。 参考 + &man.pr.1; 得到更多信息。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><option>-T <replaceable>title</replaceable></option></term> + + <listitem> + <para>使用 <replaceable>title</replaceable> 在 + &man.pr.1; 上来替代文件名。 + 这个选项仅在使用 <option>-p</option> + 选项时起作用。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><option>-t</option></term> + + <listitem> + <para>打印 troff 数据。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><option>-v</option></term> + + <listitem> + <para>打印 raster 数据。</para> + </listitem> + </varlistentry> + </variablelist> + + <para>下面是一个例子: 这个命令打印了一个很好的 + &man.ls.1; 手册页面到默认打印机:</para> + + <screen>&prompt.user; <userinput>zcat /usr/share/man/man1/ls.1.gz | troff -t -man | lpr -t</userinput></screen> + + <para> &man.zcat.1; 命令解压缩 + &man.ls.1; 的手册并且将内容传给 &man.troff.1; + 命令, 它将格式化这些内容并且生成 GNU troff + 输出给 &man.lpr.1; , 它提交任务到 + <application>LPD</application> 打印池。 + 因为使用了 <option>-t</option> + 选项为 &man.lpr.1; , 打印池将会转换 GNU + troff 输出到默认打印机可以理解的格式当任务被打印时。</para> </sect3> <sect3 id="printing-lpr-options-job-handling"> - <title>Job Handling Options ** 翻译进行中 **</title> + <title>任务处理选项</title> - <para></para> + <para>下面的 &man.lpr.1; 选项告诉 + <application>LPD</application> 对任务特殊处理:</para> + + <variablelist> + <varlistentry> + <term>-# <replaceable>copies</replaceable></term> + + <listitem> + <para>生成 <replaceable>copies</replaceable> 个副本给任务中的每个文件, + 替代每个文件一份拷贝。 + 管理员可以禁止这个选项来减少打印机的浪费和鼓励复印机的使用。 + 参考 + <link + linkend="printing-advanced-restricting-copies">限制多份拷贝</link> 。</para> + + <para>这个例子打印三份拷贝的文件 + <filename>parser.c</filename> 跟着三份拷贝的文件 + <filename>parser.h</filename> 到默认打印机:</para> + + <screen>&prompt.user; <userinput>lpr -#3 parser.c parser.h</userinput></screen> + </listitem> + </varlistentry> + + <varlistentry> + <term>-m</term> + + <listitem> + <para>打印完成后发信。 使用这个选项, + <application>LPD</application> 系统将会发送邮件到您的帐户, + 当它完成了处理您的任务后。 + 在信中, 它将会告诉您任务是否成功完成或者出现了错误, + 并且 (通常) 指明是什么错误。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>-s</term> + + <listitem> + <para>不要复制文件到打印池目录, + 要使用符号连接。</para> + + <para>如果您正在打印一个很大的任务, 您可能需要这个选项。 + 它节省打印池目录的空间 + (您的任务可能使打印池目录所在的文件系统剩余空间超出)。 + 它同样也节省了时间, 因为 + <application>LPD</application> + 将不会拷贝任务的每个字节到打印池目录。</para> + + <para>这也有一个缺点: 因为 + <application>LPD</application> 将直接指向源文件, + 您不能修改或者删除它们直到它们被打印出来。</para> + + <note> + <para>如果您打印到一台远程打印机, + <application>LPD</application> + 将最终将文件从本地主机拷贝到远程主机上, + 所以选项 <option>-s</option> 只能节省本地打印池目录的空间, + 而不是远程的。 + 虽然如此, 但它还是很有用。</para> + </note> + </listitem> + </varlistentry> + + <varlistentry> + <term>-r</term> + + <listitem> + <para>移除任务中的文件在它们被复制到打印池目录之后, + 或者在用 + <option>-s</option> 选项打印它们之后。 + 谨慎使用这个选项!</para> + </listitem> + </varlistentry> + </variablelist> </sect3> <sect3 id="printing-lpr-options-misc"> - <title>Header Page Options ** 翻译进行中 **</title> + <title>报头页选项</title> - <para></para> + <para>这些 &man.lpr.1; 的选项调整了通常出现在任务报头页上的文本。 + 如果报头页被跳过了在目标打印机上, + 这些选项将不会起作用。 参考 + <link linkend="printing-advanced-header-pages">报头页</link> + 得到更多关于设置报头页的信息。</para> + + <variablelist> + <varlistentry> + <term>-C <replaceable>text</replaceable></term> + + <listitem> + <para>替换报头页上的主机名为 + <replaceable>text</replaceable>。 + 主机名通常都是提交任务的主机名称。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>-J <replaceable>text</replaceable></term> + + <listitem> + <para>替换报头页上的任务名为 + <replaceable>text</replaceable>。 任务名通常是任务中头一个文件的名字, + 或者 + <filename>stdin</filename> 如果您正在打印标准输入。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>-h</term> + + <listitem> + <para>不打印任何报头页。</para> + + <note> + <para>在某些地点, 这个选项可能无效, + 与报头页的产生方法有关。 参考 <link + linkend="printing-advanced-header-pages">报头页</link> + 得到详细信息。</para> + </note> + </listitem> + </varlistentry> + </variablelist> </sect3> </sect2> <sect2 id="printing-lpc"> - <title>Administering Printers ** 翻译进行中 **</title> + <title>管理打印机</title> - <para></para> + <para>作为一个打印机的管理者, 您必须要安装, + 设置, 并且测试它们。 使用 &man.lpc.8; 命令, + 您可以与打印机以更多的方式交流。 用 &man.lpc.8; , + 您可以</para> + + <itemizedlist> + <listitem> + <para>启动或停止打印机</para> + </listitem> + + <listitem> + <para>启用或禁止它们的队列</para> + </listitem> + + <listitem> + <para>重新安排每个队列中的任务。</para> + </listitem> + </itemizedlist> + + <para>首先, 一个关于术语的解释: 如果一个打印机被 + <emphasis>停止</emphasis> 了, 它将不会打印它队列中的任何东西。 + 但用户还是可以提交任务, 它们会在队列中等待直到打印机被 + <emphasis>启动</emphasis> 或者队列被清空。</para> + + <para>如果一个队列被 <emphasis>禁止</emphasis>, 没有用户 (除了 + <username>root</username>) 可以提交任务到打印机。 一个 + <emphasis>启用</emphasis> 的队列允许任务被提交。 + 一个打印机可以被 <emphasis>启动</emphasis> 但它的队列被禁止, + 在这种情况下打印机将打印队列中的任务知道队列为空。</para> + + <para>通常, 您必须有 <username>root</username> 权限来使用 + &man.lpc.8; 命令。 普通用户可以使用 &man.lpc.8; + 命令来获得打印机状态并且重启一台挂了的打印机。</para> + + <para>这里是一个关于 &man.lpc.8; 命令的摘要。 大部分命令带着一个 + <replaceable>printer-name</replaceable> 参数来知道要对哪台打印机操作。 + 您可以用 <literal>all</literal> + 填在 <replaceable>printer-name</replaceable> 的位置来代表所有在 + <filename>/etc/printcap</filename> 文件中列出的打印机。</para> + + <variablelist> + <varlistentry> + <term><command>abort + <replaceable>printer-name</replaceable></command></term> + + <listitem> + <para>取消当前任务并停止打印机。 + 用户仍然可以提交任务, 如果队列还是启用的。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><command>clean + <replaceable>printer-name</replaceable></command></term> + + <listitem> + <para>从打印机的打印池目录移除旧的文件。 + 有时, 组成任务的文件没有被 + <application>LPD</application> 正确的删除, + 特别是在打印中出现错误或者管理活动比较多的时候。 + 这个命令查找不属于打印池目录的文件并删除它们。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><command>disable + <replaceable>printer-name</replaceable></command></term> + + <listitem> + <para>禁止新任务入队。 如果打印机正在工作, + 它将会继续打印队列中剩余的任务。 + 超级用户 (<username>root</username>) 总是可以提交任务, + 甚至提交到一个禁止的队列。</para> + + <para>这个命令在测试一台新打印机或者安装过滤器时非常有用: + 禁止队列并提交以 + <username>root</username> 提交任务。 + 其他用户将不能提交任务直到您完成了测试并用命令 + <command>enable</command> 重新启用了队列的时候。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><command>down <replaceable>printer-name</replaceable> + <replaceable>message</replaceable></command></term> + + <listitem> + <para>打印机下线。 等于 + <command>disable</command> 命令后跟一个 <command>stop</command> 命令。 + <replaceable>message</replaceable> 将作为打印机状态, + 当用户使用 &man.lpq.1; 或者 <command>lpc status</command> + 命令查看打印机队列状态的时候显示出来。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><command>enable + <replaceable>printer-name</replaceable></command></term> + + <listitem> + <para>为打印机开启队列。 + 用户可以提交任务到打印机但是在打印机启动之前不会打印出任何东西。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><command>help + <replaceable>command-name</replaceable></command></term> + + <listitem> + <para>打印关于 + <replaceable>command-name</replaceable> 命令的帮助。 不带 + <replaceable>command-name</replaceable>, + 则打印可用命令的摘要。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><command>restart + <replaceable>printer-name</replaceable></command></term> + + <listitem> + <para>启动打印机。 普通用户可以使用这个命令, + 当一些特别的环境导致 + <application>LPD</application> 锁死时, 但他们不能启用一台使用 + <command>stop</command> 或者 + <command>down</command> 命令停用的打印机。 + <command>restart</command> 命令等同于 + <command>abort</command> 后跟着一个 + <command>start</command>。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><command>start + <replaceable>printer-name</replaceable></command></term> + + <listitem> + <para>启用打印机。 打印机将开始打印队列中的任务。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><command>stop + <replaceable>printer-name</replaceable></command></term> + + <listitem> + <para>停止打印机。 打印机将完成当前任务并且将不再打印队列中的任务任务。 + 尽管打印机被停用, + 但用户仍然可以提交任务到一个开启的队列。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><command>topq <replaceable>printer-name</replaceable> + <replaceable>job-or-username</replaceable></command></term> + + <listitem> + <para>重新以 + <replaceable>printer-name</replaceable> 安排队列, + 通过将列出的 <replaceable>job</replaceable> 编号或者指定的所属 + <replaceable>username</replaceable> 的任务放在队列的最前面。 + 对于这个命令, 您不可以使用 + <literal>all</literal> 当作 + <replaceable>printer-name</replaceable>。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><command>up + <replaceable>printer-name</replaceable></command></term> + + <listitem> + <para>打印机上线; 相对于 + <command>down</command> 命令。 等同于 + <command>start</command> 后跟着一个 + <command>enable</command> 命令。</para> + </listitem> + </varlistentry> + </variablelist> + + <para>&man.lpc.8; 的命令行接受上面的命令。 + 如果您不输入任何命令, &man.lpc.8; 则进入一个交互模式, + 在这里您可以输入命令直到输入 <command>exit</command>, + <command>quit</command>, 或者文件结束符。</para> </sect2> </sect1> <sect1 id="printing-lpd-alternatives"> - <title>Alternatives to the Standard Spooler ** 翻译进行中 **</title> + <title>替换标准打印池</title> - <para></para> + <para>如果您已经通读过了这个手册, + 那么到现在您应该已经了解了关于 FreeBSD 包含的打印池系统 + <application>LPD</application> + 的一切。 您可能发现了它很多的缺点, + 它们很自然的让您提出这样的问题: + <quote>这里还有什么打印池系统吗 (并且可以工作在 + FreeBSD 上) ?</quote></para> + + <variablelist> + <varlistentry> + <term>LPRng</term> + + <indexterm><primary>LPRng</primary></indexterm> + <listitem> + <para><application>LPRng</application>, 它的意思是 + <quote>LPR: 下一代</quote>, + 是一个完全重写的 PLP。 Patrick Powell + 和 Justin Mason (PLP 维护的主要负责人) 合作完成了 + <application>LPRng</application>。 + <application>LPRng</application> 的主站是 <ulink + url="http://www.lprng.org/"></ulink>。</para> + </listitem> + </varlistentry> + <varlistentry> + <term>CUPS</term> + + <indexterm><primary>CUPS</primary></indexterm> + <listitem> + <para><application>CUPS</application>, 通用 UNIX 打印系统, + 提供了一个轻便的打印层给 &unix;-基础的操作系统。 + 它是由 Easy Software + Products 开发的, 并且成为了 &unix; + 供应商和用户的标准打印解决方案。</para> + + <para><application>CUPS</application> 使用 Internet 打印协议 + (<acronym>IPP</acronym>) 作为管理打印任务和队列的基础。 + 行式打印机守护程序 + (<acronym>LPD</acronym>) 服务器消息块 + (<acronym>SMB</acronym>), 和 AppSocket (a.k.a. JetDirect) + 协议的部分功能也被支持。 CUPS + 增加了基于浏览网络打印机和 PostScript 打印机描述 + (<acronym>PPD</acronym>) 的打印选项来支持 + &unix; 下的真实打印。</para> + + <para><application>CUPS</application> 的主站是 <ulink + url="http://www.cups.org/"></ulink>。</para> + </listitem> + </varlistentry> + </variablelist> </sect1> <sect1 id="printing-troubleshooting"> - <title>Troubleshooting ** 翻译进行中 **</title> + <title>疑难问题</title> + + <para>在使用 &man.lptest.1; 进行简单的测试之后, + 您可能得到了下面的结果, + 而不是正确的结果:</para> + + <variablelist> + <varlistentry> + <term>过了一会儿, 它工作了; 或者, 它没有退出一整张纸。</term> + + <listitem> + <para>打印机进行了打印, 但在这之前它呆了一段而且什么都没做。 + 事实上, 您可能需要按一下打印机上的 + 打印剩余 或者 送纸 按钮来让结果出现。</para> + + <para>如果这是问题所在, 打印机可能在等待在打印之前任务是否还有更多的数据。 + 要修正这个问题, 您可以让文本过滤器发送一个送纸字符 + (或者其他需要的) 到打印机。 + 这通常足够让打印机立即打印出内部缓存内剩余的文本。 + 它同样可以用来确保每个任务的结尾都占用一整张纸, + 这样下一个任务才不会在前一个任务最后一张纸的中间开始。</para> + + <para>接下来的 shell 脚本 + <filename>/usr/local/libexec/if-simple</filename> + 的脚本打印了一个送纸符在它发送任务到打印机之后:</para> - <para></para> + <programlisting>#!/bin/sh +# +# if-simple - Simple text input filter for lpd +# Installed in /usr/local/libexec/if-simple +# +# Simply copies stdin to stdout. Ignores all filter arguments. +# Writes a form feed character (\f) after printing job. + +/bin/cat && printf "\f" && exit 0 +exit 2</programlisting> + </listitem> + </varlistentry> + + <varlistentry> + <term>它的输出产生了 <quote>楼梯效果。</quote></term> + + <listitem> + <para>您可能在纸上得到下面这些:</para> + + <programlisting>!"#$%&'()*+,-./01234 + "#$%&'()*+,-./012345 + #$%&'()*+,-./0123456</programlisting> + + <indexterm><primary>MS-DOS</primary></indexterm> + <indexterm><primary>OS/2</primary></indexterm> + <indexterm><primary>ASCII</primary></indexterm> + <para>您也成为了 <emphasis>楼梯效果</emphasis> + 的受害者, 这是由对新行的标志字符的解释不一致造成的。 + &unix; 风格的操作系统使用一个单个字符: + ASCII 码 10, + 即换行 (LF)。 &ms-dos;, &os2;, 和其他的系统使用一对儿字符, + ASCII 码 10 <emphasis>和</emphasis> ASCII 码 + 13 (回车 CR)。 许多打印机使用 &ms-dos; + 的习惯来代表新行。</para> + + <para>当您在 FreeBSD 上打印时, 您的文本仅用了换行字符。 + 打印机, 打印机看到换行字符后, + 走一行纸, 但还光标位置还是在这张纸上要打印的下一个字符处。 + 这就是回车的作用: + 将下一个要打印的字符的位置移到纸张的左边缘。</para> + + <para>这里是 FreeBSD 想要打印机做的:</para> + + <informaltable frame="none" pgwide="1"> + <tgroup cols="2"> + <tbody> + <row> + <entry>打印机收到 CR</entry> + <entry>打印机打印 CR</entry> + </row> + + <row> + <entry>打印机收到 LF</entry> + <entry>打印机打印 CR + LF</entry> + </row> + </tbody> + </tgroup> + </informaltable> + + <para>下面有几种完成这个的办法:</para> + + <itemizedlist> + <listitem> + <para>使用打印机的配置开关或者控制面板来更改它对这些字符的解释。 + 查看打印机的手册来找到怎样更改。</para> + + <note> + <para>如果您引导您的系统到其他除了 + FreeBSD 之外的操作系统, 您可能不得不 + <emphasis>重新配置</emphasis> 打印机使用 + 这个操作系统对 CR 和 LF 字符的解释。 + 您可能更喜欢下面这另一种解决方案。</para> + </note> + </listitem> + + <listitem> + <para>让 FreeBSD 的串口驱动自动转换 LF 到 CR+LF。 + 当然, 这 <emphasis>仅仅</emphasis> 工作在串口打印机上。 + 要开启这个功能, + 定义 <literal>ms#</literal> 变量并 + 设置 <literal>onlcr</literal> 模式在 + <filename>/etc/printcap</filename> 文件中相应打印机处。</para> + </listitem> + + <listitem> + <para>发送一个 <emphasis>转义码</emphasis> 到打印机来让它临时对 LF 字符做不同的处理。 + 参考您的打印机手册来了解您的打印机支持哪些转义码。 + 当您找到合适的转义码, + 修改文本过滤器让其先发送这个转义码, + 然后再发送打印任务。</para> + + <indexterm><primary>PCL</primary></indexterm> + <para>这里是一个为懂得 + Hewlett-Packard PCL 转义码的打印机编写的文本过滤器。 + 这个过滤器使得打印机将 LF 作为一个 LF 和一个 CR 来对待; + 然后它发送任务; 最后发送一个送纸符弹出任务的最后一张纸。 + 它应该可以在几乎所有 + Hewlett Packard 打印机上工作。</para> + + <programlisting>#!/bin/sh +# +# hpif - Simple text input filter for lpd for HP-PCL based printers +# Installed in /usr/local/libexec/hpif +# +# Simply copies stdin to stdout. Ignores all filter arguments. +# Tells printer to treat LF as CR+LF. Ejects the page when done. + +printf "\033&k2G" && cat && printf "\033&l0H" && exit 0 +exit 2</programlisting> + + <para>下面是一个 <filename>/etc/printcap</filename> 文件的例子在叫做 + <hostid>orchid</hostid> 的主机上。 它只有一台打印机连接在第一个并口上, + 一台 Hewlett Packard + LaserJet 3Si 名字叫做 <literal>teak</literal>。 它使用上面那段脚本作为文本过滤器:</para> + + <programlisting># +# /etc/printcap for host orchid +# +teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\ + :lp=/dev/lpt0:sh:sd=/var/spool/lpd/teak:mx#0:\ + :if=/usr/local/libexec/hpif:</programlisting> + </listitem> + </itemizedlist> + </listitem> + </varlistentry> + + <varlistentry> + <term>行行覆盖。</term> + + <listitem> + <para>打印机从来不进纸换行。 + 所有的文本都打印在头一行文本的上面。</para> + + <para>这个问题是 <quote>相反</quote> 于楼梯效果, + 像上面描述的那样, 并且更少见。 + 一些地方, LF 这个 FreeBSD 用来结束一行的字符被作为 + CR 这个将打印位置返回到纸的左边的字符对待。 + 而没有向下走纸一行。</para> + + <para>使用打印机的配置开关或者控制面板来强制对 + LF 和 CR 进行下面的转换:</para> + + <informaltable frame="none" pgwide="1"> + <tgroup cols="2"> + <thead> + <row> + <entry>打印机收到</entry> + <entry>打印机打印</entry> + </row> + </thead> + + <tbody> + <row> + <entry>CR</entry> + <entry>CR</entry> + </row> + + <row> + <entry>LF</entry> + <entry>CR + LF</entry> + </row> + </tbody> + </tgroup> + </informaltable> + </listitem> + </varlistentry> + + <varlistentry> + <term>打印丢掉字符。</term> + + <listitem> + <para>当打印时, 每行里打印机都丢掉一些字符没有打。 + 这个问题可能随着打印的进行越发严重, + 丢掉越来越多的字符。</para> + + <para>这个问题是由打印机跟不上计算机通过串口发送数据的速度造成的 + (这个问题应该不会发生在并口打印机上)。 + 有两种方法能克服这个问题:</para> + + <itemizedlist> + <listitem> + <para>如果打印机支持 XON/XOFF 流量控制, + 那就让 FreeBSD 使用它, 通过加入 <literal>ixon</literal> 模式在 + <literal>ms#</literal> 变量里。</para> + </listitem> + + <listitem> + <para>如果打印机支持载波流量控制, + 指定 <literal>crtscts</literal> 模式在 + <literal>ms#</literal> 变量里。 + 并且要确定连接打印机和计算机的线是支持载波流量控制的。</para> + </listitem> + </itemizedlist> + </listitem> + </varlistentry> + + <varlistentry> + <term>它打印出垃圾。</term> + + <listitem> + <para>打印机打印出的东西看起来是一些随机的字符, + 而不是想要打印的东西。</para> + + <para>这通常意味着另一种串口打印机通讯参数设置不正确的错误。 + 复查 + <literal>br</literal> 变量中设定的波特, 和 + <literal>ms#</literal> 中的校验设置; 确定打印机也在使用和 + <filename>/etc/printcap</filename> 文件中相同的设置。</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>没有反应。</term> + + <listitem> + <para>如果没有反应, 问题就可能出在 + FreeBSD 而不是硬件上了。 增加日志文件 + (<literal>lf</literal>) 变量到 + <filename>/etc/printcap</filename> 文件里出现问题的打印机的记录处。 + 比如, 下面是打印机 <literal>rattan</literal> 的记录, 使用了 + <literal>lf</literal> 变量:</para> + + <programlisting>rattan|line|diablo|lp|Diablo 630 Line Printer:\ + :sh:sd=/var/spool/lpd/rattan:\ + :lp=/dev/lpt0:\ + :if=/usr/local/libexec/if-simple:\ + :lf=/var/log/rattan.log</programlisting> + + <para>然后, 再次打印。 检查日志文件 (在我们的例子当中, 是 + <filename>/var/log/rattan.log</filename> 这个文件) 来看是否有错误信息出现。 + 根据出现的信息, + 试着来修正问题。</para> + + <para>如果您没有指定 <literal>lf</literal> 变量, + <application>LPD</application> 会使用 + <filename>/dev/console</filename> 作为默认值。</para> + </listitem> + </varlistentry> + </variablelist> </sect1> </chapter> |