Home / Alt manpages / pdfdetach(1)

  • pdfdetach(1)
  • User command
  • linux

Extract Embedded Files from PDFs with pdfdetach

You will list and extract attachments embedded in a PDF without opening the document in a graphical viewer. The guide uses pdfdetach from Poppler 24.02.0, installed here as poppler-utils 24.02.0-1ubuntu9.9. Allow about ten minutes if you already have the PDF and know where the extracted files should go.

You need a readable PDF, a shell and the poppler-utils package. These commands normally run as your ordinary user. Do not use sudo merely because the PDF came from someone else. If you need to read a protected directory, copy the PDF to a working directory you own instead.

1. Check the installed command

Confirm which executable will run and record its version. This is a read-only checkpoint:

$ command -v pdfdetach
/usr/bin/pdfdetach
$ pdfdetach -v
pdfdetach version 24.02.0
$ dpkg-query -W -f='${Package} ${Version}\n' poppler-utils
poppler-utils 24.02.0-1ubuntu9.9

The local manual page describes itself as version 3.03, while the installed binary reports Poppler 24.02.0. Use the executable's version when comparing behaviour with another machine. The option names used below are present in both the local manual and the installed help output.

2. List the embedded files

Start with a list. Replace /path/to/document.pdf with the actual file, and keep the path quoted if it contains spaces:

$ pdfdetach -list '/path/to/document.pdf'
1 embedded file
  1: notes.txt
  2: source-data.csv

The names and exact formatting are document-dependent. Treat the numbers as the useful part of the listing: -save selects by number, while -savefile selects by the embedded file name. The command does not extract anything during this step.

Checkpoint: if the command exits successfully, repeat the list with an explicit status check:

$ pdfdetach -list '/path/to/document.pdf'
$ printf 'exit status: %s\n' "$?"
exit status: 0

Run printf immediately after pdfdetach. A later command would replace the status you are checking.

3. Extract one attachment by number

Use the number shown by -list. By default, -save uses the embedded file name as the output name in the current directory:

$ mkdir -p /tmp/pdfdetach-work
$ cd /tmp/pdfdetach-work
$ pdfdetach -save 1 '/path/to/document.pdf'
$ ls -l -- notes.txt
-rw-r--r-- 1 andy andy 1842 Sep 25 12:00 notes.txt

The size, owner and timestamp in ls will differ on your machine. The useful check is that the expected file exists and is non-empty. For a text attachment, inspect it without executing anything:

$ file -- notes.txt
notes.txt: ASCII text
$ sed -n '1,12p' -- notes.txt

Do not trust an attachment just because it has a familiar name or extension. Treat extracted files as untrusted input. Scan them with your usual tools before opening or running them.

4. Choose a different output name

Use -o with -save when you want a controlled destination name. This also makes the output easier to identify in an automated job:

$ pdfdetach -save 2 -o '/tmp/pdfdetach-work/data.csv' '/path/to/document.pdf'
$ test -s '/tmp/pdfdetach-work/data.csv'
$ printf 'extracted: %s\n' "$?"
extracted: 0

With a single-file save, -o is the file name to use. It is not a directory selector in this form. Do not confuse the number with a shell positional argument: -save 2 means attachment number 2, not a file called 2.

Warning: choose a new destination when an existing file matters. An output command can replace a file at the path you provide. If you accidentally wrote the wrong attachment over a useful file, pdfdetach has no undo facility; restore that file from your backup or snapshot.

5. Extract every attachment into a clean directory

-saveall writes every embedded file, using the names reported by -list. Pass a directory with -o:

$ mkdir -p /tmp/pdfdetach-work/all
$ pdfdetach -saveall -o /tmp/pdfdetach-work/all '/path/to/document.pdf'
$ find /tmp/pdfdetach-work/all -maxdepth 1 -type f -printf '%f\n' | sort
notes.txt
source-data.csv

The default directory is the current directory, so omitting -o is easy to get wrong. A clean, disposable directory keeps the extracted names away from unrelated files and makes the result easy to review. The command uses names supplied by the PDF; inspect the output directory after extraction and do not blindly pass every result to another program.

There is no elevated-privilege step here. If a destination is not writable, fix the path or its ownership deliberately rather than running the whole extraction as root.

6. Select by embedded file name

If a PDF is regenerated and attachment numbers may move, -savefile can select the name printed by -list:

$ pdfdetach -savefile 'source-data.csv' \
    -o '/tmp/pdfdetach-work/source-data.csv' \
    '/path/to/document.pdf'
$ file -- '/tmp/pdfdetach-work/source-data.csv'

Use the embedded name exactly as listed, including case and punctuation. A name that looks like a path is still input supplied by the document, so prefer an explicit -o path and a directory you have checked. If the name is ambiguous or the command reports that it cannot find it, return to -list and copy the displayed name rather than guessing.

7. Handle passwords and failures

For an encrypted PDF, -upw supplies the user password and -opw supplies the owner password:

$ pdfdetach -list -upw 'USER_PASSWORD' '/path/to/encrypted.pdf'
$ printf 'exit status: %s\n' "$?"
exit status: 0

Do not paste a real password into a shared terminal, shell history or a script. The local manual says that an owner password bypasses all PDF security restrictions, so handle -opw as a security-sensitive operation and use it only when you are authorised to do so. A password does not make an untrusted attachment safe.

The documented exit statuses help separate causes:

  • 0: no error.
  • 1: the PDF could not be opened.
  • 2: an output file could not be opened.
  • 3: a PDF permission error occurred.
  • 99: another error occurred.

For example, a missing input is an input-path problem, not a reason to retry with sudo:

$ pdfdetach -list /tmp/does-not-exist.pdf
I/O Error: Couldn't open file '/tmp/does-not-exist.pdf': No such file or directory.
$ printf 'exit status: %s\n' "$?"
exit status: 1

Check the path with ls -l, check readability with test -r, and check the destination with test -w. Keep the original PDF until the extracted files have passed your inspection.

Done means

  • pdfdetach -list showed which attachments were present and returned status 0.
  • You selected the intended attachment by its listed number or exact name.
  • Single-file output used an explicit destination, and all-file output used a clean directory.
  • The extracted files exist, have sensible sizes and types, and were treated as untrusted input.
  • Any failure was classified by its exit status, with the original PDF left untouched.