aboutsummaryrefslogtreecommitdiff
path: root/documentation/content/en/books/handbook/printing/_index.adoc
blob: f07ddc02bce3c1bd9d9720cb691762feeb6b37b1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
---
title: Chapter 10. Printing
part: Part II. Common Tasks
prev: books/handbook/kernelconfig
next: books/handbook/linuxemu
description: This chapter covers the printing system in FreeBSD
tags: ["printing", "CUPS", "LPD", "PostScript", "PDLs", "HPLIP", "LPRng"]
showBookMenu: true
weight: 13
path: "/books/handbook/"
---

[[printing]]
= Printing
:doctype: book
:toc: macro
:toclevels: 1
:icons: font
:sectnums:
:sectnumlevels: 6
:sectnumoffset: 10
:partnums:
:source-highlighter: rouge
:experimental:
:images-path: books/handbook/printing/

ifdef::env-beastie[]
ifdef::backend-html5[]
:imagesdir: ../../../../images/{images-path}
endif::[]
ifndef::book[]
include::shared/authors.adoc[]
include::shared/mirrors.adoc[]
include::shared/releases.adoc[]
include::shared/attributes/attributes-{{% lang %}}.adoc[]
include::shared/{{% lang %}}/teams.adoc[]
include::shared/{{% lang %}}/mailing-lists.adoc[]
include::shared/{{% lang %}}/urls.adoc[]
toc::[]
endif::[]
ifdef::backend-pdf,backend-epub3[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]
endif::[]

ifndef::env-beastie[]
toc::[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]

Putting information on paper is a vital function, despite many attempts to eliminate it.
Printing has two basic components.
The data must be delivered to the printer, and must be in a form that the printer can understand.

[[printing-quick-start]]
== Quick Start

Basic printing can be set up quickly.
The printer must be capable of printing plain `ASCII` text.
For printing to other types of files, see <<printing-lpd-filters>>.

[.procedure]
****
. Create a directory to store files while they are being printed:
+
[source,shell]
....
# mkdir -p /var/spool/lpd/lp
# chown daemon:daemon /var/spool/lpd/lp
# chmod 770 /var/spool/lpd/lp
....
+
. As `root`, create [.filename]#/etc/printcap# with these contents:
+
[.programlisting]
....
lp:\
lp=/dev/unlpt0:\  <.>
sh:\
mx#0:\
sd=/var/spool/lpd/lp:\
lf=/var/log/lpd-errs:
....
+
<.> This line is for a printer connected to a `USB` port.
+
For a printer connected to a parallel or "printer" port, use:
+
[.programlisting]
....
:lp=/dev/lpt0:\
....
+
For a printer connected directly to a network, use:
+
[.programlisting]
....
:lp=:rm=network-printer-name:rp=raw:\
....
+
Replace _network-printer-name_ with the `DNS` host name of the network printer.
+
. Enable LPD by editing [.filename]#/etc/rc.conf#, adding this line:
+
[.programlisting]
....
lpd_enable="YES"
....
+
Start the service:
+
[source,shell]
....
# service lpd start
Starting lpd.
....
+
. Print a test:
+
[source,shell]
....
# printf "1. This printer can print.\n2. This is the second line.\n" | lpr
....
+
[TIP]
====
If both lines do not start at the left border, but "stairstep" instead, see <<printing-lpd-filters-stairstep>>.
====
+
Text files can now be printed with `lpr`.
Give the filename on the command line, or pipe output directly into `lpr`.
+
[source,shell]
....
% lpr textfile.txt
% ls -lh | lpr
....
****

[[printing-connections]]
== Printer Connections

Printers are connected to computer systems in a variety of ways.
Small desktop printers are usually connected directly to a computer's `USB` port.
Older printers are connected to a parallel or "printer" port.
Some printers are directly connected to a network, making it easy for multiple computers to share them.
A few printers use a rare serial port connection.

FreeBSD can communicate with all of these types of printers.

