lpr Command in Linux: Complete Guide to Printing Files and Parameters

lpr command in Linux and it perimeters

I’ll admit printing is the part of Linux system administration I deal with least often these days — most of my work lives entirely on screens. But every so often a compliance requirement or a physical signature form means someone needs a document printed from a headless Linux server or over SSH, and lpr is the command that quietly makes that possible without ever touching a GUI print dialog.

What lpr Does

lpr submits files to a print queue managed by CUPS (the Common Unix Printing System), which is the printing architecture used by virtually every modern Linux distribution. lpr itself is actually a BSD-heritage command-line interface preserved for compatibility — under the hood, on a modern Linux system, it’s talking to the same CUPS daemon (cupsd) that handles print jobs submitted through a desktop GUI.

lpr [OPTIONS] [FILE]...

Basic usage:

lpr document.pdf

This submits document.pdf to the default printer’s queue. If no file is given, lpr reads from standard input, which lets you pipe generated content straight to the printer:

ls -la /var/log | lpr

How lpr and CUPS Work Together

When you run lpr, it doesn’t talk to the printer hardware directly. Instead, it hands the file off to the CUPS scheduler (cupsd), which:

  1. Queues the job.
  2. Determines the appropriate filter chain to convert the input format (PDF, PostScript, plain text, image) into a format the target printer understands (often PostScript or a manufacturer-specific raster format via a PPD — PostScript Printer Description — file).
  3. Sends the converted data to the printer over the configured connection (USB, network/IPP, or a print server).
  4. Tracks job status, so tools like lpq and lpstat can report on it.

This architecture is why lpr supports printing so many different file types out of the box — the actual format conversion work is delegated to CUPS’s filtering system, not handled by lpr itself.

Core Options and Parameters

-P PRINTER — Select a Specific Printer

lpr -P office_laser document.txt

Without -P, lpr sends the job to the system’s configured default printer. You can list available printers with lpstat -p (a companion CUPS command) to find valid printer names for -P.

-#COPIES — Number of Copies

lpr -#3 report.pdf

Note the somewhat unusual syntax — the number of copies is attached directly after a # rather than being a separate argument, a holdover from lpr‘s traditional BSD option syntax.

-o OPTION=VALUE — Pass Print Job Options

This is where most of the practically useful control lives, since it passes options through to CUPS itself:

lpr -o sides=two-sided-long-edge document.pdf
lpr -o media=A4 document.pdf
lpr -o fit-to-page document.pdf
lpr -o number-up=2 document.pdf
  • sides=two-sided-long-edge / sides=two-sided-short-edge — duplex printing.
  • media=SIZE — paper size (e.g., A4, Letter, Legal).
  • fit-to-page — scale content to fit the selected page size.
  • number-up=N — print N logical pages per physical sheet (useful for draft printing to save paper).
  • orientation-requested=4 — landscape orientation (CUPS uses numeric IPP orientation codes; 4 is landscape, 3 is portrait).

Multiple -o flags can be combined in a single command:

lpr -P office_laser -o sides=two-sided-long-edge -o media=A4 -#2 report.pdf

-r — Remove the File After Spooling

lpr -r /tmp/generated_report.txt

Deletes the local file once it has been successfully handed off to the print spooler — useful for cleanup in automated report-generation-and-print scripts where the local copy is only a temporary artifact.

-h — Suppress the Burst Page

Disables the “banner” or “burst” page that some print environments insert between jobs to identify where one job ends and the next begins — useful in low-volume or single-user contexts where the banner page is just wasted paper.

-J NAME — Assign a Job Name

lpr -J "Q3 Financial Report" report.pdf

Assigns a human-readable name to the job as it appears in queue listings (lpq), which is helpful when multiple jobs are queued and you need to identify yours at a glance.

Companion Commands: Managing the Print Queue

lpr doesn’t work alone — a small family of BSD-heritage commands manage the print queue around it:

lpq — Check Queue Status

lpq -P office_laser

Lists pending jobs for the given printer, showing job IDs, owners, and status — the equivalent of checking “what’s still waiting to print.”

lprm — Remove a Job from the Queue

lprm -P office_laser 42

Cancels job ID 42 (as reported by lpq) before it prints — essential when you realize you sent the wrong file or the wrong number of copies.

lpstat — Check Printer and Job Status (CUPS-native)

