After performing the simple test with lptest(1), you might have gotten one of the following results instead of the correct printout:
The printer printed the above, but it sat for awhile and did nothing. In fact, you might have needed to press a PRINT REMAINING or FORM FEED button on the printer to get any results to appear.
If this is the case, the printer was probably waiting to see if there was any more data for your job before it printed anything. To fix this problem, you can have the text filter send a FORM FEED character (or whatever is necessary) to the printer. This is usually sufficient to have the printer immediately print any text remaining in its internal buffer. It is also useful to make sure each print job ends on a full sheet, so the next job does not start somewhere on the middle of the last page of the previous job.
The following replacement for the shell script
/usr/local/libexec/if-simple
prints a
form feed after it sends the job to the printer:
#!/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
You got the following on paper:
!"#$%&'()*+,-./01234 "#$%&'()*+,-./012345 #$%&'()*+,-./0123456
You have become another victim of the staircase effect, caused by conflicting interpretations of what characters should indicate a new line. UNIX® style operating systems use a single character: ASCII code 10, the line feed (LF). MS-DOS®, OS/2®, and others uses a pair of characters, ASCII code 10 and ASCII code 13 (the carriage return or CR). Many printers use the MS-DOS® convention for representing new-lines.
When you print with FreeBSD, your text used just the line feed character. The printer, upon seeing a line feed character, advanced the paper one line, but maintained the same horizontal position on the page for the next character to print. That is what the carriage return is for: to move the location of the next character to print to the left edge of the paper.
Here is what FreeBSD wants your printer to do:
Printer received CR | Printer prints CR |
Printer received LF | Printer prints CR + LF |
Here are some ways to achieve this:
Use the printer's configuration switches or control panel to alter its interpretation of these characters. Check your printer's manual to find out how to do this.
If you boot your system into other operating systems besides FreeBSD, you may have to reconfigure the printer to use a an interpretation for CR and LF characters that those other operating systems use. You might prefer one of the other solutions, below.
Have FreeBSD's serial line driver automatically
convert LF to CR+LF. Of course, this works with printers
on serial ports only. To enable this
feature, use the ms#
capability and
set the onlcr
mode
in the /etc/printcap
file
for the printer.
Send an escape code to the printer to have it temporarily treat LF characters differently. Consult your printer's manual for escape codes that your printer might support. When you find the proper escape code, modify the text filter to send the code first, then send the print job.
Here is an example text filter for printers that understand the Hewlett-Packard PCL escape codes. This filter makes the printer treat LF characters as a LF and CR; then it sends the job; then it sends a form feed to eject the last page of the job. It should work with nearly all Hewlett Packard printers.
#!/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
Here is an example /etc/printcap
from a host called orchid
. It has a single printer
attached to its first parallel port, a Hewlett Packard
LaserJet 3Si named teak
. It is using the
above script as its text filter:
# # /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:
The printer never advanced a line. All of the lines of text were printed on top of each other on one line.
This problem is the „opposite” of the staircase effect, described above, and is much rarer. Somewhere, the LF characters that FreeBSD uses to end a line are being treated as CR characters to return the print location to the left edge of the paper, but not also down a line.
Use the printer's configuration switches or control panel to enforce the following interpretation of LF and CR characters:
Printer receives | Printer prints |
---|---|
CR | CR |
LF | CR + LF |
While printing, the printer did not print a few characters in each line. The problem might have gotten worse as the printer ran, losing more and more characters.
The problem is that the printer cannot keep up with the speed at which the computer sends data over a serial line (this problem should not occur with printers on parallel ports). There are two ways to overcome the problem:
If the printer supports XON/XOFF flow control, have
FreeBSD use it by specifying the ixon
mode
in the ms#
capability.
If the printer supports carrier flow control, specify
the crtscts
mode in the
ms#
capability.
Make sure the cable connecting the printer to the computer
is correctly wired for carrier flow control.
The printer printed what appeared to be random garbage, but not the desired text.
This is usually another symptom of incorrect
communications parameters with a serial printer. Double-check
the bps rate in the br
capability, and the
parity setting in the
ms#
capability; make sure the printer is
using the same settings as specified in the
/etc/printcap
file.
If nothing happened, the problem is probably within
FreeBSD and not the hardware. Add the log file
(lf
) capability to the entry for the
printer you are debugging in the
/etc/printcap
file. For example, here is
the entry for rattan
, with the
lf
capability:
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
Then, try printing again. Check the log file (in our
example, /var/log/rattan.log
) to see any
error messages that might appear. Based on the messages you
see, try to correct the problem.
If you do not specify a lf
capability,
LPD uses
/dev/console
as a default.
All FreeBSD documents are available for download at http://ftp.FreeBSD.org/pub/FreeBSD/doc/
Questions that are not answered by the
documentation may be
sent to <freebsd-questions@FreeBSD.org>.
Send questions about this document to <freebsd-doc@FreeBSD.org>.