[[printing-connections-usb]]
`USB`::
`USB` printers can be connected to any available `USB` port on the computer.
+
When FreeBSD detects a `USB` printer, two device entries are created: [.filename]#/dev/ulpt0# and [.filename]#/dev/unlpt0#.
Data sent to either device will be relayed to the printer.
After each print job, [.filename]#ulpt0# resets the `USB` port.
Resetting the port can cause problems with some printers, so the [.filename]#unlpt0# device is usually used instead.
[.filename]#unlpt0# does not reset the USB port at all.

[[printing-connections-parallel]]
Parallel (`IEEE`-1284)::
The parallel port device is [.filename]#/dev/lpt0#.
This device appears whether a printer is attached or not, it is not autodetected.
+
Vendors have largely moved away from these "legacy" ports, and many computers no longer have them.
Adapters can be used to connect a parallel printer to a `USB` port.
With such an adapter, the printer can be treated as if it were actually a `USB` printer.
Devices called _print servers_ can also be used to connect parallel printers directly to a network.

[[printing-connections-serial]]
Serial (RS-232)::
Serial ports are another legacy port, rarely used for printers except in certain niche applications.
Cables, connectors, and required wiring vary widely.
+
For serial ports built into a motherboard, the serial device name is [.filename]#/dev/cuau0# or [.filename]#/dev/cuau1#.
Serial `USB` adapters can also be used, and these will appear as [.filename]#/dev/cuaU0#.
+
Several communication parameters must be known to communicate with a serial printer.
The most important are _baud rate_ or `BPS` (Bits Per Second) and _parity_.
Values vary, but typical serial printers use a baud rate of 9600 and no parity.

[[printing-connections-network]]
Network::
Network printers are connected directly to the local computer network.
+
The `DNS` hostname of the printer must be known.
If the printer is assigned a dynamic address by `DHCP`, `DNS` should be dynamically updated so that the host name always has the correct `IP` address.
Network printers are often given static `IP` addresses to avoid this problem.
+
Most network printers understand print jobs sent with the LPD protocol.
A print queue name can also be specified.
Some printers process data differently depending on which queue is used.
For example, a `raw` queue prints the data unchanged, while the `text` queue adds carriage returns to plain text.
+
Many network printers can also print data sent directly to port 9100.

[[printing-connections-summary]]
=== Summary

Wired network connections are usually the easiest to set up and give the fastest printing.
For direct connection to the computer, `USB` is preferred for speed and simplicity.
Parallel connections work but have limitations on cable length and speed.
Serial connections are more difficult to configure.
Cable wiring differs between models, and communication parameters like baud rate and parity bits must add to the complexity.
Fortunately, serial printers are rare.

[[printing-pdls]]
== Common Page Description Languages

Data sent to a printer must be in a language that the printer can understand.
These languages are called Page Description Languages, or PDLs.

[[print-pdls-ascii]]
`ASCII`::
Plain `ASCII` text is the simplest way to send data to a printer.
Characters correspond one to one with what will be printed: an `A` in the data prints an `A` on the page.
Very little formatting is available.
There is no way to select a font or proportional spacing.
The forced simplicity of plain `ASCII` means that text can be printed straight from the computer with little or no encoding or translation.
The printed output corresponds directly with what was sent.
+
Some inexpensive printers cannot print plain `ASCII` text.
This makes them more difficult to set up, but it is usually still possible.

[[print-pdls-postscript]]
PostScript(R)::
PostScript(R) is almost the opposite of `ASCII`.
Rather than simple text, a PostScript(R) program is a set of instructions that draw the final document.
Different fonts and graphics can be used.
However, this power comes at a price.
The program that draws the page must be written.
Usually this program is generated by application software, so the process is invisible to the user.
+
Inexpensive printers sometimes leave out PostScript(R) compatibility as a cost-saving measure.

[[print-pdls-pcl]]
`PCL` (Printer Command Language)::
`PCL` is an extension of `ASCII`, adding escape sequences for formatting, font selection, and printing graphics.
Many printers provide `PCL5` support.
Some support the newer `PCL6` or `PCLXL`.
These later versions are supersets of `PCL5` and can provide faster printing.