lpstat -p          # list printers and their status
lpstat -o          # list pending jobs
lpstat -d           # show the current default printer

lpoptions — View or Set Printer Options

lpoptions -p office_laser -l    # list available options for a printer
lpoptions -d office_laser       # set the system default printer

Practical, Real-World Examples

1. Printing a Report Generated by a Script

generate_monthly_report.sh > /tmp/report.txt
lpr -P accounting_printer -J "Monthly Report" -r /tmp/report.txt

2. Printing Double-Sided, Multiple Copies

lpr -P office_laser -o sides=two-sided-long-edge -#5 handout.pdf

3. Draft-Printing to Save Paper

lpr -o number-up=4 -o fit-to-page draft_document.pdf

Four logical pages per physical sheet is a common trick for quickly reviewing a long document without burning through paper for a draft that will be discarded.

4. Checking and Clearing a Stuck Queue

lpq -P office_laser
lprm -P office_laser -           # remove all of the current user's jobs

5. Printing from a Remote Server Over SSH

ssh server 'cat /var/log/critical_report.txt' | lpr -P local_printer

This pulls content from a remote server and prints it on a locally connected printer, without needing to manually copy the file down first.

lpr in Shell Scripting and Automation

A pattern I’ve used for automated compliance reporting where a signed physical copy was still required by policy:

#!/bin/bash
REPORT="/tmp/compliance_report_$(date +%Y%m%d).pdf"
generate_compliance_report.py > "$REPORT"

if lpstat -p compliance_printer | grep -q "is idle"; then
  lpr -P compliance_printer -o sides=two-sided-long-edge -J "Compliance $(date +%Y-%m-%d)" -r "$REPORT"
  echo "Report sent to printer"
else
  echo "Printer not ready, report saved at $REPORT" >&2
fi

Checking lpstat -p before submitting avoids silently queuing jobs to an offline or error-state printer without any feedback.

Comparing lpr to Related Commands

