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 lpd(8). Print jobs are submitted with lpr(1).
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:
#mkdir -p /var/spool/lpd/lp#chown daemon:daemon /var/spool/lpd/lp#chmod 770 /var/spool/lpd/lp
Printers are defined in
	/etc/printcap.  An entry for each printer
	includes details like a name, the port where it is attached,
	and various other settings.  Create
	/etc/printcap with these contents:
lp:\:lp=/dev/unlpt0:\
:sh:\
:mx#0:\
:sd=/var/spool/lpd/lp:\
:lf=/var/log/lpd-errs:
The name of this printer.  lpr(1) sends print
	    jobs to the   | |||||||||||
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 /etc/printcap, use
	chkprintcap(8) to test it for errors:
#chkprintcap
Fix any reported problems before continuing.
Enable lpd(8) in
	/etc/rc.conf:
lpd_enable="YES"
Start the service:
#service lpd start
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
	doc.txt to the default printer:
%lpr doc.txt%cat doc.txt | lpr
Printers can be selected with -P.  To
	print to a printer called
	laser:
%lpr -Plaser doc.txt
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® 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 su(1) to become
	root before
	creating the files.
Filters are specified in
	/etc/printcap with the
	if= identifier.  To use
	/usr/local/libexec/lf2crlf as a filter,
	modify /etc/printcap like this:
lp:\ :lp=/dev/unlpt0:\ :sh:\ :mx#0:\ :sd=/var/spool/lpd/lp:\ :if=/usr/local/libexec/lf2crlf:\:lf=/var/log/lpd-errs:
The backslash line continuation
	  characters at the end of the lines in
	  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:
lp:lp=/dev/unlpt0:sh:mx#0:sd=/var/spool/lpd/lp:if=/usr/local/libexec/lf2crlf:lf=/var/log/lpd-errs:
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:
A printed file looks
                    like the steps of a staircase
                                                 scattered by the windA 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
	  /usr/local/libexec/lf2crlf with these
	  contents:
#!/bin/sh
CR=$'\r'
/usr/bin/sed -e "s/$/${CR}/g"Set the permissions and make it executable:
#chmod 555 /usr/local/libexec/lf2crlf
Modify /etc/printcap to use the
	  new filter:
: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.
GNU Enscript converts plain text files into nicely-formatted PostScript® for printing on PostScript® 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 print/enscript-letter or print/enscript-a4 from the Ports Collection.
Create /usr/local/libexec/enscript
	  with these contents:
#!/bin/sh /usr/local/bin/enscript -o -
Set the permissions and make it executable:
#chmod 555 /usr/local/libexec/enscript
Modify /etc/printcap to use the
	  new filter:
:if=/usr/local/libexec/enscript:\
Test the filter by printing a plain text file.
Many programs produce PostScript® documents. However, inexpensive printers often only understand plain text or PCL. This filter converts PostScript® files to PCL before sending them to the printer.
Install the Ghostscript PostScript® interpreter, print/ghostscript9-base, from the Ports Collection.
Create /usr/local/libexec/ps2pcl
	  with these contents:
#!/bin/sh /usr/local/bin/gs -dSAFER -dNOPAUSE -dBATCH -q -sDEVICE=ljet4 -sOutputFile=- -
Set the permissions and make it executable:
#chmod 555 /usr/local/libexec/ps2pcl
PostScript® input sent to this script will be rendered and converted to PCL before being sent on to the printer.
Modify /etc/printcap to use this
	  new input filter:
:if=/usr/local/libexec/ps2pcl:\
Test the filter by sending a small PostScript® program to it:
%printf "%%\!PS \n /Helvetica findfont 18 scalefont setfont \ 72 432 moveto (PostScript printing successful.) show showpage \004" | lpr
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® file are usually %!.  A
	  filter can detect those two characters.  PostScript® files
	  can be sent on to a PostScript® printer unchanged.  Text
	  files can be converted to PostScript® with
	  Enscript as shown earlier.
	  Create /usr/local/libexec/psif with
	  these contents:
#!/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
    ;;
esacSet the permissions and make it executable:
#chmod 555 /usr/local/libexec/psif
Modify /etc/printcap to use this
	  new input filter:
:if=/usr/local/libexec/psif:\
Test the filter by printing PostScript® and plain text files.
Writing a filter that detects many different types of input and formats them correctly is challenging. 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.
The entries in /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® laser
	printer in an office.  Most users want to print plain text,
	but a few advanced users want to be able to print PostScript®
	files directly.  Two entries can be created for the same
	printer in /etc/printcap:
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
	/usr/local/libexec/enscript filter shown
	in an earlier example.  Advanced users can print PostScript®
	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.
Several utilities are available to monitor print jobs and check and control printer operation.
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:
%lpq -PRank Owner Job Files Total Size 1st jsmith 0 (standard input) 12792 byteslp
Show the current user's pending jobs on all printers:
%lpq -alp: 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
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:
#lprm -PdfA002smithy dequeued cfA002smithy dequeued dfA003smithy dequeued cfA003smithy dequeued dfA004smithy dequeued cfA004smithy dequeuedlp-
Remove a single job from a printer. lpq(1) is used to find the job number.
%lpqRank Owner Job Files Total Size 1st jsmith 5 (standard input) 12188 bytes%lprm -PdfA005smithy dequeued cfA005smithy dequeuedlp5
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
	  lpc(8).  Only
	  root can use
	  commands which modify printer status.
Show the status of all printers:
%lpc status alllp: 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:
#lpc disablelp: queuing disabledlp#lpc enablelp: queuing enabledlp
Stop printing, but continue to accept new jobs. Then begin printing again:
#lpc stoplp: printing disabledlp#lpc startlp: printing enabled daemon startedlp
Restart a printer after some error condition:
#lpc restartlp: no daemon to abort printing enabled daemon restartedlp
Turn the print queue off and disable printing, with a message to explain the problem to users:
#lpc downlp: printer and queuing disabled status message is now: Repair parts will arrive on MondaylpRepair parts will arrive on Monday
Re-enable a printer that is down:
#lpc uplp: printing enabled daemon startedlp
See lpc(8) for more commands and options.
Printers are often shared by multiple users in businesses and schools. Additional features are provided to make sharing printers more convenient.
The printer name is set in the first line of the
	  entry in /etc/printcap.  Additional
	  names, or aliases, can be added after
	  that name.  Aliases are separated from the name and each
	  other by vertical bars:
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
%lpr -Psalesprintersales-report.txt
Users in the Repairs department print to their printer with
%lpr -Prepairsprinterrepairs-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.
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 /etc/printcap.
	  These header pages only use line feed characters for new
	  lines.  Some printers will need the
	  /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
	  /etc/printcap are ignored.  Settings
	  are usually available from the printer front panel or a
	  configuration web page accessible with a web browser.
All FreeBSD documents are available for download at https://download.freebsd.org/ftp/doc/
Questions that are not answered by the
    documentation may be
    sent to <freebsd-questions@FreeBSD.org>.
    Send questions about this document to <freebsd-doc@FreeBSD.org>.