[[print-pdls-host-based]]
Host-Based::
Manufacturers can reduce the cost of a printer by giving it a simple processor and very little memory.
These printers are not capable of printing plain text.
Instead, bitmaps of text and graphics are drawn by a driver on the host computer and then sent to the printer.
These are called _host-based_ printers.
+
Communication between the driver and a host-based printer is often through proprietary or undocumented protocols, making them functional only on the most common operating systems.

[[print-pdls-table]]
=== Converting PostScript(R) to Other PDLs

Many applications from the Ports Collection and FreeBSD utilities produce PostScript(R) output.
This table shows the utilities available to convert that into other common PDLs:

[[print-pdls-ps-to-other-tbl]]
.Output PDLs
[cols="1,1,1", frame="none", options="header"]
|===
<| Output PDL
<| Generated By
<| Notes

|`PCL` or `PCL5`
|package:print/ghostscript9-base[]
|`-sDEVICE=ljet4` for monochrome, `-sDEVICE=cljet5` for color

|`PCLXL` or `PCL6`
|package:print/ghostscript9-base[]
|`-sDEVICE=pxlmono` for monochrome, `-sDEVICE=pxlcolor` for color

|`ESC/P2`
|package:print/ghostscript9-base[]
|`-sDEVICE=uniprint`

|`XQX`
|package:print/foo2zjs[]
|
|===

[[print-pdls-summary]]
=== Summary

For the easiest printing, choose a printer that supports PostScript(R).
Printers that support `PCL` are the next preferred.
With package:print/ghostscript9-base[], these printers can be used as if they understood PostScript(R) natively.
Printers that support PostScript(R) or `PCL` directly almost always support direct printing of plain `ASCII` text files also.

Line-based printers like typical inkjets usually do not support PostScript(R) or `PCL`.
They often can print plain `ASCII` text files.
package:print/ghostscript9-base[] supports the PDLs used by some of these printers.
However, printing an entire graphic-based page on these printers is often very slow due to the large amount of data to be transferred and printed.

Host-based printers are often more difficult to set up.
Some cannot be used at all because of proprietary PDLs.
Avoid these printers when possible.

Descriptions of many PDLs can be found at http://www.undocprint.org/formats/page_description_languages[].
The particular `PDL` used by various models of printers can be found at http://www.openprinting.org/printers[].

[[printing-direct]]
== Direct Printing

For occasional printing, files can be sent directly to a printer device without any setup.
For example, a file called [.filename]#sample.txt# can be sent to a `USB` printer:

[source,shell]
....
# cp sample.txt /dev/unlpt0
....

Direct printing to network printers depends on the abilities of the printer, but most accept print jobs on port 9100, and man:nc[1] can be used with them. To print the same file to a printer with the `DNS` hostname of _netlaser_:

[source,shell]
....
# nc netlaser 9100 < sample.txt
....

[[printing-lpd]]
== LPD (Line Printer Daemon)

Printing a file in the background is called _spooling_.
A spooler allows the user to continue with other programs on the computer without waiting for the printer to slowly complete the print job.

FreeBSD includes a spooler called man:lpd[8].
Print jobs are submitted with man:lpr[1].

[[printing-lpd-setup]]
=== Initial Setup

A directory for storing print jobs is created, ownership is set, and the permissions are set to prevent other users from viewing the contents of those files:

[source,shell]
....
# mkdir -p /var/spool/lpd/lp
# chown daemon:daemon /var/spool/lpd/lp
# chmod 770 /var/spool/lpd/lp
....

Printers are defined in [.filename]#/etc/printcap#.
An entry for each printer includes details like a name, the port where it is attached, and various other settings.
Create [.filename]#/etc/printcap# with these contents:

[.programlisting]
....
lp:\				<.>
	:lp=/dev/unlpt0:\	<.>
	:sh:\			<.>
	:mx#0:\			<.>
	:sd=/var/spool/lpd/lp:\	<.>
	:lf=/var/log/lpd-errs:	<.>
