Creating Smart Print Queues

This article will help you understand print filters and how to create and install your own personalized filters.

In the December 1999 issue of Linux Journal, Michael Hughes introduced a few basics for setting up printing on your Linux computer. This article will go into greater detail on getting your print installation to work for a variety of printers. The biggest problem is that most applications, especially the graphics-based ones that run under X, print using the PostScript printer language, and most of us do not have a PostScript printer.

I'm basically lazy—I want my computer to make things easier for me. What's a computer for if not to automate tasks and simplify my life? It didn't take me long to become frustrated with having to deal with printing plaintext files vs. PostScript files from Netscape or other applications. So I wrote a printer filter to take care of these decisions for me, and you can, too. The BSD print system that comes with your Linux distribution has the capability to pipe print files through a filter, which can be any executable program. Since the filters usually have a simple job to do, they are normally written as a bash or Perl script.

The printer daemon sends the file to be printed to the standard input of the filter, and the filter modifies the file as needed. The filter can then write the modified file to standard output, which the print system sends on to the printer. Your filter can make any kind of modification to the file, and you don't even have to write the modified file to standard output, as we shall see later.

The BSD Printing System

Specific printer capabilities are defined in the /etc/printcap file, which is normally created when Linux is installed. Each printer or printer configuration that you use must be defined in this file. The printers can be attached locally, attached to another computer on your network or to network printers. You can set up multiple configurations for the same printer to handle different file types, and the print system can send output to other devices or save it to a file. Virtually anything that can accept a computer file is fair game for the output device.

Each printer configuration in your printcap file defines a print queue. You print something from the command line with the lpr command or through a print button or menu in various applications. UNIX and Linux applications use the lpr command to make the actual print request by using the line-printer daemon, lpd, which spawns a copy of itself to handle each print request. lpd is the main program and runs continuously in the background to handle all requests from lpr, lpq (for querying print job and printer status) and lprm (to remove jobs from the print queue).

Listing 1 is a typical printcap entry that defines a printer attached to your parallel printer port. Comments in the file start with a hash (#) character. Each entry defines a printer queue and consists of a series of fields delimited with the colon (:) character. The first field of the entry supplies one or more names for the print queue, separated by the pipe (|) character. You should include “lp” as the name of one of your print queues, since it will be the default queue when you print without specifying a queue. The last sub-field of this first field should contain a description of this print queue and may be displayed by some print management software. I gave this queue an alias of “text” so that the print command could be either lpr filename or lpr -Ptext filename.

Listing 1

For readability, I usually place each field on a separate line, with the backslash escape character at the end of each line except the last one. But you don't have to. It is traditional to place extra colons at the beginning and end of each field when they are given on separate lines, as in this example, with all continuation lines indented by a tab. The extra colons are ignored by lpd when it reads this file.

The fields after the first one tell lpd the properties for this queue. Each of these subsequent fields begins with a keyword, an equal (=) sign for text values or a hash (#) sign for numeric values, and the value for the field. Some keywords are switches and do not have values. In Listing 1, the second keyword, “lp”, defines the device to which the output will be sent. In this case, /dev/lp should be a symbolic link to /dev/lp0 or /dev/lp1 for your printer port. Don't confuse this field name with the default print queue name in the first field. The order of the fields does not matter, except for the first field that names the queue.

The lf keyword specifies the full path to the log file, where errors from the print daemon concerning this queue can be recorded. When something goes wrong, the contents of this file may give you a clue to the problem, although many print-related error messages will be sent to your system log, /var/log/messages. The sb boolean keyword tells lpd to print a short one-line “banner”. Finally, sd, the spool directory keyword, lets you specify the directory path in which to place a temporary copy of the file being printed. You must specify a spool directory for each print queue. Other controlling information for the queue and each print job is also placed in this directory, so each queue in your printcap file needs to have its own spool directory.

These are the most common of the many available parameters. The printcap man page lists all the parameters that can be used to configure your print queue entries.