---
title: "How to Merge PDF Files on Linux Command Line (pdfunite)"
description: "Merge PDF files on Linux command line with pdfunite from poppler-utils. Covers installation, usage, alternatives (qpdf, Ghostscript), and troubleshooting."
date: 2026-07-19
categories: ["linux"]
tags: ["pdf","command-line"]
---

import Button from "@components/widgets/Button.astro";
import Notice from "@components/widgets/Notice.astro";
import ListCheck from "@components/widgets/ListCheck.astro";
import Accordion from "@components/widgets/Accordion.astro";
import Tabs from "@components/widgets/Tabs.astro";
import Tab from "@components/widgets/Tab.astro";

You can merge PDF files on Linux command line in seconds using `pdfunite` from the `poppler-utils` package. It is the fastest way to combine PDFs when you are working in a terminal, running batch scripts on a headless server, or automating document pipelines. This guide covers `pdfunite` in depth, then shows when to reach for alternatives like `qpdf` (preserves bookmarks and hyperlinks) and `Ghostscript` (compresses output). If you work with PDFs regularly from the terminal, these are [essential Linux commands](/linux-commands) to have in your toolkit.

## What is poppler-utils?

Poppler-utils is a set of command-line utilities built on the poppler PDF library (a fork of xpdf). It ships with most Linux distros and includes six tools:

<ListCheck>
<ul>
<li><strong>pdfinfo:</strong> print PDF metadata (title, author, page count, encryption status)</li>
<li><strong>pdftotext:</strong> <a href="/pdf-extract-text-linux-cmd/">converts a PDF file to plain text</a></li>
<li><strong>pdftohtml:</strong> convert PDF to HTML</li>
<li><strong>pdfimages:</strong> extract embedded images from a PDF</li>
<li><strong>pdfseparate:</strong> split a PDF into single-page files</li>
<li><strong>pdfunite:</strong> merge multiple PDF files into one</li>
</ul>
</ListCheck>

This article focuses on `pdfunite` for merging, with coverage of the other tools where they help in a merge workflow (like `pdfinfo` for verification).

## How to install poppler-utils on Linux

Poppler-utils is in the official repos of every major distro. Install it with your package manager.

<Tabs>
<Tab name="Debian / Ubuntu">
```sh
sudo apt install poppler-utils
```
</Tab>
<Tab name="RHEL / Fedora">
```sh
sudo dnf install poppler-utils
```
</Tab>
<Tab name="Arch Linux">
```sh
sudo pacman -S poppler
```
</Tab>
<Tab name="openSUSE">
```sh
sudo zypper install poppler-tools
```
</Tab>
<Tab name="Alpine">
```sh
sudo apk add poppler-utils
```
</Tab>
<Tab name="macOS (Homebrew)">
```sh
brew install poppler
```
</Tab>
</Tabs>

<Notice type="info" title="Verify installation">
Run `pdfunite --version` to confirm it is installed. On Ubuntu 24.04 LTS you will see something like:

```
pdfunite version 24.02.0
Copyright 2005-2024 The Poppler Developers - http://poppler.freedesktop.org
Copyright 1996-2011 Glyph & Cog, LLC
```

Version numbers vary by distro. Ubuntu 24.04 ships `24.02.0`, Debian sid has `26.01.0`, and the latest upstream release is `26.07.0` (July 2026). Any of these will work fine for merging PDFs.
</Notice>

## How to merge PDF files with pdfunite

### Basic syntax

The syntax is simple: list the input PDFs first, then the output filename last.

```sh
pdfunite file1.pdf file2.pdf file3.pdf output.pdf
```

This concatenates `file1.pdf`, `file2.pdf`, and `file3.pdf` in that order into `output.pdf`.

<Notice type="warning" title="Output file overwritten without warning">
pdfunite silently overwrites the output file if it already exists. There is no confirmation prompt. Double-check your output filename before running the command.
</Notice>

### Merging with wildcards

You can use shell globbing to merge all PDFs in a directory:

```sh
pdfunite *.pdf output.pdf
```

<Notice type="warning" title="Wildcard ordering trap">
The shell expands `*` alphabetically, not numerically. If your files are named `page_1.pdf`, `page_2.pdf`, ..., `page_10.pdf`, the order will be `page_1.pdf, page_10.pdf, page_2.pdf`. That is wrong.

Fix: use zero-padded filenames (`page_01.pdf`, `page_02.pdf`, ..., `page_10.pdf`) or list files explicitly.
</Notice>

### Merging from a file list

