FreeBSD 使用手册
上一页 | 第10章 　打印 | 下一页

# 10.7 疑难问题

在使用 lptest(1) 进行简单的测试之后， 您可能得到了下面的结果， 而不是正确的结果：

过了一会儿， 它工作了； 或者， 它没有退出一整张纸。

  打印机进行了打印， 但在这之前它呆了一段而且什么都没做。 事实上， 您可能需要按一下打印机上的 打印剩余 或者 送纸 按钮来让结果出现。

  如果这是问题所在， 打印机可能在等待， 看看在打印之前， 您的任务是否还有更多的数据。 要修正这个问题， 您可以让文本过滤器发送一个送纸字符 (或者其他需要的) 到打印机。 这通常足够让打印机立即打印出内部缓存内剩余的文本。 它同样可以用来确保每个任务的结尾都占用一整张纸， 这样下一个任务才不会在前一个任务最后一张纸的中间开始。

  接下来的 shell 脚本 `/usr/local/libexec/if-simple` 的脚本打印了一个送纸符在它发送任务到打印机之后：

      #!/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

它的输出产生了 “楼梯效果”。

  您可能在纸上得到下面这些：

      !"#$%&'()*+,-./01234
                      "#$%&'()*+,-./012345
                                       #$%&'()*+,-./0123456

  您也成为了 楼梯效果 的受害者， 这是由对新行的标志字符的解释不一致造成的。 UNIX® 风格的操作系统使用一个单个字符： ASCII 码 10， 即换行 (LF)。 MS-DOS®， OS/2®， 和其他的系统使用一对儿字符， ASCII 码 10 和 ASCII 码 13 (回车 CR)。 许多打印机使用 MS-DOS 的习惯来代表新行。

  当您在 FreeBSD 上打印时， 您的文本仅用了换行字符。 打印机， 打印机看到换行字符后， 走一行纸， 但还光标位置还是在这张纸上要打印的下一个字符处。 这就是回车的作用： 将下一个要打印的字符的位置移到纸张的左边缘。

  这里是 FreeBSD 想要打印机做的：

  打印机收到 CR | 打印机打印 CR
  打印机收到 LF | 打印机打印 CR + LF

  下面有几种完成这个的办法：

  - 使用打印机的配置开关或者控制面板来更改它对这些字符的解释。 查看打印机的手册来找到怎样更改。

    > 注意: 如果您引导您的系统到其他除了 FreeBSD 之外的操作系统， 您可能不得不 重新配置 打印机使用 这个操作系统对 CR 和 LF 字符的解释。 您可能更喜欢下面这另一种解决方案。

  - 让 FreeBSD 的串口驱动自动转换 LF 到 CR+LF。 当然， 这 仅仅 工作在串口打印机上。 要开启这个功能， 定义 `ms#` 变量并 设置 `onlcr` 模式在 `/etc/printcap` 文件中相应打印机处。

  - 发送一个 转义码 到打印机来让它临时对 LF 字符做不同的处理。 参考您的打印机手册来了解您的打印机支持哪些转义码。 当您找到合适的转义码， 修改文本过滤器让其先发送这个转义码， 然后再发送打印任务。

    这里是一个为懂得 Hewlett-Packard PCL 转义码的打印机编写的文本过滤器。 这个过滤器使得打印机将 LF 作为一个 LF 和一个 CR 来对待； 然后它发送任务； 最后发送一个送纸符弹出任务的最后一张纸。 它应该可以在几乎所有 Hewlett Packard 打印机上工作。

        #!/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

    下面是一个 `/etc/printcap` 文件的例子在叫做 `orchid` 的主机上。 它只有一台打印机连接在第一个并口上， 一台 Hewlett Packard LaserJet 3Si 名字叫做 `teak`。 它使用上面那段脚本作为文本过滤器：

        #
        #  /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:

行行覆盖。

  打印机从来不进纸换行。 所有的文本都打印在头一行文本的上面。

  这个问题是 “相反” 于楼梯效果， 像上面描述的那样， 并且更少见。 一些地方， LF 这个 FreeBSD 用来结束一行的字符被作为 CR 这个将打印位置返回到纸的左边的字符对待。 而没有向下走纸一行。

  使用打印机的配置开关或者控制面板来强制对 LF 和 CR 进行下面的转换：

  打印机收到 | 打印机打印
  --- | ---
  CR | CR
  LF | CR + LF

打印丢掉字符。

  当打印时， 每行里打印机都丢掉一些字符没有打。 这个问题可能随着打印的进行越发严重， 丢掉越来越多的字符。

  这个问题是由打印机跟不上计算机通过串口发送数据的速度造成的 (这个问题应该不会发生在并口打印机上)。 有两种方法能克服这个问题：

  - 如果打印机支持 XON/XOFF 流量控制， 那就让 FreeBSD 使用它， 通过加入 `ixon` 模式在 `ms#` 变量里。

  - 如果打印机支持请求/清除硬件握手信号 （通常时 `RTS/CTS`）， 指定 `crtscts` 模式在 `ms#` 变量里。 并且要确定连接打印机和计算机的线是支持硬件流量控制的。

它打印出垃圾。

  打印机打印出的东西看起来是一些随机的字符， 而不是想要打印的东西。

  这通常意味着另一种串口打印机通讯参数设置不正确的错误。 复查 `br` 变量中设定的波特， 和 `ms#` 中的校验设置； 确定打印机也在使用和 `/etc/printcap` 文件中相同的设置。

没有反应。

  如果没有反应， 问题就可能出在 FreeBSD 而不是硬件上了。 增加日志文件 (`lf`) 变量到 `/etc/printcap` 文件里出现问题的打印机的记录处。 比如， 下面是打印机 `rattan` 的记录， 使用了 `lf` 变量：

      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

  然后， 再次打印。 检查日志文件 (在我们的例子当中， 是 `/var/log/rattan.log` 这个文件) 来看是否有错误信息出现。 根据出现的信息， 试着来修正问题。

  如果您没有指定 `lf` 变量， LPD 会使用 `/dev/console` 作为默认值。

上一页 | 起始页 | 下一页
替换标准后台打印 | 上一级 | Linux二进制兼容模式

本文档和其它文档可从这里下载：ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

如果对于FreeBSD有问题，请先阅读文档，如不能解决再联系<questions@FreeBSD.org>.
关于本文档的问题请发信联系 <doc@FreeBSD.org>.