....

<.> The name of this printer. man:lpr[1] sends print jobs to the `lp` printer unless another printer is specified with `-P`, so the default printer should be named `lp`.

<.> The device where the printer is connected. Replace this line with the appropriate one for the connection type shown here.

<.> Suppress the printing of a header page at the start of a print job.

<.> Do not limit the maximum size of a print job.

<.> The path to the spooling directory for this printer. Each printer uses its own spooling directory.

<.> The log file where errors on this printer will be reported.

After creating [.filename]#/etc/printcap#, use man:chkprintcap[8] to test it for errors:

[source,shell]
....
# chkprintcap
....

Fix any reported problems before continuing.

Enable man:lpd[8] in [.filename]#/etc/rc.conf#:

[.programlisting]
....
lpd_enable="YES"
....

Start the service:

[source,shell]
....
# service lpd start
....

[[printing-lpd-lpr]]
=== Printing with man:lpr[1]

Documents are sent to the printer with `lpr`.
A file to be printed can be named on the command line or piped into `lpr`.
These two commands are equivalent, sending the contents of [.filename]#doc.txt# to the default printer:

[source,shell]
....
% lpr doc.txt
% cat doc.txt | lpr
....

Printers can be selected with `-P`.
To print to a printer called _laser_:

[source,shell]
....
% lpr -Plaser doc.txt
....

[[printing-lpd-filters]]
=== Filters

The examples shown so far have sent the contents of a text file directly to the printer.
As long as the printer understands the content of those files, output will be printed correctly.

Some printers are not capable of printing plain text, and the input file might not even be plain text.

_Filters_ allow files to be translated or processed.
The typical use is to translate one type of input, like plain text, into a form that the printer can understand, like PostScript(R) or `PCL`.
Filters can also be used to provide additional features, like adding page numbers or highlighting source code to make it easier to read.

The filters discussed here are _input filters_ or _text filters_.
These filters convert the incoming file into different forms.
Use man:su[1] to become `root` before creating the files.

Filters are specified in [.filename]#/etc/printcap# with the `if=` identifier.
To use [.filename]#/usr/local/libexec/lf2crlf# as a filter, modify [.filename]#/etc/printcap# like this:

[.programlisting]
....
lp:\
	:lp=/dev/unlpt0:\
	:sh:\
	:mx#0:\
	:sd=/var/spool/lpd/lp:\
	:if=/usr/local/libexec/lf2crlf:\   <.>
	:lf=/var/log/lpd-errs:
....

<.> `if=` identifies the _input filter_ that will be used on incoming text.

[TIP]
====
The backslash _line continuation_ characters at the end of the lines in [.filename]#printcap# entries reveal that an entry for a printer is really just one long line with entries delimited by colon characters.
An earlier example can be rewritten as a single less-readable line:

[.programlisting]
....
lp:lp=/dev/unlpt0:sh:mx#0:sd=/var/spool/lpd/lp:if=/usr/local/libexec/lf2crlf:lf=/var/log/lpd-errs:
....

====

[[printing-lpd-filters-stairstep]]
==== Preventing Stairstepping on Plain Text Printers

Typical FreeBSD text files contain only a single line feed character at the end of each line.
These lines will "stairstep" on a standard printer:

[.programlisting]
....
A printed file looks
                    like the steps of a staircase
                                                 scattered by the wind
....

A filter can convert the newline characters into carriage returns and newlines.
The carriage returns make the printer return to the left after each line.
Create [.filename]#/usr/local/libexec/lf2crlf# with these contents:

[.programlisting]
....
#!/bin/sh
CR=$'\r'
/usr/bin/sed -e "s/$/${CR}/g"
....

Set the permissions and make it executable:

[source,shell]
....
# chmod 555 /usr/local/libexec/lf2crlf
....

Modify [.filename]#/etc/printcap# to use the new filter:

[.programlisting]
....
:if=/usr/local/libexec/lf2crlf:\
....

Test the filter by printing the same plain text file.
The carriage returns will cause each line to start at the left side of the page.

[[printing-lpd-filters-enscript]]
==== Fancy Plain Text on PostScript(R) Printers with package:print/enscript[]

GNUEnscript converts plain text files into nicely-formatted PostScript(R) for printing on PostScript(R) printers.
It adds page numbers, wraps long lines, and provides numerous other features to make printed text files easier to read.
Depending on the local paper size, install either package:print/enscript-letter[] or package:print/enscript-a4[] from the Ports Collection.

Create [.filename]#/usr/local/libexec/enscript# with these contents:

[.programlisting]
....
#!/bin/sh
/usr/local/bin/enscript -o -
....

Set the permissions and make it executable:

[source,shell]
....
# chmod 555 /usr/local/libexec/enscript
....

Modify [.filename]#/etc/printcap# to use the new filter:

[.programlisting]
....
:if=/usr/local/libexec/enscript:\
....

Test the filter by printing a plain text file.

[[printing-lpd-filters-ps2pcl]]
==== Printing PostScript(R) to `PCL` Printers

Many programs produce PostScript(R) documents.
However, inexpensive printers often only understand plain text or `PCL`.
This filter converts PostScript(R) files to `PCL` before sending them to the printer.

Install the Ghostscript PostScript(R) interpreter, package:print/ghostscript9-base[], from the Ports Collection.

Create [.filename]#/usr/local/libexec/ps2pcl# with these contents:

[.programlisting]
....
#!/bin/sh
/usr/local/bin/gs -dSAFER -dNOPAUSE -dBATCH -q -sDEVICE=ljet4 -sOutputFile=- -
....

Set the permissions and make it executable:

[source,shell]
....
# chmod 555 /usr/local/libexec/ps2pcl
....

PostScript(R) input sent to this script will be rendered and converted to `PCL` before being sent on to the printer.

Modify [.filename]#/etc/printcap# to use this new input filter:

[.programlisting]
....
:if=/usr/local/libexec/ps2pcl:\
....

Test the filter by sending a small PostScript(R) program to it:

[source,shell]
....
% printf "%%\!PS \n /Helvetica findfont 18 scalefont setfont \
72 432 moveto (PostScript printing successful.) show showpage \004" | lpr
....

[[printing-lpd-filters-smart]]
==== Smart Filters

A filter that detects the type of input and automatically converts it to the correct format for the printer can be very convenient.
The first two characters of a PostScript(R) file are usually `%!`.
A filter can detect those two characters.
PostScript(R) files can be sent on to a PostScript(R) printer unchanged.
Text files can be converted to PostScript(R) with Enscript as shown earlier.
Create [.filename]#/usr/local/libexec/psif# with these contents:

[.programlisting]
....
#!/bin/sh
#
#  psif - Print PostScript or plain text on a PostScript printer
#
IFS="" read -r first_line
first_two_chars=`expr "$first_line" : '\(..\)'`

case "$first_two_chars" in
%!)
    # %! : PostScript job, print it.
    echo "$first_line" && cat && exit 0
    exit 2
    ;;
*)
    # otherwise, format with enscript
    ( echo "$first_line"; cat ) | /usr/local/bin/enscript -o - && exit 0
    exit 2
    ;;
esac
....

Set the permissions and make it executable:

[source,shell]
....
# chmod 555 /usr/local/libexec/psif
....

Modify [.filename]#/etc/printcap# to use this new input filter:

[.programlisting]
....
:if=/usr/local/libexec/psif:\
....

Test the filter by printing PostScript(R) and plain text files.

[[printing-lpd-filters-othersmart]]
==== Other Smart Filters

Writing a filter that detects many different types of input and formats them correctly is challenging.
package:print/apsfilter[] from the Ports Collection is a smart "magic" filter that detects dozens of file types and automatically converts them to the `PDL` understood by the printer.
See http://www.apsfilter.org[] for more details.