If you have a text file listing the PDFs you want to merge (one filename per line), note that `pdfunite` does **not** support reading from stdin via a `-` flag. Use command substitution instead.

**Simple approach** (works if filenames have no spaces):

```sh
pdfunite $(cat files.txt) output.pdf
```

**Safer approach** (handles filenames with spaces):

```sh
mapfile -t files < files.txt
pdfunite "${files[@]}" output.pdf
```

The `files.txt` file should contain one PDF path per line:

```
report-intro.pdf
report-chapter1.pdf
report-chapter2.pdf
report-appendix.pdf
```

### Verify the merge

After merging, check the page count to confirm all pages are present:

```sh
pdfinfo output.pdf | grep "^Pages:"
```

Compare against the sum of individual page counts:

```sh
pdfinfo file1.pdf | grep "^Pages:"
pdfinfo file2.pdf | grep "^Pages:"
pdfinfo output.pdf | grep "^Pages:"   # should equal the sum
```

Also check the file is not empty:

```sh
ls -lh output.pdf
```

## Limitations of pdfunite (what you should know)

pdfunite is fast and simple, but it concatenates PDFs at the page content level. This means:

- **Hyperlinks are lost.** Internal TOC links and cross-references break after merging.
- **Bookmarks/outlines are stripped.** PDF outlines (the sidebar navigation in viewers like Evince or Acrobat) disappear.
- **No encryption support.** You cannot merge password-protected PDFs directly.
- **No page manipulation.** You cannot rotate, reorder, or extract specific pages.
- **No compression.** The output file can be larger than expected.

