Convert PostScript and PDF Files Safely with Ghostscript

Run gs with no arguments and it tries to open a preview window rather than doing anything useful, which is most people's first surprise. Point it at a device instead and Ghostscript will render PostScript or PDF input, convert it to another format, and inspect page geometry without a desktop application in sight. This guide uses the installed Ghostscript 10.02.1 from the ghostscript package. You will convert a PostScript file to PDF, render a PDF page to PNG, and check a file's bounding box in about 10 minutes.

You need a shell, a readable input file, and enough space for the output. The examples write into a new directory below /tmp. They do not require sudo or a system service. Replace the example paths with copies of your own files before running commands on valuable data.

1. Check the installed command

Start by recording the version and the devices available in this executable. A device is Ghostscript's output driver: pdfwrite creates PDF, png16m creates colour PNG, and bbox reports geometry.

gs --version
gs -h | sed -n '1,35p'

On this machine the version is 10.02.1. The help output lists the supported input formats and devices, and it shows the default output device as x11alpha, which is exactly why an unqualified command tries to open a preview window. Explicitly choosing a device makes a script predictable.

Checkpoint: continue only if gs --version prints a version and the device you plan to use appears in gs -h.

2. Create a small input for a safe test

If you already have a test PostScript file, set input.ps to its path and skip this step. Otherwise, create a deliberately simple file in a temporary working directory. The PostScript source draws a rectangle and writes one line of text.

work=/tmp/gs-example
mkdir -p "$work"
cat > "$work/input.ps" <<'EOF'
%!PS
/Helvetica findfont 18 scalefont setfont
72 720 moveto
(Ghostscript test page) show
newpath 72 680 moveto 300 680 lineto 300 540 lineto 72 540 lineto closepath stroke
showpage
EOF

The here-document is quoted, so the shell does not expand text inside the PostScript file. This example changes only /tmp/gs-example. If you need to remove it later, inspect the path first, then run rm -rf -- /tmp/gs-example; do not substitute a broad directory.

3. Convert PostScript to PDF

Choose the pdfwrite device before naming the input. Set an explicit output file and use -dBATCH so Ghostscript exits after processing the file. -dNOPAUSE prevents page prompts in batch work, while -dSAFER keeps the installed safer mode explicit.

gs -q -dSAFER -dBATCH -dNOPAUSE \
  -sDEVICE=pdfwrite \
  -sOutputFile="$work/output.pdf" \
  "$work/input.ps"
file "$work/output.pdf"
pdfinfo "$work/output.pdf" 2>/dev/null | sed -n '1,12p' || true

Expected output from file identifies a PDF document. If pdfinfo is installed, it should report one page and the page size; Ghostscript itself does not require pdfinfo, the final command is only an optional inspection.

Warning: do not use -sOutputFile=- casually. That sends output to standard output, and the manpage warns that -q is also needed to stop diagnostic messages corrupting the stream. For one output file per page, use a template such as -sOutputFile="$work/page-%02d.pdf" where the selected device supports that output format.

4. Render a PDF page to PNG

Use png16m for a full-colour raster output. The -r150 option requests 150 pixels per inch; omit it to use the device default. The %02d part is replaced by a page number, so a multi-page document produces a numbered sequence.

gs -q -dSAFER -dBATCH -dNOPAUSE \
  -sDEVICE=png16m -r150 \
  -sOutputFile="$work/page-%02d.png" \
  "$work/output.pdf"
file "$work/page-01.png"

For the test document, file should identify a PNG image. If an image viewer is unavailable, inspect dimensions with an image utility you already trust. A large resolution or a long PDF can create many large files, so check the input page count and available disk space before rendering an untrusted document in a loop.

Destructive action: Ghostscript can overwrite an existing named output file. If you need a single-page output, use a separate empty output directory and remove old files before the run: choose a new destination or make a backup first.

5. Inspect page geometry with the bbox device

The bbox device does not make a normal document. It reports the bounding box of marks on each page, which is useful when checking EPS artwork or diagnosing unexpected margins.

gs -q -dSAFER -dBATCH -dNOPAUSE \
  -sDEVICE=bbox "$work/input.ps"

Output resembles this:

%%BoundingBox: 71 539 301 721
%%HiResBoundingBox: 71.999998 539.999983 300.239991 720.395978

The exact values depend on the input, fonts and marks. The ordinary bounding box uses integer coordinates; the high-resolution line preserves more detail. This is a diagnostic result, not a PDF or image to open.

6. Keep safer mode and file lookup in view

Ghostscript 10.02.1 enables safer mode by default, restricting the file operations available to a job. Keep that behaviour for documents you did not create yourself. The explicit -dSAFER in these examples documents the expectation and protects the command if defaults change in a wrapper.

Warning: the manpage describes -dNOSAFER and -dDELAYSAFER as ways to loosen those restrictions. Do not add either option merely to silence an error: it can let PostScript access files or perform operations that the safer policy blocks. First confirm which file is missing, whether the input is trustworthy, and whether an explicit controlled search path is enough.

Ghostscript also reads options from the GS_OPTIONS environment variable before command-line options. That can make a copied command behave differently between shells. Check it when debugging surprising device, output or security behaviour:

printf 'GS_OPTIONS=%s\n' "${GS_OPTIONS-}"
printf 'GS_DEVICE=%s\n' "${GS_DEVICE-}"
env | grep -E '^(GS_OPTIONS|GS_DEVICE|GS_FONTPATH|GS_LIB)=' || true

For unattended scripts, clear inherited settings only when you understand the surrounding environment, for example by running with a controlled environment in the service or job definition. Do not put secrets in these variables: Ghostscript's diagnostics and process environment may be visible to other users depending on the system.

7. Diagnose the common failures

Done means