[[printing-lpd-queues]]
=== Multiple Queues

The entries in [.filename]#/etc/printcap# are really definitions of _queues_.
There can be more than one queue for a single printer.
When combined with filters, multiple queues provide users more control over how their jobs are printed.

As an example, consider a networked PostScript(R) laser printer in an office.
Most users want to print plain text, but a few advanced users want to be able to print PostScript(R) files directly.
Two entries can be created for the same printer in [.filename]#/etc/printcap#:

[.programlisting]
....
textprinter:\
	:lp=9100@officelaser:\
	:sh:\
	:mx#0:\
	:sd=/var/spool/lpd/textprinter:\
	:if=/usr/local/libexec/enscript:\
	:lf=/var/log/lpd-errs:

psprinter:\
	:lp=9100@officelaser:\
	:sh:\
	:mx#0:\
	:sd=/var/spool/lpd/psprinter:\
	:lf=/var/log/lpd-errs:
....

Documents sent to `textprinter` will be formatted by the [.filename]#/usr/local/libexec/enscript# filter shown in an earlier example.
Advanced users can print PostScript(R) files on `psprinter`, where no filtering is done.

This multiple queue technique can be used to provide direct access to all kinds of printer features.
A printer with a duplexer could use two queues, one for ordinary single-sided printing, and one with a filter that sends the command sequence to enable double-sided printing and then sends the incoming file.

[[printing-lpd-monitor]]
=== Monitoring and Controlling Printing

Several utilities are available to monitor print jobs and check and control printer operation.

[[printing-lpd-monitor-lpq]]
==== man:lpq[1]

man:lpq[1] shows the status of a user's print jobs.
Print jobs from other users are not shown.

Show the current user's pending jobs on a single printer:

[source,shell]
....
% lpq -Plp
Rank   Owner      Job  Files                                 Total Size
1st    jsmith     0    (standard input)                      12792 bytes
....

Show the current user's pending jobs on all printers:

[source,shell]
....
% lpq -a
lp:
Rank   Owner      Job  Files                                 Total Size
1st    jsmith     1    (standard input)                      27320 bytes

laser:
Rank   Owner      Job  Files                                 Total Size
1st    jsmith     287  (standard input)                      22443 bytes
....

[[printing-lpd-monitor-lprm]]
==== man:lprm[1]

man:lprm[1] is used to remove print jobs.
Normal users are only allowed to remove their own jobs.
`root` can remove any or all jobs.

Remove all pending jobs from a printer:

[source,shell]
....
# lprm -Plp -
dfA002smithy dequeued
cfA002smithy dequeued
dfA003smithy dequeued
cfA003smithy dequeued
dfA004smithy dequeued
cfA004smithy dequeued
....

Remove a single job from a printer.
man:lpq[1] is used to find the job number.

[source,shell]
....
% lpq
Rank   Owner      Job  Files                                 Total Size
1st    jsmith     5    (standard input)                      12188 bytes

% lprm -Plp 5
dfA005smithy dequeued
cfA005smithy dequeued
....

[[printing-lpd-monitor-lpc]]
==== man:lpc[8]

man:lpc[8] is used to check and modify printer status.
`lpc` is followed by a command and an optional printer name.
`all` can be used instead of a specific printer name, and the command will be applied to all printers.
Normal users can view status with man:lpc[8].
Only `root` can use commands which modify printer status.

Show the status of all printers:

[source,shell]
....
% lpc status all
lp:
	queuing is enabled
	printing is enabled
	1 entry in spool area
	printer idle
laser:
	queuing is enabled
	printing is enabled
	1 entry in spool area
	waiting for laser to come up
....

Prevent a printer from accepting new jobs, then begin accepting new jobs again:

[source,shell]
....
# lpc disable lp
lp:
	queuing disabled
# lpc enable lp
lp:
	queuing enabled
....

Stop printing, but continue to accept new jobs.
Then begin printing again:

[source,shell]
....
# lpc stop lp
lp:
	printing disabled