<Notice type="error" title="pdfunite strips hyperlinks and bookmarks">
If your PDFs have a table of contents with clickable links or PDF outlines/bookmarks, do not use pdfunite. Use [qpdf](#qpdf--preserve-hyperlinks-and-bookmarks) instead. It preserves both.
</Notice>

For simple merges (combining invoices, scanned pages, or reports without internal links), pdfunite is the right tool. If you need bookmarks or hyperlinks to survive, switch to qpdf.

## Alternative tools for merging PDFs on Linux

When pdfunite is not enough, these three tools cover the gaps.

<Tabs>
<Tab name="qpdf">

### qpdf: preserve hyperlinks and bookmarks

qpdf is the best alternative when you need to preserve PDF structure. It handles encryption, page ranges, and keeps bookmarks and hyperlinks intact.

**Install:**

```sh
# Debian / Ubuntu
sudo apt install qpdf

# RHEL / Fedora
sudo dnf install qpdf

# Arch Linux
sudo pacman -S qpdf
```

**Merge PDFs:**

```sh
qpdf --empty --pages file1.pdf file2.pdf file3.pdf -- output.pdf
```

**Merge specific page ranges:**

```sh
# Pages 1-5 from file1, all pages from file2
qpdf --empty --pages file1.pdf 1-5 file2.pdf 1-z -- output.pdf
```

**Decrypt then merge:**

```sh
qpdf --decrypt --password=SECRET encrypted.pdf decrypted.pdf
pdfunite decrypted.pdf other.pdf merged.pdf
```

</Tab>
<Tab name="Ghostscript">

### Ghostscript: merge and compress

Ghostscript is heavier (~30 MB install) but does something no other lightweight tool does: compress PDFs during or after merging. Good for reducing file size before uploading or emailing.

**Install:**

```sh
# Debian / Ubuntu
sudo apt install ghostscript

# RHEL / Fedora
sudo dnf install ghostscript

# Arch Linux
sudo pacman -S ghostscript
```

**Merge and compress in one step:**

```sh
gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite \
   -dPDFSETTINGS=/ebook \
   -sOutputFile=merged.pdf file1.pdf file2.pdf
```

**Compress an existing PDF:**

```sh
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 \
   -dPDFSETTINGS=/ebook -dNOPAUSE -dQUIET -dBATCH \
   -sOutputFile=compressed.pdf merged.pdf
```

**PDFSETTINGS quality levels:**

| Setting | DPI | Use case |
|---|---|---|
| `/screen` | 72 | Smallest file, screen-only reading |
| `/ebook` | 150 | Good balance of size and quality |
| `/printer` | 300 | High quality for printing |
| `/prepress` | 300 | Color-preserving, largest file |

</Tab>
<Tab name="stapler">

### stapler: lightweight pdftk replacement

pdftk was removed from Fedora repos in 2019 and is hard to install on modern Ubuntu due to its gcj dependency. `stapler` is a Python-based replacement that does page-level operations.

**Install:**

```sh
# Via pip (any distro)
pip install stapler

# Fedora
sudo dnf install pdf-stapler
```

**Merge PDFs:**

```sh
stapler sel file1.pdf file2.pdf output.pdf
```

stapler also supports page selection, splitting, and other pdftk-like operations. If you need a pdftk-compatible interface without the install headaches, stapler is the tool to use.

</Tab>
</Tabs>

## Tool comparison table

| Feature | pdfunite | qpdf | Ghostscript | stapler |
|---|---|---|---|---|
| Simple merge | ✅ Best | ✅ Good | ✅ Works | ✅ Good |
| Preserve hyperlinks | ❌ | ✅ | ❌ | ✅ |
| Preserve bookmarks | ❌ | ✅ | ❌ | ✅ |
| Handle encrypted PDFs | ❌ | ✅ Best | Limited | Limited |
| Compress output | ❌ | Limited | ✅ Best | ❌ |
| Page-level ops | ❌ | ✅ | Limited | ✅ Best |
| Speed | Very fast | Fast | Slower | Fast |
| Package size | under 1 MB | ~3 MB | ~30 MB | ~14 MB |
| In modern distro repos | ✅ | ✅ | ✅ | ❌ (pdftk removed) |

<Notice type="info" title="Which tool should I use?">
Start with **pdfunite** for simple merges. It is the fastest and lightest. Switch to **qpdf** when bookmarks, hyperlinks, or encrypted PDFs matter. Use **Ghostscript** when you need to compress the output. Use **stapler** when you need pdftk-style page manipulation.
</Notice>

## Real-world workflows and automation

### Batch merge script with validation

This script validates all input files exist, merges them, and reports the page count:

```sh
#!/bin/bash
set -euo pipefail

OUTPUT="${1:-merged.pdf}"
shift

# Validate all inputs exist
for f in "$@"; do
    [[ -f "$f" ]] || { echo "ERROR: File not found: $f" >&2; exit 1; }
done

pdfunite "$@" "$OUTPUT"
echo "Created: $OUTPUT ($(pdfinfo "$OUTPUT" | grep "^Pages:" | awk '{print $2}') pages)"
```

Usage:

```sh
chmod +x merge-pdfs.sh
./merge-pdfs.sh combined-report.pdf chapter1.pdf chapter2.pdf chapter3.pdf
```

For more advanced automation workflows, you can integrate PDF processing into tools like [n8n for document processing pipelines](/n8n-self-host-workflow-automation).

### Handling encrypted PDFs

pdfunite cannot process password-protected PDFs. Decrypt them first with qpdf:

```sh
# Decrypt
qpdf --decrypt --password=THEPASS protected.pdf unprotected.pdf

# Then merge as usual
pdfunite unprotected.pdf other.pdf merged.pdf

# Clean up the decrypted file
rm unprotected.pdf
```

### Verifying the merge

Always verify after merging, especially in scripts:

```sh
# Check total page count matches sum of inputs
EXPECTED=$(pdfinfo file1.pdf | grep "^Pages:" | awk '{sum += $2} END {print sum}')
EXPECTED=$((EXPECTED + $(pdfinfo file2.pdf | grep "^Pages:" | awk '{print $2}')))
ACTUAL=$(pdfinfo output.pdf | grep "^Pages:" | awk '{print $2}')

if [[ "$EXPECTED" -eq "$ACTUAL" ]]; then
    echo "OK: $ACTUAL pages"
else
    echo "MISMATCH: expected $EXPECTED, got $ACTUAL" >&2
    exit 1
fi
```

### Keeping poppler-utils updated (security)

<Notice type="warning" title="Keep poppler-utils updated">
Poppler processes arbitrary PDF files, and it has had multiple CVEs (CVE-2026-10118, CVE-2025-52885, CVE-2025-43718, and others). If you are merging PDFs from untrusted sources, keep the package updated and consider [running CLI tools in isolated environments](/docker-podman-ai-cli-tools-safe-environment).

```sh
# Debian / Ubuntu
sudo apt update && sudo apt upgrade poppler-utils

# RHEL / Fedora
sudo dnf upgrade poppler-utils
```
</Notice>

<Button text="Automate document workflows with n8n" link="/n8n-self-host-workflow-automation" variant="outline" color="blue" />

## Troubleshooting common errors

<Accordion label="Permission denied" group="troubleshooting">

You do not have read or write permission on the PDF files.

```sh
# Check permissions
ls -l file.pdf

# Fix: give owner read+write
chmod u+rw file.pdf
```

If the files are owned by another user, you may need `sudo` or to change ownership with `chown`.

</Accordion>

<Accordion label="File not found" group="troubleshooting">

The file does not exist or the filename is wrong.

```sh
# Check your working directory
pwd

# List PDFs in the current directory
ls *.pdf

# Use tab completion to avoid typos
pdfunite file1<TAB>
```

If you are running the command in a script, use absolute paths or verify the working directory first.

</Accordion>

<Accordion label="Invalid or damaged PDF file" group="troubleshooting">

The PDF is corrupted. Unlike what some guides claim, `pdfinfo` does **not** have a `-repair` flag. Use one of these tools to attempt repair:

**With qpdf** (rebuilds the PDF structure):

```sh
qpdf --check damaged.pdf
qpdf --qdf damaged.pdf repaired.pdf
```

**With Ghostscript** (rewrites the entire PDF):

```sh
gs -o repaired.pdf -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress damaged.pdf
```

**With pdftk** (if installed):

```sh
pdftk damaged.pdf output repaired.pdf
```

If none of these work, the file is likely beyond repair. Compare file sizes with [comparing folders on the command line](/compare-folders-content-differences) if you have a backup to check against.

</Accordion>

<Accordion label="Command not found: pdfunite" group="troubleshooting">

poppler-utils is not installed. Verify:

```sh
which pdfunite
# No output = not installed
```

Go back to the [installation section](#how-to-install-poppler-utils-on-linux) and install it for your distro.

</Accordion>

<Accordion label="Memory issues with large PDFs" group="troubleshooting">

pdfunite loads full PDFs into memory. If you are merging files that are hundreds of MB each, you may run into memory pressure. Check your system resources:

```sh
# Check available memory
free -h

# Monitor swap usage
swapon --show
```

For very large files, consider Ghostscript which uses a streaming approach:

```sh
gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite \
   -dPDFSETTINGS=/prepress \
   -sOutputFile=merged.pdf large1.pdf large2.pdf
```

If you need to [monitor Linux system resources](/swap-usage-linux) during batch operations, set up alerts so you catch OOM conditions early.

</Accordion>

## Conclusion

For merging PDF files on the Linux command line, the tool you pick depends on what you need:

- **pdfunite:** default choice for simple merges. Fast, tiny, already installed on most systems.
- **qpdf:** use when bookmarks, hyperlinks, or encrypted PDFs are involved.
- **Ghostscript:** use when you need to compress the output or merge very large files.
- **stapler:** use when you need pdftk-style page manipulation.

Companion poppler tools are useful in a merge workflow: `pdfinfo` to check page counts and encryption status before merging, `pdfseparate` to split a PDF (the reverse operation), and `pdftotext` to extract text for verification.

If you run a VPS or headless server and process PDFs regularly, keep poppler-utils updated and consider [securing your Linux server](/secure-ssh-server-linux) if it handles files from external sources.

<Button text="Explore more Linux commands" link="/linux-commands" variant="outline" color="blue" />

## FAQ

<Accordion label="Can pdfunite merge password-protected PDFs?" group="faq">
No. pdfunite cannot process encrypted PDFs. Decrypt them first with qpdf:

```sh
qpdf --decrypt --password=THEPASS protected.pdf unprotected.pdf
pdfunite unprotected.pdf other.pdf merged.pdf
```
</Accordion>

<Accordion label="Does pdfunite preserve bookmarks and hyperlinks?" group="faq">
No. pdfunite concatenates page content at a low level, which strips bookmarks (outlines) and breaks internal hyperlinks. If you need these preserved, use qpdf instead:

```sh
qpdf --empty --pages file1.pdf file2.pdf -- output.pdf
```
</Accordion>

<Accordion label="What is the difference between pdfunite and qpdf?" group="faq">
pdfunite is simpler and lighter (under 1 MB, fastest). It is great for basic merges where you do not care about bookmarks or hyperlinks. qpdf is heavier (~3 MB) but preserves PDF structure, handles encrypted files, supports page ranges, and can decrypt PDFs. For most people, start with pdfunite and switch to qpdf when you hit a limitation.
</Accordion>

<Accordion label="How do I merge PDFs in a specific order?" group="faq">
List the files explicitly in the order you want:

```sh
pdfunite intro.pdf chapter1.pdf chapter2.pdf appendix.pdf output.pdf
```

If using wildcards, shell glob expansion is alphabetical: `page_1.pdf` comes before `page_10.pdf`, not `page_2.pdf`. Use zero-padded filenames (`page_01.pdf`, `page_02.pdf`, ..., `page_10.pdf`) to get correct numerical ordering.
</Accordion>