Normalise PostScript Safely with ps2ps and eps2eps
You will finish with a repeatable way to turn a PostScript or PDF input into simpler, normalised PostScript, or into an Encapsulated PostScript file when that is the format you need. The commands are wrappers around Ghostscript's ps2write and eps2write devices, so the result is regenerated output rather than a small edit to the original file.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes for a first conversion and a basic inspection. You need the ghostscript package and a readable input file. The examples below use Ghostscript 10.02.1, installed here as package version 10.02.1~dfsg1-0ubuntu7.9. Other releases can produce different serialisation details, so check the installed version before comparing files byte for byte.
1. Check the installed commands
Start with read-only checks. Neither command needs elevated privileges when the input and destination are in directories you can access:
$ command -v ps2ps eps2eps gs
/usr/bin/ps2ps
/usr/bin/eps2eps
/usr/bin/gs
$ gs --version
10.02.1
$ dpkg-query -W -f='${Package} ${Version}\n' ghostscript
ghostscript 10.02.1~dfsg1-0ubuntu7.9
Checkpoint: the commands must resolve to the installation you intend to use. If command -v finds a private wrapper earlier in PATH, inspect that wrapper before trusting its behaviour.
2. Choose the output format and destination
Use ps2ps INPUT OUTPUT.ps for ordinary PostScript output. The manpage describes the result as level 2, DSC 3.0 conforming PostScript. Use eps2eps INPUT OUTPUT.eps when another application expects an Encapsulated PostScript file.
Despite its name, eps2eps does not require an EPS input. The installed manpage says that PostScript and PDF input are also accepted. EPS output has stricter boundaries: it is intended to be imported as a single black-box graphic, and the EPS writer produces a single-page DSC-conforming file. Do not choose EPS merely because the source file happens to have a convenient extension.
Before you run either command, choose a new destination path. These tools open the output path for writing, so a typo or an output path naming the source can destroy the only copy you have. Make a backup or work in a new directory before processing irreplaceable artwork. There is no undo operation provided by ps2ps or eps2eps; recovery means restoring your backup or regenerating the destination from the original.
3. Convert PostScript to normalised PostScript
Run the command with exactly two non-option arguments: the input followed by the output. This example keeps the source untouched and creates a sibling file with a deliberately different name:
$ ps2ps ./diagram.ps ./diagram-normalised.ps
A successful run normally returns to the shell without a progress report because the wrapper asks Ghostscript to run quietly. Verify both the exit status and the output header:
$ printf 'exit status: %s\n' "$?"
exit status: 0
$ sed -n '1,12p' ./diagram-normalised.ps
%!PS-Adobe-3.0
%%Invocation: path/gs ...
%%BoundingBox: ...
%%Creator: GPL Ghostscript 10021 (ps2write)
%%LanguageLevel: 2
The exact invocation line, bounding box, creation date and byte count vary. The useful checks are the PostScript header, the level 2 declaration and the fact that the file is non-empty. A zero exit status means Ghostscript completed the conversion; it does not prove that every downstream application will accept the output.
4. Convert to EPS when a single imported graphic is required
Use the alias for an EPS destination:
$ eps2eps ./diagram.ps ./diagram.eps
$ printf 'exit status: %s\n' "$?"
exit status: 0
$ sed -n '1,10p' ./diagram.eps
%!PS-Adobe-3.0 EPSF-3.0
%%Invocation: path/gs ...
%%BoundingBox: ...
%%Creator: GPL Ghostscript 10021 (eps2write)
%%LanguageLevel: 2
Look for the EPSF-3.0 header and a useful %%BoundingBox. The box is calculated from the converted page content, so it can differ from the page-sized bounding box produced by ps2ps. If the output is empty, clipped or unexpectedly large, inspect the source's page setup and drawing coordinates rather than assuming that changing the file extension will fix it.
5. Use a Ghostscript option only when the source needs it
Both wrappers accept general Ghostscript command-line options and options for their selected output device. The installed usage message gives paper size as a concrete example:
$ ps2ps -sPAPERSIZE=a4 ./input.ps ./input-a4.ps
Keep options before the two file names. Start without extra switches, then add one option at a time when the input or consuming application requires it. This makes a changed bounding box or page size attributable to a specific setting. Use gs -h to see the installed device list and the local Ghostscript documentation path.
The wrappers already invoke Ghostscript with quiet, batch and non-interactive settings. They also enable -dSAFER and disable the traditional PostScript search behaviour with -P-. Do not treat those defaults as a complete security review of hostile files. Conversion still interprets the input, and a file from an untrusted source should be handled in an isolated account or disposable environment where practical.
6. Diagnose failures without guessing
First check the command shape. Omitting either file name produces a usage message and status 1:
$ ps2ps
Usage: ps2ps [options] input.ps output.ps
e.g. ps2ps -sPAPERSIZE=a4 input.ps output.ps
$ printf 'exit status: %s\n' "$?"
exit status: 1
If the command reports that it cannot read the input, check the exact path and ordinary filesystem permissions. If it cannot create the output, check the destination directory, free space and whether the file is already open by another process. Use sudo only when the directory's access policy genuinely requires it; elevated privileges do not repair malformed PostScript or make a missing file appear.
For a malformed or unsupported document, preserve the original error text and retry with a copy in a temporary directory. Do not repeatedly overwrite the same destination while experimenting. If the conversion succeeds but the result renders incorrectly, compare the output in the target application and retain the source so you can try a narrower option change.
Done means
- You confirmed the installed Ghostscript and wrapper versions.
- You selected
ps2psfor normalised PostScript oreps2epsfor an imported EPS graphic. - You wrote to a new destination and kept the source as a recovery copy.
- The command returned status 0 and the output header matches the selected format.
- You used extra Ghostscript options only for a demonstrated input or output requirement.
- You can distinguish a command-line, filesystem or document-content failure before reaching for elevated privileges.