# lpc start lp
lp:
	printing enabled
	daemon started
....

Restart a printer after some error condition:

[source,shell]
....
# lpc restart lp
lp:
	no daemon to abort
	printing enabled
	daemon restarted
....

Turn the print queue off and disable printing, with a message to explain the problem to users:

[source,shell]
....
# lpc down lp Repair parts will arrive on Monday
lp:
	printer and queuing disabled
	status message is now: Repair parts will arrive on Monday
....

Re-enable a printer that is down:

[source,shell]
....
# lpc up lp
lp:
	printing enabled
	daemon started
....

See man:lpc[8] for more commands and options.

[[printing-lpd-shared]]
=== Shared Printers

Printers are often shared by multiple users in businesses and schools.
Additional features are provided to make sharing printers more convenient.

[[printing-shared-aliases]]
==== Aliases

The printer name is set in the first line of the entry in [.filename]#/etc/printcap#.
Additional names, or _aliases_, can be added after that name.
Aliases are separated from the name and each other by vertical bars:

[.programlisting]
....
lp|repairsprinter|salesprinter:\
....

Aliases can be used in place of the printer name.
For example, users in the Sales department print to their printer with

[source,shell]
....
% lpr -Psalesprinter sales-report.txt
....

Users in the Repairs department print to _their_ printer with

[source,shell]
....
% lpr -Prepairsprinter repairs-report.txt
....

All of the documents print on that single printer.
When the Sales department grows enough to need their own printer, the alias can be removed from the shared printer entry and used as the name of a new printer.
Users in both departments continue to use the same commands, but the Sales documents are sent to the new printer.

[[printing-shared-headers]]
==== Header Pages

It can be difficult for users to locate their documents in the stack of pages produced by a busy shared printer.
_Header pages_ were created to solve this problem.
A header page with the user name and document name is printed before each print job.
These pages are also sometimes called _banner_ or _separator_ pages.

Enabling header pages differs depending on whether the printer is connected directly to the computer with a `USB`, parallel, or serial cable, or is connected remotely over a network.

Header pages on directly-connected printers are enabled by removing the `:sh:\` (Suppress Header) line from the entry in [.filename]#/etc/printcap#.
These header pages only use line feed characters for new lines.
Some printers will need the [.filename]#/usr/share/examples/printing/hpif# filter to prevent stairstepped text.
The filter configures `PCL` printers to print both carriage returns and line feeds when a line feed is received.

Header pages for network printers must be configured on the printer itself.
Header page entries in [.filename]#/etc/printcap# are ignored.
Settings are usually available from the printer front panel or a configuration web page accessible with a web browser.

[[printing-lpd-references]]
=== References

Example files: [.filename]#/usr/share/examples/printing/#.

The _4.3BSD Line Printer Spooler Manual_, [.filename]#/usr/share/doc/smm/07.lpd/paper.ascii.gz#.

Manual pages: man:printcap[5], man:lpd[8], man:lpr[1], man:lpc[8], man:lprm[1], man:lpq[1].

[[printing-other]]
== Other Printing Systems

Several other printing systems are available in addition to the built-in man:lpd[8].
These systems offer support for other protocols or additional features.

[[printing-other-cups]]
=== CUPS (Common UNIX(R) Printing System)

CUPS is a popular printing system available on many operating systems.
Using CUPS on FreeBSD is documented in a separate article: extref:{cups}[CUPS]

[[printing-other-hplip]]
=== HPLIP

Hewlett Packard provides a printing system that supports many of their inkjet and laser printers.
The port is package:print/hplip[].
The main web page is at https://developers.hp.com/hp-linux-imaging-and-printing[].
The port handles all the installation details on FreeBSD.
Configuration information is shown at https://developers.hp.com/hp-linux-imaging-and-printing/install[].

[[printing-other-lprng]]
=== LPRng

LPRng was developed as an enhanced alternative to man:lpd[8].
The port is package:sysutils/LPRng[].
For details and documentation, see http://www.lprng.com/[].