Linux has a fairly complicated printing system, compared to the printing services most PCs use. It allows many users to print documents at the same time, and each user can send documents from one or more applications without waiting for the previous document to finish printing. The printing system processes the files to be printed correctly on different kinds of printers connected to the computer in different ways. If you print on a network, files can be created on one host and printed out on a printer controlled by another host.
Before we go into the inner workings of the Linux printing system, we would like to point you to http://www.linuxprinting.org, a very comprehensive site with information about printing on Linux. If you have problems or questions concerning printing that this chapter cannot answer, this site should be your next stop.
The whole process happens without much fuss, when you press the Print button in an application or issue a command, such as lpr, to print a document. That document does not go directly to the printer, though, because it might already be busy. Instead, the document is stored in a temporary file in a directory called the printer spool directory. As the word “spool” suggests, the documents get taken out of the directory one by one as the printer becomes free. Each printer has its own spool directory.
When Linux starts, it sets up a printer daemon (an independently running process) called lpd. This process waits around, checking each spool directory for files that should be printed. When the process finds a file, it makes a copy of itself. The new lpd takes control of the print spool where the file was placed and queues it for printing. It won’t send the next file to that printer until the last file has finished printing. The master lpd starts an lpd for each spooling directory on the system when a file is sent to it, so there may be as many lpd daemons running as the number of active spooling directories, plus the master lpd. Each subordinate lpd stays around until its spool directory is empty.
Your Linux installation process associates
the printer port on your system to a device named in the
/dev
directory. You must then link that device
name to the convenient printer names you use in your commands;
that’s the role of the printer capability file
called /etc/printcap
.
Another key task in printer management is to make sure you have
filters in place for lpd to use when formatting
documents for printing. These filters are also specified in the
/etc/printcap
file, and we’ll
talk a lot about them in this section.
There are several printer-support packages for Linux. Most distributions use the BSD-derived package that contains the lpd printer daemon. These packages include a set of utilities and manpage documents to support traditional Unix-style printing on Linux. The BSD printing system doesn’t have as many administrative tools or user controls as, for example, the System V Unix printer-management system (which uses the lpsched or lprng daemon), but each user controls the files that she sends to the printer. This section describes installation and configuration of the BSD printer-support package. (The various printing utilities are described in Section 9.6 in Chapter 9.)
There is a new system called Common Unix Printer System (CUPS) that is bound to take over the Linux (if not Unix) printing world. At this point, very few distributions come with CUPS preinstalled — the BSD printing system is still ubiquitous — which is why we concentrate on the older system here. We’ll look at CUPS in brief later in this chapter, though.
Some Linux distributions provide a printer-management tool that simplifies printer installation and management through a GUI. These tools are documented by the vendor that supplies them. They manage printing by controlling the same tools and files we are about to describe, but with less fine control. They can save you a lot of trouble getting started, but they don’t always get things right. If you want to correct an installation set up through these tools or want to improve on their performance, you still should work through the procedures in this section.
Before you set up printer services, be sure the printing devices are online. If you also use another operating system, such as Microsoft Windows, you can exercise the hardware to ensure that it is connected properly and working before loading Linux. Successfully printing a document from another operating system immediately eliminates one major source of woe and head scratching. Similarly, if you are going to use printer services on a network, your system should be on the network and all protocols functioning before proceeding.
A word about the so-called GDI printers (or Windows printers) is in order here. GDI printers are really brain-damaged printers in the true sense of the meaning: their “brain,” the internal processing unit that builds up a page from the data sent to it, has been removed; this task is performed in the printer driver on the computer itself. The printer itself only consists of the actual printing hardware and a very small amount of software that controls the hardware. Of course, drivers for these printers are typically available only for Microsoft Windows systems (where the graphics subsystem is called GDI, which is where the name comes from), so there is hardly any hope of getting such a printer to work with Linux.
Install printer services as the root
user, with
superuser privileges. The superuser is the only user besides the
lpd print daemon able to write directly to a
printer by directing output to the corresponding output device. Other
users cannot send output directly to the printer and must instead use
the printer utilities to handle printing tasks.
Before you get started, you can abuse your root privileges to verify
that your system’s assigned device files actually
have a valid link to the physical device. Just send a brief
ASCII test file directly to the printer by
redirection. For
instance, if you have a printer on your
first parallel port, its device name is probably either
/dev/lp0
or
/dev/lp1
, depending on your installation. The
following command outputs some text suited for testing a printer
setup, which you can redirect to your printer. (If you have an early
PostScript printer, you may need instead to send it a small
PostScript test file to prevent it from getting confused. Newer
PostScript printers can often perform this conversion themselves.)
lptest > /dev/lp1
The lptest utility (which may not be available on all distributions) is designed to conveniently exercise an ASCII printer or terminal to make sure it is working correctly. It sends a prepend file composed of the 96 ASCII characters in a sequence that creates a “ripple” or “barber-pole” output effect. The default output of lptest on Linux is 16,000 characters arrayed in 79-character lines, long enough to require more than one page to print. If you run lptest with no arguments, it prints the standard output to your screen, and you can see what should be sent to the printer. The lptest command allows you to trim the width of the output column and to limit the number of output lines. For example, to display an output 35 characters wide, limited to six lines, you would enter:
lptest 35 6
The output should look much like this:
!"#$%&'( )*+,-./0123456789:;<=>?@ABC "#$%&'( )*+,-./0123456789:;<=>?@ABCD #$%&'( )*+,-./0123456789:;<=>?@ABCDE $%&'( )*+,-./0123456789:;<=>?@ABCDEF %&'( )*+,-./0123456789:;<=>?@ABCDEFG &'( )*+,-./0123456789:;<=>?@ABCDEFGH
This output is short enough that you can see the result of redirecting it to your printer without wasting a lot of paper, and it is long enough to identify many obvious problems with printing.
Of course, you can also use the cat command to direct a file to the printer. To send a PostScript test file to a PostScript printer, for example, type:
cat testfile.ps > /dev/lp1
If you have a serial printer, try directing output to the serial port to which it is connected. For the first serial port (COM1 in MS-DOS) try something like:
lptest > /dev/ttys0
or:
lptest > /dev/ttyS0
Make sure you send to the correct serial port; don’t
try to output the file to a serial mouse, for example. If your serial
printer is on, say, the second serial port, it is addressed as
/dev/ttyS1
or /dev/ttys1
.
If you have a page printer that buffers a partial page, after it
stops printing you may need to take the printer offline and press the
Form Feed button to get it to print the last partial page.
Don’t forget to put the printer back online
afterward. (A permanent solution is to get Linux to send the formfeed
character to the printer, either by forcing it through the
/etc/printcap
entry for the printer or by having
the printer filter-append it to the end of the file.
We’ll discuss these options later.)
If your little test resulted in “laddered” text (text that looks something like the following example) and then continued off the page, the printer did not insert a carriage return at the end of each line:
!"#$%&'( )*+,-./0123456789:;<=>?@ABC "#$%&'( )*+,-./0123456789:;<=>?@ABCD #$
You might be able to figure out what went wrong here. Text files in Unix use just a newline (also known as a linefeed, ASCII code 10) to terminate each line. MS-DOS uses both a newline and a carriage return. Your printer was therefore set up to use MS-DOS-style line endings with both newline and carriage-return characters at the end of each line. In order to print a text file from Unix, you can install a printer filter to accommodate the Unix newline, or you can reconfigure your printer to properly return to the start of the line on receipt of a newline character. Often this is simply a matter of setting a dip switch. Check your printer manual. (Be careful about changing your printer characteristics if you use multiple operating systems.)
Laddering won’t be an issue if you have a printer using a page-description language, such as PostScript (the universally used page-layout language from Adobe), and you always filter plain text into that output form before printing. Filtering is described later in this chapter.
OK, you have your printer hardware set up and connected. You should collect a hardcopy of your resource documents (at least the manpages for the print utilities and files described here, and the Printing HOWTO file). Also, it is useful to have the technical specifications for your printer. Often these are no longer provided when you buy your printer, but you can usually download the information you need from an FTP site or a web site operated by the printer manufacturer. While you are retrieving such information, look around and see if there is documentation (such as a description of printer error messages and their meanings) that can help you troubleshoot and manage your printer. Most printer manufacturers also offer a technical manual for the printer that you can buy. This may or may not be the same volume as the service manual.
For example, on the Hewlett-Packard web site, http://www.hp.com/cposupport/software.html, you can retrieve printer technical data sheets; product specs; port-configuration information; PostScript, PCL, and HP-GL files for testing your printers (and filters); descriptions of printer control sequences you can pass to the printer to control its behavior; and documents telling how you can integrate lpd-based printing services with HP’s JetAdmin package (and thereby with Netware-networked printers as well).
Now, before starting, take a deep breath; be patient with yourself. Printer services configuration is a skill that takes time to develop. If you have sufficiently standard equipment and successfully use one of the new-fangled printer management utilities to quickly and efficiently install and configure printer services, celebrate! Then note that you can probably fine-tune the installation for better performance by applying the procedures we describe next, and perhaps by using filters and utilities written specifically to support all the features of your printer model. If you decide to revise a successful printer installation, make sure you take notes on the changes you make so that you can find your way back if your changes don’t do what you expected.
In order to print from Linux, you need to install the BSD print system (or an alternative system). This provides basic tools, but it does not support modern printers. Indeed, it was designed to support line printers (hence the name “line printing daemon”) and devices common to the computer rooms of the 1960s and 1970s. In order to support modern printers, powerful supplemental packages provide the features most users think of as essential. (The ftp://ftp.ibiblio.org FTP site and its mirrors archive the packages we mention here.)
In this section, we discuss some important packages to support modern print services. We assume your system will have at least the groff formatter, the Ghostscript page-formatting package, and the GNU Enscript filter packages, which are described in Chapter 9. Most Linux distributions already include these as well as other formatting and printing utilities. If yours does not, you can retrieve them from the usual Linux FTP sites or take them from the CD-ROM of another distribution.
It matters where you get formatting and filtering packages. If you receive Ghostscript from a European distribution, for example, it probably defaults to an A4 paper format rather than the 8.5x11-inch paper format kept in U.S. binary archives. In either case, you can easily override the default through an lpr option passed to the filter. Alternatively, you can build the tools from source.
The trend in printer technology is away from character-oriented output and toward adoption of a page-description language (PDL) that provides sophisticated graphics and font control. By far the most popular of the PDLs is PostScript, which has been widely adopted in the Unix and Internet communities. A major reason for its acceptance is Ghostscript, a PostScript implementation copyrighted by Aladdin Enterprises. A version is also distributed under the GNU Public License through the Free Software Foundation, along with a large font library that can be used with either version and with other PostScript interpreters. Ghostscript is indispensable if you do any kind of printing besides character-based output, and it is easily extensible.
Ghostscript implements almost all the instructions of the PostScript language and supports viewer utilities, such as Ghostview, that allow PostScript documents to be displayed in an X window. Similarly, excellent filters are readily available that convert PostScript output into other printing languages, such as Hewlett-Packard’s PCL, and into forms printable as raster output on inkjet, dot matrix, and laser printers. The Ghostscript package supports Adobe Type 1 and 3 PostScript fonts and provides a number of utilities for graphics format conversion and filtering. It can even generate PDF files — i.e., files that conform to the Adobe Portable Document Format specification.
Ghostscript may be insufficient to use by itself, however, because it doesn’t provide printer control to switch between PostScript and text modes. Although Ghostscript does provide a filter that provides this capability (and more), the nenscript filter meets the tests of simplicity, flexibility, and reliability for most systems, so we document it here.
A typical Linux formatting and printing system might primarily use groff to format documents, creating PostScript output that is then processed by Ghostscript for printing and display.
You probably also want to install the TEX formatting package. Even if you do not install the full TEX distribution, you should at least install the xdvi utility, in order to view TEX output and (processed) Texinfo files in an X window (unless you have installed the KDE Desktop Environment, which contains a more user-friendly replacement called kdvi). Other filters can process device independent (DVI) output into forms such as PostScript (dvips) or PCL (dvilj) if you have an aversion to the Ghostscript package or need to use native printer fonts for efficient data transfer and rapid printing.
The Lout package is also worthy of consideration as an efficient and compact package to format text documents for PostScript output. It supports Level 2 PostScript and the Adobe Structuring Conventions, takes comparatively little memory, and comes with good enough documentation to learn quickly. Lout doesn’t create an intermediate output form; it goes directly from markup input to PostScript output.
To support graphics work and X Window System utilities, you probably
want to install other tools, some of which probably come with your
distribution. A collection of current versions of the most popular
print support packages for Linux can be found at the ftp://ftp.ibiblio.org Linux archive, in
/pub/Linux/system/printing
. The
netpbm and pbmplus packages
support a large variety of graphics file format conversions. (Such
formats have to be converted to PostScript before you try to print
them.) The Ghostview package provides display tools to view
PostScript files in an X Window System environment, and also provides
PostScript and PDF support for other packages, such as your web
browser.
The ImageMagick package, described in Chapter 9, deserves special mention. It lets you display a large number of graphics formats in an X window and convert many file formats to other file formats. (It uses Ghostview and Ghostscript when it needs to display a PostScript image.) Most of the graphics files you can print you can also display using ImageMagick.
A “magic” filter package may also save you much grief in configuring and supporting different document output formats. We will touch on the APSfilter magic filter package, but you may prefer the Magic-Filter package instead. Both are available at the ftp://ftp.ibiblio.org FTP archive. For more on magic filters, see Section 8.4.9 later in this chapter.
If you want to support fax devices, you can use the tiffg3 utility with Ghostscript to output Group III fax format files. To control a Class 1 or Class 2 fax modem on your Linux host, you can use the efax package, which is provided in many distributions, or you can install and configure the more capable, but more complex, FlexFax or HylaFax packages.
There are additional tools to support double-sided printing on laser printers, and packages that convert PostScript to less common printer-control languages to support Canon and IBM Proprinter devices, for example. There is a package to support printing in Chinese on laser printers and bitmap devices. Most of these packages don’t directly affect management of print services, so we don’t describe them in detail here, but this is a good time to install them if you wish to use them.
For the benefit of your users, make sure that all the manual pages for the packages you install are prepared properly when you complete your installations. Then run /sbin/mkwhatis (/usr/bin/mandb on Debian) to build the manual page index file that facilitates locating information online. Some packages, such as Ghostscript, also provide additional documention that you can print or make available on the system for reference. (Linux distributions tend to omit these documents, but you can FTP them from the sites where the software packages are developed and maintained. The GNU archives of the Free Software Foundation, for example, are accessed by anonymous FTP at ftp://GNU.ai.mit.edu.)
The essence of printer configuration is
creating correct entries in the printer capabilities file,
/etc/printcap
. A simple printcap entry for an HP
LaserJet 4MP laser printer attached to the first (bidirectional)
parallel port on an ISA bus PC
might look something like this:[31]
ljet|lp|ps|PostScript|600dpi 20MB memory|local|LPT1: :lp=/dev/lp0:rw: :sd=/var/spool/lpd/ljet4:mx#0:mc#0:pl#72:pw#85: :lf=/var/log/lpd-errs:if=/usr/local/cap/ljet4:
Don’t be scared. After reading the following sections, you will find yourself browsing printcap files with ease.
The /etc/printcap
file should accommodate every
printer and printer port or address — serial, parallel,
SCSI, USB, or
networked — your system will use. Make sure it reflects any
change in hardware. And as always, be aware that some hardware
changes should be performed only when power to your system is shut
off.
The printcap file format rules, briefly, are:
A comment line begins with a pound sign (#).
Each “line” of the printcap file defines a printer. A line that ends with a backslash character () is continued on the next line. Be very careful that no space or tab character follows the backslash character on the line. Traditionally, a continuation line is indented for readability. Multiple printer definitions can use the same actual printer, applying the same or different filters.
Fields in the line are separated by colon characters (:); fields can be empty. However, a printcap line entry cannot be an empty field.
Traditionally, the first field in the entry has no preceding colon.
The first field of the entry line contains names for the printer, each separated by a vertical bar character (|). In the earlier example entry, this portion is the name field:
ljet|lp|ps|PostScript|600dpi 20MB memory|local|LPT1
Printer naming is discussed in detail in the next section. You should
create a subdirectory of /var/spool/lpd
with the
same name as the first printer ID listed in each printcap entry.
However, the actual print spool that is used is assigned by the
sd
variable for the printcap entry; if the
sd
variable doesn’t point to the
actual print spool directory, any file sent to that printer
definition will vanish.
There must be at least a default printer entry in printcap. If a
printer is named lp, that printer is used as the default system
printer. Do not confuse the lp default printer name with the
lp
local printer variable, which is described
next. We recommend you use lp as an alias (one of the names after the
| characters) rather than the primary printer name (the first in the
list), so you can switch the default printer without difficulty.
Each local printer must have an lp
variable set.
In the previous example, the variable was set by this segment of the
printcap entry:
lp=/dev/lp0
For compulsive and sometimes practical reasons, some administrators recommend that the entries of the printcap file be kept in alphabetical order.
Most printer entries traditionally begin with a short printer name entry in the first field, at least one fuller printer name, and one longer explanatory entry. Thus, both ljet and PostScript are names for the printer whose nameline is:
ljet|lp|ps|PostScript|600dpi 20MB memory|local|LPT1:
Documents can be output to any printer named in a nameline in
/etc/printcap
.
You might name your printers after the model (HP, Epson), or the type
of printer (PS, PCL), or its specific modes. The DeskJet 540, for
example, is a printer that should have two definitions in the
printcap file, one for black print and another for color. The filters
you use to support it are likely to be those for the DeskJet 500 or
550C. For simple administration, you can assign printer names that
are the names of a filter or filter parameter used for a specific
device. Thus, if you have one LaserJet 4 and will use the ljet4
filter only for it, ljet4
is one logical name for
the printer. Similarly, a dot-matrix printer might be named
72dpi
when accessed via its low-resolution printer
definition line, and have the name 144dpi
when
accessed in a higher resolution.
If you use a printer administration utility that comes with your
Linux distribution, you may have to follow certain arbitrary rules in
preparing your printcap entries in order to get the tools working.
For example, if you use Red Hat’s printer manager
utility provided on the administrator’s desktop, you
may need to make sure that hp
is the first name of
the first active printer entry in the printcap file. This means that
when you need to switch default printers, you need to move the new
default printer to the top entry of the list and then remove the
hp
name from the old default printer and prepare
it as the first name of the new default printer. In order to prevent
confusion in use of the spool queues, you should just leave the
/var/spool/lpd/lp
directory set up and create a
new directory with the actual name of the spool directory that
corresponds to the name by which you actually will address the
printer. Thus, if you want to send your files to print on a printer
named moa, you will need to create a directory named
/var/spool/lpd/moa
, with appropriate
permissions, and specify that directory as the printer spool for that
printer. Setting up printer directories is described in the next
section.
The printcap file provides a number of variables that you can define. Most variables are provided to specify page parameters, files and directories, filters, communications channel settings, and remote access control. Anytime you prepare a printcap file on a new system, read the printcap manual page to make sure you use the correct variable names. Variables set in a printcap entry that are not recognized are passed through to the filter for processing.
The printcap variables described here are listed in roughly their
order of importance. Some variables are boolean, and are considered
set if they are present. Others are set with the assignment operator
(=) or numeric value operator (#) and a value; the variable precedes
the operator and the string or number follows the operator. Examples
of the variables described in the following list are included in the
contrived sample /etc/printcap
file that
follows. The printcap manual page has a more complete listing of
variables recognized by lpd.
sd
Specifies the spool directory used by
the printer. Spool directories should all be in the same
directory tree (on a fast hard disk), which is usually
/var/spool
. Spool files are defined even for
remote printers. Each spool file should have one of the names
assigned to the printer it serves.
lp
Assigns a local printer device,
typically connected through a parallel port, serial port, or SCSI
interface. The lp
variable must be assigned to a
device file in the /dev
directory, which may be
a link to a physical device. The lp
variable must
be assigned if there is a local printer. This variable should not be
assigned if the rp
variable is assigned (that is,
the print spool manager is on another host).[32] If
lp
assigns a serial device, the baud rate must be
specified with the br
variable.
lf
Specifies the log file for storing error messages. All printers should have this variable set and normally use the same error log file. Error entries include the name of the printer and can reveal problems with the user’s printer environment, the host configuration, the communications channel that is used, and sometimes the printer hardware itself.
rw
This
variable should be specified if the printer is able to send data back
to the host through the specified device file. The
rw
variable tells lpd that the
device should be opened for both reading and writing. This can be
useful for serial or SCSI PostScript printers, for example, because
they may return fairly useful error messages to
lpd, which stores them in the error log.
mx
Specifies the maximum size of a print job
in the spool. A value of zero sets no limit (the default,
mx#0
), and any other value sets the maximum file
size in blocks. Most of the time you don’t want to
set a limit, but you could, for example, set a value slightly smaller
than the expected minimum space available on a disk.
if
Specifies an input filter to use. If
you do not specify an input (if
) or output
(of
) filter, the system uses the default
/usr/sbin/lpf
filter. For some MS-DOS-style
character printers, this is sufficient. Other useful filters are
provided in the formatting utilities, and there are some flexible
“magic filter” packages that will
determine (usually correctly) the filtering to apply from the content
of the data file passed to it. See Section 8.4.7 that follows.
of
Specifies an output filter to use.
When you assign the of
variable and
don’t assign the if
variable, the
system uses the filter once when the device is opened. All queued
jobs are then sent until the queue is exhausted (and
lpd removes the lock file from the spool
directory). This is not normally useful, but it could serve such
purposes as sending faxes to a fax modem for dialed connection over a
telephone line.
When you assign both the if
and
of
variables, the if
-specified
filter normally processes the file, but the
of
-specified filter prints a banner page before
the input filter is applied. Using both input and output filters
effectively on the same print queue is notoriously difficult.
br
Specifies the data-transfer rate
(baud rate) for a serial port. You must supply this
value if the printer is accessed via serial port. A pound sign
precedes a numeric value that expresses the data-transfer rate in
bits per second (not truly the baud rate, which is an effective rate
of flow as opposed to the maximum rate of flow). The specified rate
should not exceed any hardware limits. For example, if your serial
port is capable of a 57.6 Kbps rate and the printer can process 28.8
Kbps, the assigned rate should not exceed that lower limit (perhaps
br#19200
). Supported bps values are the usual
multiples for serial communications: 300, 600, 1200, 2400, 4800,
9600, and so on. A number of additional data conditioning values may
be set if you do assign a br
value, but most of
them aren’t useful for typical Linux installations.
The default behavior is probably acceptable for your printing
purposes, but if you intend to print via serial port, study the
br
, fc
, fs
,
xc
, and xs
variables in the
printcap manual page.
pl
Specifies the page length
as the number of lines using the default font characters for
character devices (and printers that can use a character mode). An
example is pl#66
for an 11-inch page at six lines
per inch. This value allows space for cropping and accommodates the
limits of some other devices, such as inkjet printers that cannot
print to the bottom of the sheet or the edge of the paper. Normally
used in conjunction with the pw
variable.
pw
Specifies
the width of the page supported, in
characters, using the default font characters for character devices.
pw
is set like the pl
variable;
for example, pw#85
for 10 characters per inch with
an 8.5-inch printable page width.
px
Specifies the number of pixels to use on the X axis for a bitmap image file sent to a raster device.
py
Specifies the number of pixels to use on the Y axis for a bitmap image file sent to a raster device.
sh
Suppresses printing of a header or banner page. In most cases, you should set this.
rp
Specifies the name of a
remote printer to use. This variable cannot be set if the
lp
variable is set for the same printer. The
printer handling is performed by the remote host assigned in the
rm
variable, which is required when
rp
is set. Usually, the only variables set along
with these are spooling and error recording. See the example that
follows.
rm
Specifies a remote host that controls
the remote printer to which you print. The specified host ID assigned
by rm
should be one that is known to the network
services as installed (set up in /etc/hosts
or
known through NIS, for example).
rs
Restricts access to local printers to those users with an account on the system.
rg
Specifies a restricted group that can use the
printer. For example, to reserve a defined printer for superuser,
enter rg=root
.
sf
Suppresses the formfeed sent to the printer by default at the end of a print file.
ff
Assigns the formfeed character or string the
device should use. The default is Ctrl-L (equivalent to
ff='f
'), which
is usual for most devices.
fo
Sends a formfeed character to the device before sending the file.
mc
Specifies the maximum number of copies you can
print. Values are the same as for the mx
variable;
usually you want to allow unlimited copies (mc#0
),
which is the default.
sc
Example 8-1 contains a sample printcap file that
shows off many of the variables discussed in the previous list. It
contains an entry for a remote printer; printing to the printer named
hp (also the default, as it is the first entry)
sends the documents to the host
spigot.berk.ora.com
, where they are printed on the
printer queue lp.
Example 8-1. Sample /etc/printcap file
# Fare well, sweet prints. hp|bat|west|spigot|berkeley|TI MicroLaser Turbo: :mx#0:rp=lp: :lp=:sd=/var/spool/lpd:rm=spigot.berk.ora.com: :lf=/var/log/lpd-errs: # To the print room kiwi|810|rint|Big Apple|Apple 810 via EtherTalk: :lp=/var/spool/lpd/kiwi:sh: :sd=/var/spool/lpd/kiwi:pl#72:pw#85:mx#0: :lf=/var/log/lpd-errs:if=/usr/local/cap/kiwi: # big bird--agapornis via shielded serial access samoa|S|PostScript|secure|QMS 1725 by serial adapter: :lp=dev/tty01:br#38400:rw:xc#0:xs#0400040:sh: :sd=/var/spool/lpd/samoa:pl#72:pw#85:mx#0:mc#0: :lf=/var/log/lpd-errs:if=/usr/local/cap/samoa: # agapornis via printer room subnet (standard access) moa|ps|QMS 1725 via Ethernet: :lp=/var/spool/lpd/moa/moa:rm=agapornis:rp=samoa: :sd=/var/spool/lpd/moa:mx#0:sh: :lf=/var/log/lpd-errs:if=/usr/local/cap/samoa:
Ghostscript is included in standard Linux packages; it is an essential utility in an X Window System environment and is useful even if you don’t run X. Ghostscript can provide graphics output to a standard VGA display even where no window manager is running and can also process and create PostScript-formatted files without a graphics display. You can examine what devices Ghostscript is configured to recognize and format for on your system by entering Ghostscript in interactive mode. If you enter:
$ gs
Ghostscript should load in interactive mode and await your instructions:
GS>
You can then query the devices that Ghostscript is configured to recognize, and Ghostscript will display them:
GS>devicenames ==
[/lips3 /ljet3d /djet500 /cdj970 /st800 /iwlo /x11alpha /la75plus /bjc800 /ljet2p /djet820c /cdj880 /lp8000 /appledmp /la70 /bj200 /stp /DJ9xxVIP /cdj670 /eps9high /vgalib /dl2100 /lp2563 /pjxl300 /DJ8xx /cdj500 /epson /x11mono /lex2050 /lj5gray /pjetxl /DJ6xx /cdjcolor /tek4696 /x11gray2 /lex5700 /ljetplus /paintjet /hpijs /uniprint /t4693d4 /x11cmyk4 /lxm5700m /ljet4 /djet500c /cdj1600 /stcolor /iwlq /x11cmyk /ln03 /lbp8 /ljet3 /deskjet /cdj890 /lq850 /iwhi /x11 /la75 /bjc600 /laserjet /AP21xx /cdj850 /epsonc /sxlcrt /la50 /bj10e /hpdj /DJ9xx /cdj550 /eps9mid /lvga256 /declj250 /cljet5 /pjxl /DJ6xxP /cdjmono /ap3250 /x11gray4 /lex3200 /lj5mono /pj /DJ630 /cdeskjet /t4693d8 /x11cmyk8 /lex7000 /lj4dith /dnj650c /chp2200 /hl7x0 /t4693d2 /x11cmyk2 /lj250 /jpeggray /png256 /mgrgray4 /tiffg4 /ppmraw /okiibm /cif /pnggray /mgrmono /tiffg3 /pnmraw /oki182 /nullpage /cgm8 /pcxcmyk /bitrgb /faxg4 /pgnmraw /necp6 /pxlmono /bmp16m /pcx256 /psrgb /faxg3 /pgmraw /jetp3852 /pswrite /bmp16 /pcxgray /psmono /dfaxhigh /pbmraw /ibmpro /pdfwrite /bmpmono /mgr8 /tifflzw /plan9bm /xes /ccr /miff24 /png16m /mgrgray8 /tiff12nc /pkm /r4081 /jpeg /png16 /mgrgray2 /tiffg32d /ppm /oki4w /cgm24 /pngmono /bitcmyk /tiffcrle /pnm /oce9050 /pxlcolor /cgmmono /pcx24b /bit /faxg32d /pgnm /m8510 /epswrite /bmp256 /pcx16 /psgray /dfaxlow /pgm /imagen /bbox /bmpamono /pcxmono /tiffpack /inferno /pbm /cp50 /omni /sgirgb /mgr4 /tiff24nc /pkmraw /sj48] GS>quit
$
If you are not using X, and Ghostscript fails to initialize when you
try to invoke it, complaining that it cannot open an X display, the
first device Ghostscript loaded in its build file was the X Window
System device; Ghostscript uses the first device as its default
device. You can work around this problem by specifying some other
device that Ghostscript will have installed — for example,
gs -sDEVICE=epson
. You can guard against the
problem in the future by setting a global
GS_DEVICE environment variable to some other
device on your system that can be opened by Ghostscript.
If you have such an unusual output device that the default Ghostscript installation does not support it, you need to rebuild Ghostscript to support the device, or else process your output files through a filter that converts it to a form usable by your output device. Ghostscript comes with makefiles and is easy to build if you follow the Ghostscript documentation that comes with the distribution.
The more graphics utilities, X window managers, games, and applications you use, the more likely you will need to reinstall Ghostscript to suit your requirements. Read the Ghostscript documentation before running the makefile that comes with the package. (This requires that you have gcc installed on your system.)
You can define the GSDIR environment variable to locate the path of the ghostscript command and set GS_LIB variables, if you need to build Ghostscript utilities and add them to your installation. For example:
export GSDIR=/usr/bin export GS_LIB=/usr/lib/ghostscript:/usr/local/lib/fonts:/usr/X11R6/fonts
Set the GS_LIB_DEFAULTS variable before you make a new build of Ghostscript; see the gs manual page.
The Ghostscript package also contains some PostScript programs that
provide useful print-support functions, including some sophisticated
printing capabilities we do not document here. The
gs_init.ps
file, in particular, affects the
general behavior of Ghostscript. Additional scripts (filters, shell
scripts, and so on) can be found in
/usr/lib/ghostscript
or
/usr/local/lib/ghostscript
. You may find it
useful to examine the ps2epsi.ps
utility, which
converts PostScript into encapsulated PostScript, and the
ps2ascii.ps
utility, which converts PostScript
files into plain text.
Every document passes through a filter
before going to the printer, thanks to the if
variable in the printcap file. A print filter can be found in a Linux
distribution, acquired from the printer’s vendor,
found on the Net, or even made yourself from scratch or by cobbling
together existing filters and shell utilities.
An input filter can also be used to restrict use of a printer to a
specific user or group, or to users with accounts on a particular
host. Typical if
-assigned filters are executable
shell scripts that process the text file, but they can be any program
that can take the input data stream and process it for output to a
printer.
It is increasingly common for commercial Linux distributions to build
a filter interactively. While you can usually improve on such a
filter, it can help to use one as a starting point. The Red Hat
distribution, for example, created the following shell-script filter
(named /var/spool/lpd/ljet4/filter
)[33] on
one of our systems from information provided to it in the printer
manager window and from default assumptions. The
/etc/printcap
file was modified to specify the
use of this filter, which proved to be perfectly functional on our
system:
#!/bin/sh DEVICE=ljet4 RESOLUTION=600x600 PAPERSIZE=letter SENDEOF= nenscript -TUS -ZB -p- | if [ "$DEVICE" = "PostScript" ]; then cat - else gs -q -sDEVICE=$DEVICE -r$RESOLUTION -sPAPERSIZE=$PAPERSIZE -dNOPAUSE -dSAFER -sOutputFile=- - fi if [ "$SENDEOF" != "" ]; then printf "" fi exit 0
There’s nothing exotic about this filter. First it
sets some variables that appear later as arguments in the Ghostscript
command. The script passes output through
nenscript and passes PostScript files to the
gs Ghostscript utility. (In this particular case,
the automatically generated filter will never invoke
gs because DEVICE never equals
“PostScript” in the
if
test.) If your printer doesn’t
eject the final pages of output, you can force it to by setting the
SENDEOF variable near the top of the file. For
example:
SENDEOF='f'
will cause a formfeed to be sent to the printer when it reaches the end of a file.
You might modify such a script and substitute a filter specifically
designed for a LaserJet 4 printer, such as the actual
ljet4
filter package, for example, and accommodate
printing of TEX DVI files
by filtering them through dvips and feeding them
to Ghostscript. There is an elementary discussion of how to create a
filter in the Linux Printing HOWTO.
If you use a character printer that expects a carriage return at the end of each line, it will be unhappy with Linux, which follows Unix fashion in terminating a line with a linefeed, but no carriage return. To force correct treatment of newlines on these printers, the filter has to insert the carriage return. You can do this by writing the processing into the filter, or, alternatively, by using a filter that already has the capability to insert the character.
Some printer vendors provide filters and utilities for their printers, especially where the usual solutions are likely to be inadequate to take advantage of the printer’s capabilities. For example, Hewlett-Packard provides a JetAdmin package with filters to use with its TCP/IP network-addressed LaserJet printers.
The default filter that comes with the BSD
print-management package is /usr/sbin/lpf
. This
filter is undocumented and probably best ignored, unless you wish to
retrieve the C source and trace through the program to learn its
capabilities. (You can find the full BSD source in
the lpr-secure package in the printing directory from ftp://ftp.ibiblio.org.)
Most of the print-filtering needs you have were long ago resolved, and there are filters out there to meet your needs. By running:
apropos filter
you can probably identify several print filters installed on your host.
Changing filters is simple. You need only change the
/etc/printcap
input filter specification
(if
) to specify the filter you want, and then kill
and restart lpd, which you can do using the
lpc utility. Enter (as root
):
lpc restart all
The lpc utility reports any lpd processes it kills, then restarts lpd. If files are in a print spool waiting to print, lpd also reports that an lpd daemon for that printer has been started. The lpc printer control utility is described later in this chapter, in Section 8.4.12.
Before adopting a strange print filter, study the manual page for that filter and pass some test files through it. We have found that filters don’t always perform “as advertised” in their manual page; often the document is obsolete or the filter was compiled by someone using different configuration parameters than the document assumes. There is no substitute for testing all the things you expect the filter to do before adopting it. Two good filtering packages, nenscript, a newer version of the traditional Unix filter enscript, and APSfilter, are discussed in the next sections.
The
nenscript
filter is a typical modern filter for Linux. You should find it in
/usr/bin/nenscript
if it was provided in your
Linux distribution. Otherwise, it may be installed in
/usr/local/bin
. nenscript
controls headers, footers, rotation of text, and so on, and produces
PostScript output conforming to the Adobe Structuring Conventions
from plain ASCII input (by calling Ghostscript).
It sends output to the printer specified by either the
user’s NENSCRIPT environment
variable, if set, or by the user’s
PRINTER environment variable. If neither variable
is set, nenscript uses the default printer that
lpr wants to use.
If nenscript is called using the
-Z
option, it is supposed to pass PostScript files
through without altering them. nenscript examines
the input file, and if the first two characters in the input file are
%!
, nenscript suppresses
formatting. Because this output
“type-checking” is primitive, it is
easily fooled. Obviously if the first two characters happen to be
something other than %!
, perhaps because a
formfeed is the first character, for example, the file will not be
recognized as PostScript even if it is. This can easily happen if
some filter processing takes place before the file passes through to
nenscript. Of course, a file can also have
%!
as the first characters and not be PostScript
(or could be nonconforming PostScript) and therefore may not be
handled properly if passed to a PostScript printer. There are smarter
filters for this type of checking, including Magic-Filter or
APSfilter, but nenscript may easily meet your
needs, especially if you print only to a PostScript printer.
If you use the
nenscript filter for a PostScript printer on your
system, therefore, you could specify the -Z
option
in the NENSCRIPT environment variable for all user
shells by default, in order to pass through the PostScript received
by the filter.
A shell script provided in the nenscript package invokes nenscript configured to behave as though it were another (similar) traditional Unix filter, pstext.
To use nenscript to filter your print files, make sure nenscript is installed in an appropriate path, and then set the printers for which you want nenscript to filter to point to a filter that invokes the nenscript filter. You may find that the printcap entry can point directly to the nenscript filter if you set a systemwide default NENSCRIPT variable to control its options, or you can create a simple processing filter that calls nenscript, much like the sample configuration file shown earlier.
The most versatile filters are the so-called “magic” filters. A magic filter examines the contents of a file passed to it, and filters the output for printing based on what it learns from the format of the information. If it sees the file is DVI routed to a PostScript printer, for instance, it will apply another filter (perhaps dvips) to convert the data into PostScript for printing. This is very convenient, but on occasion, the filter can make a mistake. If that happens, the user can resubmit the file with command-line options that specify which filtering to perform, or the user can preprocess the file by piping it through the needed filtering before passing it to lpr for routine print processing. There are some good magic filter packages, including APSfilter (which we have chosen to describe here), Magic-Filter, and the gslp.ps filter provided with complete Ghostscript packages.
Some Linux distributions, regrettably, omit
Ghostscript’s supplemental utilities or documents,
but you can always retrieve a complete Ghostscript distribution via
FTP from the GNU archive site
(ftp://ftp.gnu.org/gnu/ ) or one
of its mirrors. You can get the APSfilter and Magic-Filter packages
from the ftp://ftp.ibiblio.org
FTP site in the
/pub/Linux/system/printing
directory. The
Ghostscript filter, gslp.ps, is written in the
PostScript language and can be used only with Ghostscript or another
interpreter compatible with Adobe PostScript.
The
APSfilter package for Linux is a port of a package developed for
FreeBSD. For that reason, you should take a few precautions in order
to ensure that things configure properly when you install the
APSfilter package. On a Linux host, it is probably best to install
the APSfilter package in /usr/lib/apsfilter
. The
package comes from ftp://ftp.ibiblio.org as a
gzipped, tarred file. To unpack the package, put
it in the /usr/lib
directory and enter:
tar xvfz apsfilter*.tar.gz
Now the APSfilter package unpacks within subdirectories of the
apsfilter
directory.
Change to the apsfilter
directory. Before you
run the SETUP command, make sure you have all the
filters you might want to use with APSfilter installed and
configured. The /usr/lib/apsfilter/FAQ
file
tells you some of the more important and useful packages.
Before you run the installation, read the
INSTALL
document to make sure there
aren’t any surprises. Then run
./SETUP
. It tests for the presence and location
of graphics utilities and other filters APSfilter uses to convert
files into a form printable on your printer.
The SETUP
script lets you know if the filter
installed correctly. You can run it again if you wish to install more
than one printer or more than one mode for a single printer. For
example, if you install a DeskJet 540 printer, you probably will want
to use the dj500 definition for the black cartridge and the dj550c
definition for the CMYK color cartridge. APSfilter
uses very long directory names for its spool directories. If you
don’t like that, you can rename the spool
directories and change the corresponding directory fields in the
corresponding /etc/printcap entry. Be sure not to
shorten the name of the filter used; that path is critical. We
don’t recommend you make things pretty until you are
satisfied that things are working.
Before you try your new setup, you need to restart the print daemon:
/usr/sbin/lpc restart all
APSfilter sets systemwide variables for printer definitions in the
/etc/apsfilterrc
file; reading this file can be
informative. Common print problems are typically caused by file
ownership or permission problems; we show you the proper settings in
the upcoming section Section 8.4.10.2.
Then, read the FAQ
and
TROUBLESHOOTING
files in the
/usr/lib/apsfilter
directory.
If your APSfilter installation didn’t work, you can
always return to the configuration you had before you installed it by
copying back to /etc/printcap
the
/etc/printcap.orig
file that APSfilter saved for
you.
APSfilter names its printers sequentially, from
lp1
up. Don’t be confused; that
has nothing to do with the actual physical device assigned to the
printer. Again, you can change those names.
APSfilter allows you to loosen restrictions so that individual users
can set up their own .apsfilterr
file in their
home directories. The default is to not allow it, which is a bit more
secure.
The latest version of Magic-Filter (at the time of this writing, Version 1.2) is remarkably easy to install and makes a clean alternative to APSfilter. However, the installation doesn’t do any hand-holding. Though there is a useful manual page, there isn’t much information to help you set up the alternate processing that the Magic-Filter utility can do for most printing devices. In particular, if you have a versatile printer that outputs in multiple modes (PostScript, PCL5, text, and so on), you may find it worth your while to install and use this package.
The print-management system requires you to create directories that match the printcap printer names in order to spool files for printing. It also requires you to create other files for controlling the print process itself. You must set up directories and files with the correct ownership and privileges, and the printer utilities themselves also need correct permissions.
Your Linux installation created a
standard spool directory. Ideally, this is on a fast-access disk
drive. The basic spool directory (/var/spool
)
is normally used for managing mail, news, and UUCP
communications as well as for holding printer files. We recommend you
follow this practice, which is a Linux standard. Some utilities or
filters you get may expect to find
/usr/spool/lpd
as the printer spool path. You
will have to make corrections if you find this condition. You can, of
course, create /usr/spool
and link it to
/var/spool
, but that is a good idea only if
/usr
and /var
are on the
same disk drive.
You must create your own printer spool
directories. The /var/spool/lpd
directory is the
standard path containing each printer subdirectory. Each printer
subdirectory name must be used as a printer name in the first field
in a corresponding /etc/printcap
entry. For
example, /var/spool/lpd/moa
is appropriate for a
printer with moa
in a name field of the printcap
entry. In turn, the /etc/printcap
entry for this
printer should have an sd
variable set to point to
the spooling directory (sd=/var/spool/lpd/moa
, for
example).
You shouldn’t use lp
as the
actual spool directory name unless you never expect to have more than
one printer on your system or network because lp
is the default printer. (If your default printer is somewhere else on
the network, your files will still get spooled to
/var/spool/lpd/lp
first, before your
lpd forwards them to the print daemon on the
remote host to print.) You may have a printer-management utility that
automatically creates an lp
spool directory, but
you can always edit the printcap file to point to any directory you
wish.
The spool directory name should be the first name listed in the
associated /etc/printcap
entry for the printer
to make identification easy. The printcap entry will then be
associated with the names under which the lpq and
lpc utilities report print queue status.
The most common problem in
establishing print services is with file and directory permissions.
Table 8-1 lists the important files, directories,
and utilities that comprise BSD print management
on Linux. Installed locations may vary according to your Linux
distribution. The ownerships and permissions given in the following
table are recommended for the files and directories of the printing
system. (Additional filters and nonstandard spool paths may be
specified in /etc/printcap
.) Different
permissions may still work, but if you have permissions problems,
this is where you can straighten them out. An asterisk in the first
column of the table indicates that many files can exist with the
names of different printers. Note that different distributions may
have slightly different settings here; some distributions even have
different “security modes,” which
you can select depending on your security requirements and which have
an effect on the permissions used.
Table 8-1. BSD’s files, directories, and utilities for printing
Directory or file |
Permissions |
Owner/group |
Description |
---|---|---|---|
|
|
|
Typical serial port printing device |
|
|
|
Typical parallel port device (not bidirectional) |
|
|
|
Controls print-spooling services |
|
|
|
Receives print file, assigns processing data, and spools both |
|
|
|
Reports on spooled files with user and print queue data |
|
|
|
Removes print jobs from spool |
|
|
|
Tests print services to improve them |
|
|
|
Outputs an ASCII file for printer and display testing |
|
|
|
Daemon that manages printing using printcap data and data passed by lpr |
|
|
|
Primitive BSD text print filter |
|
|
|
BSD utility that reports on printer activity and usage by user ID |
|
|
|
Basic system location for temporary files |
|
|
|
Standard path for the print-spooling system |
|
|
|
Spooling subdirectories for each defined printer |
|
|
|
Filters created by Red Hat printer-management utility for each print spool |
|
|
|
lpd queue control lock |
|
|
|
Sequence file that lpd uses to order spooled files |
|
|
|
lpd writes this lock file to prevent sending next file until printer is ready |
|
|
|
lpd stores latest printer status report here |
|
|
|
Accounting record file, from which pac extracts and formats print data[a] |
|
|
|
Standard BSD log file for |
[a] This file remains empty if system accounting is not installed, unless you configure Ghostscript to perform its limited reporting there and make the file writable by all. |
The usual Linux printer-management utilities set the print files with
root
ownership and lp
group
privilege. Traditionally, BSD distributions have
used root
ownership and daemon
group privilege. You can use either group privilege, but if you use
both daemon
and lp
privileges
with different utilities and files, you will have problems. Be
particularly careful about this if you add utilities from other
packages to your services.
Let’s say you (as root
) need to
create the printer-spooling directory,
/var/spool/lpd
. You execute the command:
mkdir /var/spool/lpd
Assuming your /var/spool
was created with the
usual permissions, the new lpd
directory has
permissions of drwxrwxr-x
, which is too
permissive. If you enter the command:
chmod 755 /var/spool/lpd
the permissions are changed to drwxr-xr-x
. This is
close, but not what you want. You need to set the setuid bit, so
lp
can setuid root
:
chmod +s /var/spool/lpd
This results in drwsr-sr-x
, which is what you
want. However, the group should be lp
, not
root
, so you need to fix that:
chgrp lp /var/spool/lpd
Create the spool directories needed for each printer as
subdirectories of the /var/spool/lpd
directory
in the same way, and then use touch to create a
.seq
file in each
print directory:
touch .seq
The
lpd
daemon consults /etc/printcap
and then sends
files to printers by directing them to a device file in the
/dev
directory. Most printers on Linux boxes are
serial (usually addressed through devices named
/dev/ttys0
, /dev/ttys1
, and
so on, or /dev/ttyS0
,
/dev/ttyS1
, and so on) or parallel
(/dev/lp0
, /dev/lp1
, or
/dev/lp2
, depending on the physical addresses
the ports use). The port assignments are described in
Section 8.4.14, later in this
chapter. A common mistake when configuring print services is to use
the wrong port.
You can link a
virtual device — /dev/fax
, for
example — to an actual device you can use by creating a symbolic
link. For example:
ln -s /dev/ttys1 /dev/fax
This allows users to set up scripts and filters that address
/dev/fax
, which is much easier to remember than
/dev/ttys1
. Also, you can move the physical
device (a fax modem, for example) without breaking user setup simply
by removing /dev/fax
and then creating it again
with a link to the new device.
The BSD printer daemon is notorious for dying or just becoming inert. To be fair, this seems to be less common than it was some years ago, but it still happens. When it does, just kill the old daemon and start a new one. If lpd isn’t fairly reliable, though, there is a cause somewhere. Something could be wrong with a user’s environment, with the specified command-line options used with lpr, or with a faulty filter that sends setup data to the printer in a form the printer doesn’t like. However, you have every reason to expect to have a “pretty good” printing package installation. If you are having problems, check out Section 8.4.14, later in this chapter.
OK, let’s see if you have a working print system. After making all these changes, you can be sure that lpd doesn’t know what is going on. So run the ps command and find the ID of the lpd process. Then enter:
kill -9 processid
to kill the process you specified.[34] You should now have no print daemon running. Just enter /usr/sbin/lpd to start the print daemon.
Now, while watching the activity LEDs on your printer front panel (if there are any), send a file to the printer (still acting with superuser privilege):
lptest | lpr
The
lptest
ASCII barber pole should
begin printing to your default printer, as configured in your
/etc/printcap
file. If it
doesn’t, you have a configuration problem that has
nothing to do with privileges.
Did the printer show any activity? Does your default printer have a
spool directory? Does the directory have a .seq
file? Check /var/log/lpd-errs
and see if
anything was stored in it. Use the lpc command and
get a report on the status of the print daemon and the print spool.
If everything else looks good, make sure the printer is using the port you expected by sending a file directly to the port. For example:
# lptest > /dev/lp1
Or, to test for a serial printer:
# lptest > /dev/ttys1
and so on. If none of these worked, reexamine your
/etc/printcap
file. Is your entry properly
formed? Are there no blank spaces or tabs following the continuation
character () on your entry line? Is the printer queue correctly
specified? Does the name lp
appear as one of the
printer names of the name field? Is the first name in the name field
the same name as the spool directory it uses?
Let’s assume you got through this first little test
unscathed, and you now have several pages of lovely barber-pole
printout in your printer tray. Next comes the real challenge. Can you
print as a regular user? Log in (or run su) to
become a normal system user. Now, try the same experiment. If it
works, congratulations, you’ve got a printer! If it
doesn’t, you have a problem, but it is probably a
file or directory ownership or permissions problem. You know what you
have to do about that. Become root
again, look at
the manual pages for chgrp,
chmod, and chown, and go down
the list of files and directories to find your problem and fix it.
Repeat until Joe User can print.
The lpc utility is provided to manage printer queues and requires root privilege to perform most of its functions. lpc reports on all print queues and their attending lpd daemons. You can also specify reports on a specific printer or printing system user. To get a status report on all printers and users, type:
$ lpc status
ibis:
queuing is enabled
printing is enabled
no entries
no daemon present
crow:
queuing is enabled
printing is enabled
1 entry in spool area
crow is ready and printing
ada:
queuing is disabled
printing is disabled
no entries
no daemon present
You can enable queuing within lpc through its enable command and disable queing using its disable command. The disable command works by setting a group execute permission on the lock file in the print spool directory.
You can enable printing in lpc using its start command and disable it using its stop command. Jobs held in a print queue when a printer is stopped will remain there until printing is restarted. The stop command functions by setting a lock file in the printer spool directory and killing the print daemon for that queue, but it allows the currently printing job to complete. The abort command works like stop, but also halts any printing job immediately. (Because the job did not complete, lpr retains it and starts over again when the queue is restarted.)
The down command functions as though both a disable and a stop command were issued, and the up command does the reverse, issuing enable and start commands.
You could also limit the display to one printer:
$ lpc status crow
crow:
queuing is enabled
printing is enabled
1 entry in spool area
crow is ready and printing
The status-reporting feature is useful for anyone, and lpc allows all users to use it.
The real work for lpc usually involves solving a printing crisis. Sometimes a print daemon dies, and printing jobs back up. Sometimes a printer runs out of ink or paper, or even fails. Jobs in the print spools have to be suspended or moved to another spool where they can be printed. Someone may simply have an urgent printing task that needs to be moved to the top of the queue.
The lpc command is a classic Unix command: tight-lipped and forbidding. When you simply enter the lpc command, all you get back is a prompt:
lpc>
The command is interactive and waiting for your instructions. You can
get help by entering help
or a question mark at
the lpc prompt. lpc responds
and gives you a new prompt. For example, entering a question mark
displays:
#lpc
lpc>?
Commands may be abbreviated. Commands are: abort enable disable help restart status topq ? clean exit down quit start stop up lpc>
You can get additional help by asking for help about a specific command. For example, to learn more about restarting a stalled print queue, type:
lpc> help restart
restart kill (if possible) and restart a spooling daemon
lpc>
The lpc help message does not offer online help about the secondary arguments you can specify in some places. The manual page will offer you some guidance. Most of the commands accept all or a print spool name as a secondary argument.
The lpc topq command recognizes a print spool name
as the first argument and printer job numbers or user IDs as the
following arguments. The arguments are used to reorder the print
queue. For example, to move job 237 to the top of the
ada
print queue, followed by all jobs owned by
bckeller
in the queue, enter:
lpc> topq ada 237 bckeller
The lpd daemon will start job 237 as soon as the
current job is finished and will put any files in the queue owned by
bckeller
before the rest of the print spool. If
you were very impatient, you could use the abort
and clean commands to kill and purge the currently
printing job, then use topq to put the job you
want at the top of the queue, before using restart
to create a new lpd and restart the queue.
When you use the stop command to stop a print spool (or all print spools) you can broadcast a message to all system users at the same time. For example:
lpc> stop ada "Printer Ada taken down to replace toner cartridge."
If you do major surgery on the print spools — stopping queues and moving files around — it is wise to use lpc’s clean command. This minimizes the risk that some loose end will cause an lpd daemon to stall:
lpc> clean
Then get a new status report and restart or start all stopped print spools before exiting. There is a difference between aborting a process, stopping a process, and bringing a print queue down. If you bring a print queue down (lpc down ada, for example) you will find you cannot get lpd to serve the print spool again until you restore services with an lpc up ada command. Similarly, if you stop a queue, you have to start or restart it.
Follow up after you clear print spool problems using lpc. Further status reports will let you know promptly whether the problems were actually solved.
You should not wait for disaster to become familiar with lpc commands because printing jobs can pass through a Linux spool very fast, especially when a printer has lots of memory to buffer jobs sent to it. Study the manual page and work with lpc enough to be comfortable with the control it gives you over print spools and lpd daemons.
You can abbreviate subcommands unless it makes them ambiguous. For
instance, in the following command, h
stands for
help :
lpc> h topq
To exit from lpc, enter the command:
lpc> quit
or:
lpc> exit
For performance improvement, you can first try to maximize the physical tuning of the system. You should try to determine the maximum data flow rates you can sustain to the printers you install. Don’t specify a faster rate of communication than can be supported unless your printer is going to return flow control signals to the print daemon. That is, you must have bidirectional communications (and the printer must return the necessary signals) or else you must limit your transmission speeds so that data doesn’t get lost en route to the printer. You may have to experiment with this to wring the best possible performance from printers limited by restricted bandwidth.
Old PC serial and parallel cards just don’t have the throughput available with later cards. Newer serial cards have faster I/O processors. Newer parallel ports are typically faster and meet the Enhanced Parallel Port (EPP) standard to support bidirectional communications, which may allow lpd to control data flow to the printer better. A significant performance improvement may be only a few dollars away.
If your printer is just plain slow and cannot buffer print jobs, there isn’t much to be gained from optimizing the data-transfer rate, of course, but it may still be useful for you to use interrupt-driven flow control made possible by bidirectional communications instead of port polling, if your hardware permits, as that will decrease the system load.
You can try out various printer optimizations using the tunelp utility. Read the manual page carefully before attempting this. If a tuning procedure fails, you may need to turn the printer off and back on to reset it. Also, don’t forget to use lpc to restart the lpd daemon after each change to the configuration. Back up your working setup before monkeying around with tunelp.
An excellent first use for tunelp is to cause a
print job to abort on receiving a printer error and to notify you.
(The default is not to abort.) Setting this up can shorten the test
cycle. To cause abort on printer error, enter as
root
:
tunelp -aon
If you use a parallel port printer and your parallel port supports interrupt-driven printing, you can use tunelp to accelerate printer access:
tunelp /dev/lp1 -i7
This example switches the port controlled by interrupt 7 to use interrupt-driven printing. If an attempt to print after you made this change fails, you should reset the port and switch back to noninterrupt-driven polling:
tunelp /dev/lp1 -r -i0
If you don’t know the interrupt this device uses, you can query with tunelp -q on, and the IRQ setting will be displayed.
You can probably speed up printing a bit by reducing the pause the driver takes when it cannot send a character to the printer after a certain number of tries. For example, a fast laser printer might happily accommodate very brief pauses and not require many attempts to transmit. To try sending a character 10 times before pausing (the default is 250 attempts) and set the pause to .01, type:
tunelp /dev/lp1 -c10 -t1
The -t
takes a numeric value that represents a
multiple of .01 second. The default pause is .1 second.
Note that the optimal transfer rate for plain-text files is likely to be less efficient for graphics files, which are generally processed more slowly.
When you finish tuning your printing system, you may want to reset the printer abort flag to prevent the process from aborting on receipt of printer error:
tunelp -aoff
The tunelp utility will continue to be developed in subsequent releases of Linux. Check the manual page to see the capabilities of your release.
When you have a printer problem, first
resort to lpc to generate a status report. The
print daemons should be alive and well, and no error should be
returned. Restart the daemons if they have stopped. You can also
check the contents of the
/var/spool/lpd/
printername
/status
file and see if an error message from the printer is stored there.
Check the /var/log/lpd-errs
file for any errors
reported by lpd. If you are using Ghostscript and
its reporting features are active, use /sbin/pac
on Ghostscript’s log file to get a report that may
reveal errors Ghostscript generated. (As long as Linux system
accounting isn’t available, you might as well use
/var/log/lp-acct
to store these reports.
You’ll have to make the file writable by all to do
this.)
Look at that lpc status report again. Do files get
to the print spool? Do they leave the spool? Are the necessary
supporting files for lpd present
(.seq
, lock
, and so on)? If
lpc status reported a printer named
" : " there is a malformed
/etc/printcap
line; the last character on a
continuation line must be the backslash, not a space or tab.
Sometimes the
/etc/printcap
file is set up incorrectly, and it
makes lpd misroute a file. To test for that
condition, prepare a file for print but save it to a file instead of
spooling it to the printer. Examine the file. Is it in the form you
expect? Try a couple of sanity checks:
If as root
you send the file directly to the
device (for example, cat filename.ps > /dev/lp1
), does it print? If so, it means the problem lies
in your software configuration, not in the hardware.
Can you view your PostScript file using Ghostview? If so, you know that the format of the file is correct but the printer or filter is not interpreting it properly.
If you are testing a text file, try preparing it and routing it to a display, passing it through a utility such as less, and examine the result. A custom filter can also misroute a file.
Sometimes it is difficult to figure out where a printing problem originates. Printer configuration problems can be masked (or introduced) by having defaults overridden, for example. You may have to start by looking at an individual user’s printing habits and then work forward. Individual users can set environment variables in their shell startup files to specify the printer they want to use as a default, and the behavior of formatters and print filters. Default system values are often overridden by environment variables, and they in turn are overridden by option arguments passed to lpr on the command line or by another utility.
When a print job terminates abnormally, it may be necessary to clear
the lock file for the spool before lpd will send
another file to print from that spool
(/var/spool/lpd/
printername
/lock
).
The lpd daemon creates the lock file and changes
it on completion. You can use lpc to stop the
print daemon and then clean up the spool before starting it again.
Some problems derive from the data-transfer process. A printer may drop characters or be unable to keep up with the data flow you are attempting to provide, especially if the printer is old and slow or if the cable is unusually long. One possible symptom of data-transfer problems is when the printer can handle plain text readily, but pauses and thrashes when trying to print graphics files. If you suspect some problem of this nature, try increasing the pause the system takes before attempting to resend data and slowing the wait loop. The tunelp utility lets you control this conveniently:
tunelp -t200 -w5
This command tells lpd to pause 2 seconds between
attempts. The -w
option sets the number of loops for
the busy loop counter to read between strobe signals. Normally
-w
is set to 0. For more information on
tunelp, see Section 8.4.13 earlier in this chapter.
If
lpd never seems to run on your system, perhaps it
isn’t started up when the system boots. If this is
the case, append a /etc/lpd line to the end of
your /etc/rc.d/rc.local
file. Most Linux
distributions start lpd these days as part of the
default installation.
Some problems may never occur unless you use another package that
presents conflicts by attempting to address the same devices. For
example, UUCP utilities address a serial port
using a /dev/ttyS*
device driver. However,
UUCP is a daemon with greater privileges than
lp
, and (although it shouldn’t)
it can leave the device set with a privilege level to which
lpd cannot write.
The
Linux distribution of the BSD print package is
usually installed with lp
group permissions. On
traditional BSD print-management installations,
lpd is owned by daemon
and has
daemon
group privileges. (There’s
no special lp
group to support printing.) If you
think there are subtle problems relating to device access collisions
by processes owned by different daemons, you can change all print
utilities, group privileges to daemon
and, of
course, change directory and file-access privileges as well. That
would restore the traditional BSD configuration. A
better solution would be to find the problem devices and change their
ownership to lp
, because UUCP
will still be able to use devices lp
owns. Be
aware that a serial port address can be reached by a number of
virtual devices linked to the actual device; you have to correctly
set the ownership of the real device.
Occasionally, a user believes his print job is going to the
“wrong” printer. This is usually an
environment variable problem. Double-check your
/etc/printcap
, but also check the
user’s environment variables. For example, a user
may have a GS_DEVICE variable set so that
Ghostscript uses that printer as the default printer. If Ghostscript
processing precedes nenscript processing, for
example, the Ghostscript printer assignment could be passed to
nenscript, overriding a
NENSCRIPT or PRINTER device
specification. This can also cause strange results if one parameter
is overridden while others stay as before so that, for example, a
filter performs some special page layout for one printer, but the
file goes to another.
Older PostScript printers may simply ignore ASCII files sent to them. If a user complains about disappearing output, maybe the file isn’t getting passed through nenscript for PostScript encapsulation, or (very rarely) maybe nenscript was fooled into thinking it is already PostScript.
A multimode printer that knows when to switch modes (between PCL and plain text, for example) may still fail to eject the page and start the next file on the new page when one file of the same type is queued immediately following another of the same type. If this occurs, you can force the filter to add a formfeed at the end of each document (see the sample filter in Section 8.4.7) at the cost of sometimes printing unnecessary blank pages.
Parallel port
printer addressing can be confusing. On an XT bus system, the first
parallel port is addressed as /dev/lp0
at
0x3bc
, referring to an address in your
computer’s I/O memory. On the usual ISA bus system,
the first parallel port device is /dev/lp1
at
0x378
, which is the second parallel port on an XT
system (still the /dev/lp1
device). The usual
second parallel port on an ISA bus system is
/dev/lp2
, as you would expect, at
0x278
. However, there are some unusual
configurations out there, such as systems with three parallel ports
(if installed correctly these will be addressed as
/dev/lp0
, /dev/lp1
, and
/dev/lp2
). IRQ assignments may also be unusual
and present a problem if you are trying to set up interrupt-driven
printing.
If all else fails, review the initial installation procedure. Make
sure the hardware is actually connected and functional by booting
another operating system if possible, testing devices as
root
user,
and so on.
CUPS, the Common Unix Printer System, is the new kid on the block when it comes to printing subsystems, and probably the one that is going to take over the Linux printing world completely because of its functionality. It supports many features in modern printers like downloadable fonts, color printing, network printer browsing, printer description files (PPD files), etc. Some distributions like Caldera already use CUPS, but at the time of this writing, Red Hat, SuSE, and Debian don’t (they still have it on their CDs, though). This does not mean that CUPS does not work on these systems, however. You can always install CUPS yourself.
Currently, CUPS contains printer drivers only for HP and Epson printers, but because most available printers are compatible with these, this is rarely a problem. The authors of CUPS also sell a commercial package that contains drivers for most printers, even the very esoteric ones, and some free third-party drivers are available as well.
If you want to download and install CUPS on your system, you can find both the software and lots of documentation at http://www.cups.org.
[31] In this chapter, we use ljet4 in several examples. Be aware that the HP LaserJet 4 model is available in several versions. Some LaserJet 4 models are PCL5 printers only, and others use PostScript. Unless you are aware that different types exist, you can find it very frustrating trying to debug a printer filter that is expecting, for example, PostScript, when Ghostscript is passing it PCL5 input.
[32] A
special case arises where the printer to be addressed is a true
networked printer (that is, it has its own IP address). In that
instance, the lp
variable assigns the name of a
dummy file that is used for setting a temporary lock on the file when
the networked printer is in use. The documentation for the networked
printer should describe the procedure for setting up and managing
print services to access it.
[33] Putting a filter in a printer’s spool
directory is a convenient technique for a printer-management program
to use when setting up your printer system. You may prefer to keep
all your print filters and graphics conversion filters in the same
directory (following the Unix tradition), such as
/usr/sbin
or
/var/spool/lpd/filters
. Of course, in that case,
each filter you create must be uniquely named.
[34] You may prefer to use lpc to perform this task. Also, if your root desktop has a printer-manager tool, you can probably click the lpd button to kill and restart the print daemon.