Home / Alt manpages / pnmfile(1)

  • pnmfile(1)
  • User command
  • linux

Replace pnmfile with pamfile for dependable Netpbm image checks

You will finish with a verified way to inspect PBM, PGM, PPM and PAM files, plus a safe migration path from the obsolete pnmfile command to pamfile. The checks below use Netpbm 11.5.2, installed here as Debian package netpbm 2:11.05.02-1.1build1.

Allow about fifteen minutes. You need a shell, Netpbm installed, and an image file that you are willing to inspect. Every command in this guide is read-only apart from creating a temporary sample under /tmp. No elevated privileges are required.

1. Confirm which command you have

The installed pnmfile is a compatibility command, not the current name for new work. Its local manual says that Netpbm replaced it with pamfile in Netpbm 10.9 in September 2002. The replacement is backward compatible with PNM files and also handles PAM images.

Check both binaries and the installed library version:

$ command -v pnmfile
/usr/bin/pnmfile
$ command -v pamfile
/usr/bin/pamfile
$ pnmfile --version 2>&1 | head -1
pnmfile: Using libnetpbm from Netpbm Version: Netpbm 11.5.2
$ dpkg-query -W -f='${Package} ${Version}\n' netpbm
netpbm 2:11.05.02-1.1build1

The version line is diagnostic output from this Debian build. It is useful evidence about the library in use, but it is not a promise that every Netpbm package uses the same packaging version.

Checkpoint

If pamfile is missing, do not silently change a script to another image utility. Install or update Netpbm through your normal package-management process, then rerun this check. Do not use sudo for an inspection command that already works as your user.

2. Inspect one existing image with pnmfile

Pass a file name to pnmfile. It reads the header and prints the format, dimensions and maximum sample value:

$ pnmfile /path/to/image.ppm
/path/to/image.ppm:  PPM raw, 1920 by 1080  maxval 255

Your format may be PBM, PGM or PAM, and the subformat may be plain or raw. The spacing and wording are intended for people, not for a stable parser. A successful description tells you what the header declares; it does not validate every pixel in a large file.

pnmfile accepts several file names and labels each result. It also accepts standard input when no file name is supplied:

$ pnmfile first.ppm second.pgm
first.ppm:  PPM raw, 1920 by 1080  maxval 255
second.pgm:  PGM plain, 800 by 600  maxval 65535
$ pnmfile < image.ppm
stdin:  PPM raw, 1920 by 1080  maxval 255

If the input is missing or is not a Netpbm image, the command reports an error and returns a non-zero status. Keep that status in scripts:

if description=$(pnmfile --quiet -- "$image_path"); then
    printf '%s\n' "$description"
else
    status=$?
    printf 'Not a readable Netpbm image: %s (status %s)\n' "$image_path" "$status" >&2
    exit "$status"
fi

The -- separator makes the file name boundary clear. Quote the variable so whitespace and shell metacharacters in a path are not interpreted. The common --quiet option suppresses normal output, so omit it when you need the description.

3. Switch the normal workflow to pamfile

For a direct replacement, use the same file arguments with pamfile:

$ pamfile /path/to/image.ppm
/path/to/image.ppm:  PPM raw, 1920 by 1080  maxval 255

It produces the same kind of human-readable description, but its documented options cover the cases that commonly lead to fragile shell parsing. The default still examines only the first image in a file. That is normally the right choice for a quick header check.

Use --allimages when a file may contain multiple concatenated images and you need to inspect every one:

$ pamfile --allimages /path/to/possibly-multiple.ppm
/path/to/possibly-multiple.ppm:  PPM raw, 1920 by 1080  maxval 255
/path/to/possibly-multiple.ppm:  PPM raw, 640 by 480  maxval 255

This option consumes the complete input stream. That matters when the input is a pipe: the process feeding the pipe may otherwise wait because the checker only reads the first header.

4. Use machine output in scripts

Do not split the ordinary description on spaces if a script needs dimensions. Ask pamfile for a defined machine-oriented format instead:

$ pamfile --machine /path/to/image.ppm
/path/to/image.ppm: PPM RAW 1920 1080 3 255 RGB
$ pamfile --size /path/to/image.ppm
1920 1080
$ pamfile --count /path/to/image.ppm
/path/to/image.ppm:  1 images

--machine includes the file name, format, plain or raw subformat, width, height, depth, maximum value and tuple type. It is the safer choice when several input files or several images must be associated with their metadata. --size returns only width and height, so it loses that association when you process multiple files. --count reports how many images are present.

You may use at most one of --machine, --size and --count. These are inspection modes, not conversion modes: no image is resized, rewritten or deleted.

5. Handle pipes and failures deliberately

A header-only check is quick, but it does not prove that a truncated image contains all its declared pixel data. If you need the checker to consume every image from a pipe, use --allimages or --count. If you need full data validation, follow the check with an appropriate decoder or converter and test that tool's exit status separately.

Test a failure without touching a real image by pointing the command at a known missing path:

$ pamfile --machine /path/that/does/not/exist
pamfile: Unable to open file '/path/that/does/not/exist' for reading. fopen() returns errno 2 (No such file or directory)
$ printf 'exit status: %s\n' "$?"
exit status: 1

The exact diagnostic can vary with the platform and library. The useful signals are that an error was written and the status was non-zero. Check the path and permissions before reaching for elevated privileges. Do not overwrite an input merely to make a test pass.

Done means

  • You confirmed that the host uses Netpbm 11.5.2 and has both commands available.
  • You know that pnmfile is retained for compatibility and pamfile is the replacement.
  • You can inspect one file, multiple files or standard input without modifying image data.
  • New scripts use --machine, --size or --count instead of parsing human-oriented spacing.
  • Pipe consumers use --allimages or --count when the complete stream must be read.
  • Failures are checked through the exit status, and no command required root access.