Published on (
 See this if you're having trouble printing code examples

Unix Printing Basics

by Dru Lavigne, author of BSD Hacks

Somewhere there must be a theory stating that the amount of configuration knowledge required is directly proportional to the need for using said configured service. This is certainly often the case with printing.

True, the configuration interfaces have steadily improved in the past few years. However, administrators still need a fair bit of knowledge to understand which particular software bits they need to make the most of the features of a particular printer. Additionally, the vast array of software available often confuses new users. As an example, there are more than 300 print applications available in the ports collection. Where exactly does one start?

In the next few articles, I'll explain some basic printing terminology. I'll also discuss some of the available applications for each printing component and cover some of the pros and cons of each application. Throughout, I'll demonstrate applying this knowledge to an example printer.

If you haven't already, take some time and skim through the printing section of the FreeBSD handbook. While you may not understand everything, that section will still give you a good overview of the printing process on a Unix system. If you're new to hardware, you'll also find the "hardware setup" and "troubleshooting" subsections very helpful if you're having problems physically setting up your printer.

The Spooler

Let's start with the various components available when setting up your printer. Regardless of the operating system, the main printing software component will always be the spooler. This piece of software receives your print request, known as a print job, and places it in a print queue. As the name suggests, a queue is a lineup of jobs waiting for their turn to receive access to the hardware printer. The spooler monitors both the queue and the printer. As the printer becomes available, the spooler sends the next job for printing. Once the print successfully completes, the spooler removes the job from the queue and moves on to the next job.

Your FreeBSD system comes with lpd, the original Unix spooler. Another popular spooler, LPRng (LPR new generation), is available in the ports collection.

Both spoolers use the printer capability database located in /etc/printcap for configuration. Did you notice that the bulk of the printing section of the handbook deals with the proper configuration of this file? That's for good reason; all printing components rely on the spooler, which calls them based on their appearance in the spooler configuration file. Depending upon your particular printer, it may be easier to create this file manually or use a printer configuration tool to create the necessary /etc/printcap entries. I'll discuss both methods shortly.


Technically, a configured spooler will allow you to access your printer. You'll often want additional components, though. After all, your printer isn't very useful if it can only print gobbledygook or unformatted text with all of the appeal of plain ASCII on a terminal. It's also rather disappointing if your particular printer model comes with a slew of features, none of which you can access.

One of the required components is usually Ghostscript, especially if your printer was created for the home market. Most Unix programs assume that your printer speaks the PostScript printing language found in PostScript (which usually means expensive) printers.

Ghostscript provides a collection of print drivers. A print driver provides the necessary translation between programs and the language spoken by your particular printer. It also includes the command set required to access the features provided by your printer. Additionally, a print driver often uses a PPD (PostScript Printer Description) file to understand the capabilities of a particular printer.

LinuxPrinting has an excellent article on the interaction of PostScript, Ghostscript, print drivers, and PPDs.

Magic Filters and Configuration Utilities

Another useful component is the magic, smart, or input filter. This software recognizes different print formats and sends a job first to a necessary conversion program. Such filters usually come with a configuration utility, allowing for a fairly easy setup. Example filters from the ports collection include:

Finally, your window manager may also provide a printer subsystem that includes a printer setup utility. For example, KDEPrint gives detailed instructions for using KDEPrint, and Gnome provides the Gnome Print Manager.

Researching Your Printer

OK, now that we're aware of the various pieces, where do we go from here? Let's start with a checklist:

Depending upon which ports you've installed on your system, you may or may not already have Ghostscript. To see if you do:

% gs -v
GNU Ghostscript 7.07 (2003-05-17)
Copyright (C) 2003 artofcode LLC, Benicia, CA. All rights reserved.

Note that the name of the Ghostscript executable is gs. If you receive similar output, you have Ghostscript. If for some reason you don't keep your ports up-to-date, double-check that your version of Ghostscript is the latest available from the ports collection. Since Ghostscript is a collection of drivers and the maintainers constantly add new drivers, you do want a recent version of Ghostscript.

If you instead receive an error message about a missing command, install Ghostscript:

# cd /usr/ports/print/ghostscript-gnu
# make install clean

During the install, you'll receive a menu asking which portions to install. If you want, deselect the drivers you don't need. If you're not sure, stick with the defaults.

Next, you need to research the availability of a print driver for your particular printer model. This will let you know if there is an available Unix print driver and provide clues regarding the best route for installing and configuring that driver. Start your search at the Un*x printer compatibility database.

As an example, I have an HP OfficeJet 4110. Fortunately for me, there is an entry in the database for this printer. Hopefully, your particular model will be here as well. (If you're in the market for a printer, check out Suggested Printers for Free Software Users for practical advice on choosing a printer).

Click on the hyperlink for your model to receive a detailed description of the features and quirks provided by the driver. Before proceeding, carefully read through the driver description to see if there's anything you need to know. I made note of the following:

Armed with this information, my next stop is the FreeBSD Ports search engine to see if there are any related FreeBSD ports. A search for hpijs and hpoj shows a port for each.

For now, I'll install the hpijs driver; once I've configured my printer, I'll experiment with hpoj and that black ink patch.

# cd /usr/ports/print/hpijs
# make install

Note: Always check the ports collection for your driver. The print drivers that come with Ghostscript are compiled into its binary. Sometimes you'll need an additional port as a Ghostscript add-on to access the printer's full feature set. In my case, hpijs is an add-on to the ijs driver compiled into Ghostscript. I don't need hpoj for printing per se, only for accessing the scanning features of my all-in-one printer.

Check Your Hardware

Once you have Ghostscript and any necessary drivers installed, double-check that your FreeBSD system sees your printer. The FreeBSD handbook has explicit instructions for testing a printer connected to a parallel or serial port. However, my printer uses a USB interface. Since USB is hot swappable, I can plug my printer into an available USB port without having to first shutdown the system. As soon as I make the connection, my console (Alt F1) shows this message:

ulpt0: Hewlett-Packard officejet 4100 series, rev 2.00/1.00, 
 addr 2, iclass 7/1
ulpt0: using bi-directional mode

Which is an encouraging sign.

Note: If your message instead shows ugen0 (the generic USB driver) message, you probably removed ulpt support from your kernel configuration file. Rebuild your kernel with device ulpt.

Choosing a Configuration Tool

How you proceed is a matter of personal preference. My favorite configuration utility is /usr/ports/print/apsfilter, as it provides an easy-to-use, lightweight text interface. Michael Lucas wrote a detailed tutorial on using Apsfilter.

If your recommended driver is compiled into Ghostscript, you'll find configuring and testing your printer a breeze with Apsfilter. It will automagically create the correct entries in /etc/printcap for you.

How do you find out if Ghostscript includes your driver? Once you've installed Ghostscript, type gs -h. You'll receive a page of output, so you may want to grep for your particular driver name. In my case, searching for hpijs will fail but searching for ijs will succeed.

Unfortunately, Apsfilter isn't the best approach for this particular printer. My recommended driver is an add-on to Ghostscript and Apsfilter is a script that lets you choose from the drivers compiled into Ghostscript. It would take a lot of trial and error on my part to find the closest driver in that list. I'm not really into a lot of trial and error. Besides, I want to take full advantage of the correct driver.

Instead, I'll take a look at what came with that hpijs port I installed:

# more /usr/ports/print/hpijs/pkg-plist
%%PORTDOCS%%@dirrm share/doc/hpijs

That's not much to work with, a binary without a man page and a readme that assumes I'm installing using CUPS. (I'll discuss CUPS in greater detail in the next article). Since I don't want the overhead of CUPS for a local printer, I'll try a different approach. Since I didn't include the clean directive in my make install command when I built the hpijs port, I still have its working directory:

# ls /usr/ports/print/hpijs/work

Bingo! I've hit pay dirt. This directory contains the foomatic-rip script as well as a directory of PPDs that includes a PPD for my particular model of printer.

What exactly is foomatic-rip? It is a foomatic script that understands a database of all known printer drivers, even those not compiled into Ghostscript.

Using foomatic-rip

While it may seem counterintuitive, it looks like my easiest course of action is to edit /etc/printcap manually, telling it to use foomatic-rip and my printer's PPD file.

First, I'll need to copy those files from the work directory to more reasonable locations. I'll place foomatic-rip in the directory that contains programs installed by ports, and the PPD into a subdirectory of /etc:

# cd /usr/ports/print/hpijs/work/hpijs-1.5
# cp foomatic-rip /usr/local/bin/

# mkdir /etc/foomatic
# cp ppd/HP-OfficeJet_4110-hpijs.ppd /etc/foomatic/

Next, I'll create a spooling directory called OfficeJet to hold the print jobs sent to my OfficeJet printer:

# mkdir /var/spool/lpd/OfficeJet

Now, I'm ready to add the following lines to /etc/printcap:


Even if you don't have to create your /etc/printcap file manually, it's important to understand the contents of this file so that you can troubleshoot your printing system. man printcap will always show you the meanings of the various capabilities (for example, af, if, and sd). Let's pick apart this file:


The default printer is always lp. It can have as many nicknames as you want to give it, as long as you separate them with the pipe character (|). Here, I've given the nickname OfficeJet. Note that every line in this file (except for the very last one) ends with :\ and every line (except the very first one) begins with :.

:lp in the second line refers to the physical device where the printer attaches. Since mine is a USB printer, it uses /dev/ulpt0.

:af gives the full path to the accounting or PPD file.

:if gives the full path to the input filter. Here, I use foomatic-rip. If you instead use apsfilter, the entry it creates for you will refer to apsfilter.

:sd gives the full path to the spooling directory.

:sh stands for suppress header, so the spooler will not create a header page with the print job.

Creating a Test Page

Once I've finished configuring /etc/printcap, I need to tell lpd that its configuration file has changed:

# /etc/rc.d/lpd restart

I'm now ready to try printing a test page. From the command line as a regular user, I'll ask for a print out of my printer configuration file:

% lpr /etc/printcap

Excellent, my printer starts to make printing noises. My console (Alt F1) also gives messages showing that foomatic-rip is doing its thing.

For my next test, I start an X session where I'm using KDE as the window manager. I open up the Firefox browser, click on the File menu -> Print Preview, and see that this function works. I then successfully print a web page from my browser.

I next try to print a specified page from an OpenOffice document. Again, success. See how the various programs on a system all rely on a properly configured /etc/printcap file? With this file setup correctly, you should be able to print from any application.

In the next article, I'll experiment with that hpoj application. I'll also discuss CUPS and demonstrate its usage.

Dru Lavigne is a network and systems administrator, IT instructor, author and international speaker. She has over a decade of experience administering and teaching Netware, Microsoft, Cisco, Checkpoint, SCO, Solaris, Linux, and BSD systems. A prolific author, she pens the popular FreeBSD Basics column for O'Reilly and is author of BSD Hacks and The Best of FreeBSD Basics.

Read more FreeBSD Basics columns.


Copyright © 2009 O'Reilly Media, Inc.