TaskBest Tool
Submitting a print job (BSD-style)lpr
Submitting a print job (System V-style, CUPS-native)lp
Checking queue statuslpq / lpstat -o
Removing a queued joblprm / cancel
Configuring printer optionslpoptions / cupsctl
Managing printers via web interfaceCUPS web admin (http://localhost:631)

Modern CUPS actually provides two parallel command-line interfaces for historical compatibility reasons: the BSD-style commands (lpr, lpq, lprm) and the System V-style commands (lp, lpstat, cancel). Both talk to the same underlying CUPS daemon and largely accomplish the same things with different syntax conventions — which one you use is mostly a matter of habit or what a particular script/tutorial happened to use. lp tends to have slightly more consistent, modern-feeling option syntax (lp -d printer -n 3 file.pdf versus lpr -P printer -#3 file.pdf), but both remain fully supported.

Troubleshooting Common lpr Issues

“lpr: Error – no default destination” — no default printer is configured; specify one explicitly with -P, or set a default with lpoptions -d printer_name.

Job stuck in the queue indefinitely — check lpstat -p for the printer’s status; a printer reporting an error state (out of paper, offline, jammed) will hold jobs indefinitely until the underlying issue is resolved.

Printed output looks garbled or is entirely blank pages — usually a driver/PPD mismatch; verify the correct driver is configured for the printer model via the CUPS web interface (http://localhost:631) or lpinfo -m to list available driver models.

Permission denied submitting a job — CUPS printer access can be restricted by user or group; check /etc/cups/printers.conf and the printer’s configured access policy, or consult with whoever administers the print server.

Performance Optimization

For high-volume printing, batching multiple files into a single lpr invocation (lpr file1.pdf file2.pdf file3.pdf) reduces per-job scheduling overhead compared to invoking lpr separately for each file. For very large documents, ensure the CUPS spool directory (/var/spool/cups) has adequate free disk space, since large jobs are spooled to disk before being sent to the printer.

Security Implications

Print jobs pass through the CUPS spool directory and, for network printers, travel over the network (often via IPP) — sensitive documents printed to a shared or network printer can potentially be intercepted or left sitting in an output tray for anyone to see. For sensitive material, use printers with an authentication/release feature (holding jobs until the user authenticates at the printer) if your environment supports it, and ensure CUPS’s web administration interface isn’t exposed beyond localhost or the intended management network, since misconfigured CUPS instances have historically been a source of information disclosure and, in some cases, remote code execution vulnerabilities.

Compatibility Across Distributions

lpr is provided by the cups-bsd package (part of the broader CUPS printing system) and is available on virtually all major Linux distributions — Ubuntu, Debian, Fedora, RHEL/CentOS, Arch, openSUSE — though it may need to be explicitly installed on minimal server images, since a full printing stack isn’t always included by default on headless server installations. macOS also uses CUPS under the hood and includes lpr by default. The core options (-P, -#, -o) behave consistently across these because they’re standardized by CUPS itself rather than varying per distribution.

Understanding the CUPS Architecture Behind lpr

To really understand what lpr is doing, it helps to walk through the CUPS architecture layer by layer. At the center sits cupsd, a background daemon that listens (by default on port 631) for print requests using the Internet Printing Protocol (IPP), an HTTP-based protocol. When you run lpr, it’s essentially constructing and sending an IPP “create job” and “send document” request to cupsd, whether that daemon happens to be running locally or on a remote print server.

Once cupsd receives a job, it consults its configuration to determine which “class” of filter chain the destination printer needs. CUPS ships with a set of filters capable of converting many common formats — plain text, PostScript, PDF, and various image formats — into a format the printer itself understands, which for many printers means either PostScript or a raster format described by that printer’s PPD (PostScript Printer Description) file. Modern “driverless” printers that support IPP Everywhere or AirPrint-style protocols can often skip much of this legacy filter chain entirely, since they accept a more directly renderable format from CUPS without needing a printer-specific driver at all.

Backend modules then handle the final step of actually transmitting the processed job to the physical printer, whether that’s over USB, a network socket, or another print server acting as an intermediary. This layered design — client tool (lpr) → daemon (cupsd) → filter chain → backend → hardware — is why lpr itself can remain such a small, simple command: nearly all the real complexity of format conversion and device communication is handled elsewhere in the CUPS stack, not in lpr itself.

Configuring and Discovering Printers

Before lpr can be useful, at least one printer needs to be configured in CUPS. This is commonly done through the CUPS web administration interface (http://localhost:631/admin), though it can also be done entirely from the command line using lpadmin:

lpadmin -p office_laser -E -v socket://192.168.1.50 -m everywhere

This example adds a network printer named office_laser, reachable via raw socket printing at a given IP address, using CUPS’s generic “everywhere” driver profile for modern driverless-capable printers. Once added, lpstat -p will list it, and lpr -P office_laser becomes usable immediately.

Handling Common Print Job Formats

lpr and CUPS handle format detection largely automatically, using logic similar in spirit to the file command discussed elsewhere in this series — inspecting file content rather than trusting the extension. This means you can generally hand lpr a PDF, a plain text file, a PostScript file, or a common image format without needing to specify the format explicitly:

lpr report.pdf
lpr notes.txt
lpr diagram.png

If automatic detection ever misidentifies a file’s format, the -o document-format option can be used to force a specific MIME type interpretation, though this is rarely necessary in practice with modern CUPS installations.

Monitoring and Auditing Print Activity

For environments where print activity needs to be tracked (cost accounting, compliance, or simple troubleshooting of “who printed what”), CUPS maintains logs that can be inspected directly, complementing what lpq/lpstat show for currently queued jobs:

sudo tail -f /var/log/cups/page_log

This log records completed print jobs with details including the user, printer, and page count, which is useful both for auditing purposes and for diagnosing whether a job that seemed to vanish from the queue actually completed successfully or failed silently.

Summary

lpr is the command-line front door to CUPS-managed printing on Linux — deceptively simple on the surface (lpr file.pdf) but backed by the full flexibility of CUPS’s option system via -o for duplexing, paper size, scaling, and page layout. Paired with lpq for queue status and lprm for cancellation, it covers everything needed to manage print jobs entirely from the command line, which matters more than it might seem on headless servers or in automated reporting pipelines where a GUI simply isn’t available.

References

  • CUPS Documentation: https://www.cups.org/doc/
  • CUPS Command-Line Printing Guide: https://www.cups.org/doc/options.html
  • man lpr / man lpq / man lprm (local manual pages)
Total
0
Shares

Leave a Reply

Previous Post
less command in Linux and it perimeters

less Command in Linux: Complete Guide to Advanced File Paging, Navigation, and Parameters

Next Post
more command in Linux and it perimeters

more Command in Linux: Complete Guide to Paginated File Viewing and Parameters

Related Posts