This chapter is an unmodified version of a chapter first produced in 1997. Some or even all of the content may be out of date due to changes in Linux.
Printers are a standard peripheral for any computer system. One of the first devices added to a new system will be a printer. The multi-user, multi-processing nature of the UNIX operating system means that the UNIX printer software is more complex than that of a single-user operating system. This makes adding a printer to a UNIX box more than just plugging it in.
UNIX print software performs a number of tasks including
§ enabling safe use of printers by multiple users,
§ supporting multiple printers, and
§ allowing the use of remote (network based) printers.
This chapter will first examine the hardware issues involved in connecting a printer to a UNIX machine before moving on to examine the more complex part of the process, configuring the software.
In most situations printers are connected to a UNIX machine using serial connections. One of the reasons for this is that serial connections allow for two-way communication which some modern printers use. Many modern systems also provide parallel ports. Generally speaking connecting a printer to a UNIX system follows the same generic process used to connect terminals that was outlined in the previous chapter. Parallel printer cables will not be discussed in this subject.
Common also today are network printers. These are printers with ethernet connections built-in and are connected directly to the network. When buying network printers make sure you have the software required for your computers to talk to it.
Typically you will have two choices with printers, either parallel or serial ports depending on your printer. The details of cabling for serial ports were discussed in the previous chapter.
Since Linux is generally installed onto IBM PC compatible computers it comes with support for parallel printers built-in. The devices /dev/lp0 /dev/lp1 /dev/lp2 are all used for the parallel ports on your Linux box. Each of these devices match a specific hardware I/O address which means that your first parallel port may not be /dev/lp0 it may be /dev/lp1.
You can discover which one it is by connecting a parallel printer and trying ls /dev/lp0 or ls /dev/lp1. Whichever command causes output to be displayed on your printer is using the right device file.
Some reasons why the connection might not work as expected include
§ incorrect cabling
§
there is a getty
process on the printer port,
Especially on serial ports there might be a getty
process running on the port that will cause the login prompt to appear on the
paper. The getty
process will have to be turned off.
§
auto line feed
UNIX uses just the line feed character to separate lines. Most printers have a
carriage return/line feed, auto line feed switch that controls what the printer
expects to use. The problem can be fixed by using the stty
command, by an interface program that performs the necessary translation on all
output going to the printer, or by setting the printer dip switch to the
appropriate setting.
§
incorrect line settings,
For a serial port check the port settings especially baud as it might be set too
fast for the printer. On older printers the printer might not be configured for
the ASCII character set.
§
wrong device file or insufficient permissions.
Using the wrong device file or not having the correct permissions on that file
can result in no output to the printer.
If possible go through the hardware procedure for connecting a printer to your UNIX box.
The software that drives the UNIX printing process is another area in which the different UNIX versions differ greatly. Both versions are based on the concept of spooling (spool stands for Simultaneous Peripheral Operations On-Line).
All UNIX print software has the following components
§ a print spooler,
§ spool directories,
§ a print daemon,
§ administrative commands, and
§ filter programs.
For the purposes of this subject we will be concentrating on the Linux print software.
The print spooler is the program users execute when they wish to print something (usually the commands lpr or lp). The print spooler takes what the user wishes to print and places it into some pre-defined location, the spool directory. Usually assigning the print job some unique number.
Each printer on a UNIX system has its own spool directory. Print jobs are copied into the spool directory before being printed.
The print daemon (usually lpd or lpsched) is responsible for checking the spooling directory and sending files from the spool directory to the correct printer one job at a time.
For every printer there will always be a maximum of one print daemon. This ensures that only one document is being printed on the printer.
As can be expected there must be administrative commands to perform a number of tasks including
§ changing the priority of print jobs
§ deleting print jobs
§ enabling and disabling printers.
Both SysV and BSD print services also support the concept of an interface or filter program. These programs filter all output sent to a printer and modifies it in some way. Uses include
§
adding a banner page to every print job,
Many UNIX systems automatically add a banner page to the front of a print job.
The purpose of the page is to identify the owner of the printer output.
§ adding or removing a carriage return character, or
§ converting the files to be printed into the format the printer expects (e.g. Postscript, PCL)
The Linux print system is based on the BSD print system and we will concentrate on it. The major components of the BSD print system are listed in Table 19.1 An overview of the system is provided by Diagram 19.1.
|
Component |
Purpose |
|
lpc |
make administrative changes to the print service |
|
lpd |
the daemon, a copy is spawned for each queue, transfers information from spooling area to physical device |
|
lpq |
view the contents of a print queue |
|
lpr |
the user print command, spools information to be printed |
|
/etc/printcap |
system's printer information database |
|
lprm |
removes print jobs from queues |
Table 19.1
BSD/Linux print components
Diagram 19.1
Overview of BSD print system
Assuming that the Linux/BSD print system has been configured, started and that a valid printer has been connected to the system the following is an overview of what happens when a user wants to print something.
§
the lpr
command is used
lpr /etc/passwd
§
the lpr
commands discovers the name of the printer on which to print this file by one of
three methods
1. command line parameters for the lpr
command
2. the shell variable PRINTER
3. or the system wide configuration
§ lpr reads the /etc/printcap file to find out where the printer's spool directory is,
§
lpr creates
two files in the spool directory, each filename ends with a unique identifier
for this particular print job (an example identifier A015Aa00781
1. cfid is
the control file and contains information like who printed the file, from which
computer, and which file it was
2. dfid is
the data file that contains the actual information to print
§ lpr notifies lpd that there is a file ready to print
§ lpd forks off a child lpd to handle the request
§ lpd reads /etc/printcap to see whether or not the destination printer is a local or remote printer
§ for a remote printer the contents of the cf and df files are copied across the network,
§ for a local printer lpd spawns a copy of itself that passes the df file through a filter program (if there is one) to the printer's device file
As mentioned lpr is the only way in which a user can print a file. Example uses of lpr include
§
lpr /etc/printcap
Print the file /etc/printcap
on the systems default printer.
§
lpr -Prigel hello
Print the file hello
on the printer called rigel.
§
cat /etc/passwd |
lpr -Pgb
Send the output of the cat
command to the printer gb
lpr takes a number of other options including -# which can be used to specify the number of copies to print.
Adding a new printer to a Linux box includes the following steps
§
connect the printer,
Discussed in a previous section.
§ make sure a copy of lpd is running,
§ create an entry in the /etc/printcap file for the printer,
§ create the spool directory for the new printer,
§ use the lpc command to enable printing for the new printer
lpd is the print spooler daemon. In order for any printing to occur a copy of lpd must be running. Normally lpd is started by one of the system startup scripts, usually /etc/rc.d/rc.M.
On startup lpd reads the /etc/printcap file to find out about existing printers and will check the spool directories for any print jobs that haven't been printed.
lpd then waits for any new print requests. When it receives a new request it will fork of a child lpd to handle the request.
Is there a copy of lpd running on your system? Where is it started? What is its file permissions?
printcap is the printer configuration file and uses the same format as termcap the BSD terminal configuration file. printcap is a colon delimited text file. Each printer has one entry. An example printcap entry follows
lp|ap|arpa|ucbarpa|LA-180 DecWriter
III:\
:br#1200:fs#06320:tr=\f:of=/usr/lib/lpf:\
:lf=/usr/adm/lpd-errs:
An entry in printcap must fit on one line. Notice in the above three line example the \ character is used to ignore the special meaning of the new line character at the end of the first two lines. This effectively means that the entry is only one line.
The first field in each entry of the /etc/printcap file specifies the printer's name. A printer can actually have multiple names. Multiple names are separated using the | character. The above example printer has the following names lp ap arpa ucbarpa and LA-180 DecWriter III.
A printer called lp is the standard default printer. Whenever a user prints a file without specifying the destination printer the print job will be sent to the printer called lp. You should always have one printer with the name lp.
The remaining fields of the /etc/printcap file are used to specify a variety of different settings. These configuration settings use one of three possible formats
§ XX=string
§ XX
§ XX#number
Where XX is a two letter identifier for a particular configuration setting. Table 19.2 lists some of the settings.
Some example printcap settings include
§
sd=/usr/spool/lp/scribe
The sd setting
specifies where the spool directory for the printer is.
§
fo
The fo setting
forces the printer to do a form feed when the device is first opened.
§
mx#3
The mx setting
specifies the maximum size (in disk blocks) of files that can be printed.
|
Purpose |
|
|
sd=directory |
specify spool directory |
|
lf=file |
specify error log file |
|
lp=file |
specify device file |
|
af=file |
specify accounting file |
|
rw |
specify that printer can
both read |
|
br#number |
specify baud rate |
|
fc#number |
specify flag bits to turn off |
|
fs#number |
specify flag bits to turn on |
|
xc#number |
specify local mode bits to turn off |
|
xs#number |
specify local mode bits to turn on |
|
pl#number |
specify page length in lines |
|
pw#number |
specify page width in characters |
|
py#number |
specify page height in pixels |
|
px#number |
specify page width in pixels |
|
ff=string |
specify string that causes printer to form feed |
|
fo |
output form feed when device is opened |
|
mc#number |
specify maximum number of copies of a job allowed |
|
mx#number |
specify maximum file size in blocks allowed |
|
sc |
specify that multiple copies should be prevented |
|
sf |
specify that form feeds should be prevented |
|
sh |
suppress the printing of headers |
Table 19.2
Some /etc/printcap
configuration settings
You won't be expected to memorise the flag and local bits. You should however be aware of their purpose.
Flag bits are used to specify various communication settings for the printers. Table 19.3 shows the meanings and octal values of the more important bits.
The flag bits that are to be turned on are specified using the fs identifier (see Table 19.2). Those flag bits to be turned off are specified using the fc identifier.
The values for these fs and fc are obtained by adding the octal values from Table 19.3 together.
Assume you need to set the following for the printer you are adding
§ clear all delay bits and echo/full duplex
§ set even and odd parity, enable automatic flow control.
Calculating the fc setting would look like this
0040000 + 0010000 + 0020000 + 0002000 + 0000400 + 0001000 + 0000010 = 0073410
Which results in the printcap entry
fc#0073410
For the fs entry
0100 + 0200 + 0001 = 0301
For the printcap entry
fs#0301
Remember these numbers are in octal (base 8). If you don't know how to do addition in base 8 obtain a calculator which supports octal. Most good scientific calculators should.
|
Description |
|
|
0040000 |
form feed delay, 2 seconds |
|
0010000 |
carriage return delay, 0.08 second |
|
0020000 |
carriage return delay, 0.16 second |
|
0002000 |
tab delay |
|
0000400 |
newline delay |
|
0001000 |
newline delay, 0.1 second |
|
0000200 |
even parity |
|
0000100 |
odd parity |
|
0000040 |
pass all characters from filter to printer immediately |
|
0000020 |
translate linefeed into carriage return&linefeed |
|
0000010 |
echo, full duplex |
|
0000002 |
pass characters from printer to filter immediately |
|
0000001 |
automatic flow control |
Table 19.3
Flag settings
Local mode bits are used to configure the serial driver and use the same format as flag bits only with the xc and xs settings instead. Most of these settings are intended for terminals. Those relevant for printers are listed in Table 19.4
|
Octal
value |
Description |
|
000040 |
prevent serial driver from playing with codes destined for printer |
|
040000 |
minimize flow control interference from line noise |
|
000001 |
tell the printer to backspace when it receives an erase character |
Table 19.4
Local Mode bits for a serial printer
Each printer must have its own spool directory. They cannot share spool directories. A spool directory should be owned by the root user and the lp group and the permissions should be set to rwxrwxr-x.
Printer spool directories are usually under the directory /var/spool with the name of the directory matching the main name of the printer.
For example the spool directory for the printer rigel would be /var/spool/rigel.
Apart from the cf and df files for each print job the printer spool directory will also contain the files
§
lock
Its existence prevents multiple copies of lpd
working for this printer.
§
status
Contains the current status of printing on this printer.
These files are created by the components of the print system.
lpc is used to control the operation of the print service. It can be used to
§ disable or enable a printer,
§ disable or enable a printer's spooling queue,
§ rearrange the order of jobs in a spooling queue,
§ find the status of printers, and their associated spooling queues and printer daemons.
The following is an excerpt from UNIX System Administration Handbook by Nemeth et al (consider the Sys Admin bible by many) on lpc
lpc won our award for "flakiest program of 1989". It was also awarded this honor in 1985, 1986, 1987 and 1988. lpc has not really gotten any better, but other truly flaky programs (like Sun's automounter) have come into widespread use, and lpc is no longer at the top of the heap.
lpc understands a number of commands to perform the operations listed above. These commands can be entered as command line arguments. If lpc is started without any arguments it enters an interactive mode in which you can enter lpc commands.
beldin:# lpc status
lp:
queuing
is enabled
printing
is enabled
no entries
no
daemon present
beldin:1# lpc
lpc status
lp:
queuing
is enabled
printing
is enabled
no
entries
no
daemon present
Table 19.5 lists some of the commands that can be given to lpc. There are a number of other commands for which you should refer to the manual page.
In order to start printer for a new printer you need to enable spooling (the lpc enable command) for the printer and start a copy of the daemon (the lpc start command) for the printer.
|
Command |
Purpose |
|
?
[command] |
provide short description of command |
|
abort [all | printer ] |
terminate the daemon and then disable printing for the specified printers. |
|
enable [all | printer ] |
start spooling for the specified printers |
|
start [all | printer ] |
start printing for the listed printers |
|
stop [ all | printer ] |
stop a spooling daemon and disable printing |
|
status [ printer ] |
display the current status of each printer |
Table 19.5
lpc
commands
§
connect the printer,
Get a parallel printer cable, choose a parallel port connect the computer and
printer and identify the device file that corresponds to the parallel port. On
my system it is /dev/lp1
§
make sure a copy of lpd
is running,
Try the command ps -ax |
grep lpd. Oops, not there. Add the command /usr/sbin/lpd
to the file /etc/rc.d/rc.M
so it will start the next time the system boots. Rather than reboot the system
for this to take effect I can run it from the command line now.
§
create an entry in the /etc/printcap
file for the printer,
Add the following entry,
lp:lp=/dev/lp1: \
sd=/var/spool/lp:sh
This is my only printer so it is my default printer. The device file is /dev/lp1, the spool directory will be /var/spool/lp and I don't want any headers printed (sh).
§ create the spool directory for the new printer,
mkdir /var/spool/lp
chown root.lp /var/spool/lp
chmod 775 /var/spool/lp
§ use the lpc command to enable printing for the new printer
lpc enable lp
lpc start lp
Even if you don't have printer you can still experiment with the UNIX print service. What do you notice about the following printcap entry?
lp:lp=/tmp/printer:sd=/usr/spool/lp1:sh
The device file for this printer, specified by the lp setting, is the file /tmp/printer, which isn't a device file. lpd simply redirects its output to the device file specified in the /etc/printcap file.
If this file is not a device file the output is simply appended onto the end of the file.
Perform the steps necessary to add a printer to your system. If you don't have a printer use a normal file as the device file. Test the connection by printing something.
lpq displays the list of jobs that are currently waiting to be printed. With no parameters lpq will display a list of all print jobs on the default printer. lpq command line options are specified in Table 19.6
|
Options |
Purpose |
|
-P printer |
display the queue of the specified printer |
|
-l |
display using long format |
|
+[interval] |
display the queue periodically until it empties, interval specifies how many seconds it should sleep |
|
job# |
display only those jobs with matching job numbers |
|
username |
display only jobs belonging to the specified user |
Table 19.6
lpq
switches
lprm [-Pprinter][-][ job#...][username...]
lprm is used to remove jobs from the printer queue. The job to be removed can be specified by its printer, job number and username. The printer name defaults to lp and the job number defaults to the current job. Username defaults to the user invoking it.
Only the root user can remove someone else's print job.
Disable
the print daemon for your printer and send a few print jobs to the printer.
Since the daemon has been turned off the jobs will be queued waiting for the
print daemon to be re-enabled.
Use the lpq
command to view the print queue. Use the lprm
command to remove the print jobs.
Re-enable printing using lpc
Filters are generally used to transform data to be printed into a format that the printer can handle. For example, printing to a Deskjet 500 results in the following output
hello
there
a nice effect
The effect is caused because the printer expects a carriage return character to properly handle a new line. This problem can be handled by using a filter program that adds a carriage return character to the end of each line to be printed.
The UNIX print system was originally developed in the days of line printers. Today it is generally used for high-resolution printers that use some form of page description language (PDL). A PDL defines how the layout will be represented onto the page. Common PDLs include
§
PCL
, Printer Command Language
Developed by Hewlett-Packard as an alternative to postscript. Generally only
found on HP printers and is common amongst the PC world.
§
PostScript
PostScript is a fully-fledged programming language. PostScript files are text
files consisting of PostScript commands. It is one of the most common PDLs.
Filters are used to convert data to be printed into the appropriate PDL. Filters to convert to most PDLs are available from the Internet. In most instances a printer will come with an appropriate filter.
You should remember that the filter will be an executable program. If the filter does not have the execute permission set the whole print system will not work as expected.
The
following command translates every letter to uppercase
tr '[a-z]' '[A-Z]'
Use the command as a filter for your printer. What happens if your
filter program doesn't have execute permissions set?
The process of adding a printer to a UNIX machine involves two processes, hardware and software. The hardware steps involved in adding a printer are very similar to those involved in adding a terminal.
The UNIX print software is much more complex than that of a single-user operating system and is based on the concept of print spooling. The print services of BSD and SysV are completely different. With Linux using a system based on the BSD print service.
The Linux/BSD print system consists of the following components
§
the lpr
command,
Used by users to print.
§
the lpd
daemon,
The main print daemon.
§
the /etc/printcap
file,
Contains configuration information for each printer.
§
the lpc
command,
The main administration program used by the Systems Administrator.
§
the lpq
command,
Used to view the queue of print jobs.
§
the lprm
command,
Used to remove print jobs from the queue.
Explain the relevance and purpose of the following in relation to the BSD print system
§
lpd
§
/etc/printcap
§ lpc