grops is the GNU roff PostScript output driver, the last step between a troff document and a file a printer will actually accept. By the end of this guide you will have a PostScript file generated from a small roff document, know how to inspect it safely, and have a practical way to adjust paper format, orientation, copies and prologue selection. On this machine it comes from groff-base 1.23.0-3build2 and reports groff version 1.23.0.
Allow about 15 minutes. You need a shell, the installed groff-base package, and enough disk space for a small output file. The examples write only inside a temporary directory. No root privileges are needed.
Start by checking the exact binary and version. This catches the common distraction where a shell finds a different groff installation earlier in PATH.
command -v grops
grops --version
groff --version | head -n 1
Expected output includes /usr/bin/grops and GNU grops (groff) version 1.23.0. The driver accepts troff output, not ordinary roff source. In normal use, let groff run troff and select grops with -T ps.
Checkpoint: continue when the version is 1.23.0, or record the version you found. Options and installed font files can vary between groff releases.
Create a working directory and a short roff source file. The .TH line supplies a title, while the paragraphs provide enough visible content to identify the output later.
workdir=$(mktemp -d)
cd "$workdir"
cat > notice.roff <<'EOF'
.TH NOTICE 1 "24 September 2026" "Example"
.SH NAME
notice \- a small PostScript test document
.SH DESCRIPTION
This document checks the groff PostScript output path.
.PP
The text is deliberately plain, so failures are easier to separate from font or macro problems.
EOF
groff -T ps notice.roff > notice.ps
That command invokes grops through groff. Output goes to standard output, so the shell redirection creates notice.ps. Inspect the first lines rather than opening an untrusted PostScript file in a graphical viewer:
head -n 12 notice.ps
grep -E '^(%%Pages:|%%DocumentMedia:|%%BoundingBox:)' notice.ps
You should see a PostScript header beginning with %!PS-Adobe-3.0, DSC comments such as %%Pages:, and a one-page document. The exact comment order is an implementation detail; the useful check is that the file is non-empty, has a PostScript header and reports a page.
grops has options for output handling, but groff is normally the command you call. Pass driver options with -P. For example, make the output landscape and request two copies:
groff -T ps -P-l -P-c2 notice.roff > landscape-two-copies.ps
grep -E '^(%%Pages:|%%DocumentMedia:)' landscape-two-copies.ps
-l selects landscape orientation. -c 2 asks for two copies of each page; the compact -P-c2 form passes the option and its argument to the driver. Do not mistake copies for two pages: a copy count affects printing behaviour, while the source still contains one page.
To choose a physical medium, use -p with a format accepted by the device description. For example:
groff -T ps -P-pA4 notice.roff > a4.ps
grep -E '^(%%DocumentMedia:|%%Pages:)' a4.ps
This overrides the papersize, paperlength and paperwidth directives in the selected DESC file. If a printer or previewer rejects the result, remove the override and compare it with the default output before changing several options at once.
Check each generated file with file and a header search:
file notice.ps landscape-two-copies.ps a4.ps
for output in notice.ps landscape-two-copies.ps a4.ps; do
test -s "$output" && head -n 1 "$output"
done
If the file is empty, inspect the source and the exit status first. If the header is present but a viewer fails, the problem may be a consumer that does not support the PostScript level or DSC structure produced by this driver.
By default, grops emits PostScript LanguageLevel 2 and DSC version 3.0 output. The -b option adds compatibility workarounds as a bitmask, and the values are additive:
%! lines in included files.Use the smallest value required by the failing printer, spooler or previewer. For example, if an old consumer requires a PostScript 2.0 header:
groff -T ps -P-b8 notice.roff > legacy.ps
head -n 1 legacy.ps
Expected output starts with %!PS-Adobe-2.0. Do not use -b as a general repair switch: each bit removes information or changes compatibility behaviour.
grops finds device descriptions, font descriptions and prologue files through the groff font search path. The default PostScript device is usually named ps. A custom font directory can be placed first with -F; a custom prologue can be selected with -P:
groff -T ps -P-F -P/path/to/font-root notice.roff > custom-font-path.ps
groff -T ps -P/path/to/prologue notice.roff > custom-prologue.ps
Replace both placeholders with files you have actually installed. -F expects a directory containing the device and font layout, not merely a directory of arbitrary font files. The -P prologue argument is searched in the groff font path. The environment variable GROPS_PROLOGUE supplies a default prologue name, but an explicit -P option overrides it.
For reproducible output, set SOURCE_DATE_EPOCH to a known Unix timestamp. grops then uses it instead of the current time for the creation timestamp comment:
SOURCE_DATE_EPOCH=0 groff -T ps notice.roff > reproducible.ps
grep -m1 '^%%CreationDate:' reproducible.ps
Tip: this controls the timestamp only. Font search paths, source content and the selected groff version still need to be controlled if byte-for-byte output matters.
groff -T ps for source, or construct troff output only when you are deliberately working at the driver boundary.download list and default prologue are package data. Do not edit them in place. Use a separate font path or prologue and remove only your generated files when finished.To clean up this exercise, remove the temporary directory after checking any files you need:
cd /
rm -rf "$workdir"
Warning: this is the one destructive command in the guide. Confirm that workdir still names the temporary directory created above before running it. If you are unsure, leave the directory in place and remove it later using your system's normal temporary-file policy.
grops --version matches the installed groff release.groff -T ps generated a non-empty PostScript file with a valid header.