20.3. Job is not in print queue, but it gets printed!

In the original BSD lpd implementation, the lpr program copied users files to a special spool queue directory, and then caused the lpd server to peek in the directory and print the files.

This type of operation required spool directory space, special SETUID programs, and a slew of headaches in system security and management.

The LPR, lpq, and other user programs in the LPRng suite use TCP/IP connections and transfer jobs directly to a lpd server running on a remote host, or even the local host if appropriate. Note that this type of operation does not require a lpd server to run on each local machine. In fact, you can have a single host system performing all of your printing. This type of operation is very similar to a central mail server versus individual systems, each having their own mail server and queues.

However, some users require or want their jobs to be spooled on the local host system, and then transferred to the remote printer. This is usually the case when some type of processing (filtering) is needed in order to print the job correctly. There are several methods that can be used to force this.

Method 1: Explicit Printer Address

You can force a job to be sent directly to the pr serviced by the lpd server on host by using the form:

    lpr -Ppr@host file


You can also set the PRINTER environment variable to a similar form, and get the same effect:

    PRINTER=pr@host; export PRINTER;
    lpr file


Method 2: User and Server Printcap Entries

If you want to have the benefits of a printcap file, i.e. - you can use aliases or abbreviations for the names of printers, then here is a couple of hints. First, the LPRng software scans the printcap file for printcap entries, combining information for the same printer into a single entry. Information found later in the printcap file will override earlier information. In addition, you can tag entries as either being used for all utilities or just for the lpd server. Here are a couple of examples:

    # for all utilities
    pr:lp=pr@host
    # just for lpd
    pr:server
      :lp=/dev/lp
    # more information
    pr:check_for_nonprintable@
    # --- final result for LPR
    pr:lp=pr@host:check_for_nonprintable@
    # --- final result for lpd
    pr:lp=/dev/lp:check_for_nonprintable@


As you can see, the server keyword indicates that the printcap entry is only for the server. The lpr utility will send the job to the host, while the lpd server will print it on /dev/lp.

Note that the lp=... information overrides the :rp: (remote printer) and :rm: (remote machine) fields if they are present.

Method 3: Force sending to server on localhost

The force_localhost printcap or configuration flag forces non-lpd applications to send all requests and print jobs to the server running on the local host.

This method is similar to the previous one, but has the benefit that it can be configured as a global (i.e. - applies to all printers) rather than printer specific. You can put this in the lpd.conf file for general application, or have a printcap entry of the following form:

    # for all utilities
    pr:lp=pr@host:force_localhost


The lpd server will ignore the force_localhost flag, and send jobs to the pr queue on the host machine. However, the LPR, lpq, etc., utilities will send their requests to the server running on the local host.