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 作为默认值。

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

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