Safely Decompress .zst Files with unzstd

A file ending in .zst is unreadable until something decompresses it, and unzstd is the dedicated tool for that one job. You will build a repeatable way to unpack Zstandard files, check a compressed file before trusting it, and send decompressed data to another command without overwriting anything by accident. The examples match the installed zstd package, version 1.5.5+dfsg2-2build1.1. Its command reports Zstandard CLI version 1.5.7; the local manpage is dated March 2023 and describes zstd 1.5.5.

Allow about ten minutes. You need a shell, read access to the input file and write access to the destination directory. These are ordinary user commands. You do not normally need sudo: use elevated privileges only when the file permissions genuinely require it, and check the destination carefully before doing so.

1. Check the command and the input name

Confirm that the command is installed and inspect the file you intend to read:

$ unzstd --version
*** Zstandard CLI (64-bit) v1.5.7, by Yann Collet ***
$ ls -l /path/to/report.txt.zst

unzstd is the decompression form of zstd. The name implies the --decompress operation, so you do not need to add -d. A name ending in .zst is the normal input shape for the file examples below.

Checkpoint: Stop if ls shows a different file from the one you meant to process. Decompression can create a plain file with the same base name, so a typo can be confusing even when the command itself succeeds.

2. Decompress beside the source

Run unzstd with the compressed file as its argument:

$ unzstd /path/to/report.txt.zst
/path/to/report.txt.zst: 123456 bytes

By default, the output name is made by removing the .zst suffix. The result is therefore /path/to/report.txt, while the original report.txt.zst remains in place. The source-preserving behaviour is the default and is equivalent to using -k or --keep.

If the destination already exists, the command asks before replacing it. Answering no leaves the existing destination untouched. Do not add -f merely to silence that question: -f forces overwriting and also disables several input and output safety checks.

Checkpoint: Verify both the restored file and the retained archive:

$ ls -l /path/to/report.txt /path/to/report.txt.zst
$ file /path/to/report.txt

3. Choose the output path explicitly

Use -o when the derived name is inconvenient or the restored data belongs in another directory:

$ unzstd -o /tmp/report-restored.txt /path/to/report.txt.zst
/path/to/report.txt.zst: 123456 bytes
$ test -s /tmp/report-restored.txt
$ printf '%s\n' "$?"
0

The output path is a real state change: it creates or replaces a file. If the target already exists, omit -f until you have checked it. With an explicit output path, -f permits replacement without the confirmation prompt. Treat that combination as destructive because it can discard the previous target.

There is no need for elevated privileges when writing under a directory you own, such as a temporary working directory or your home directory. If a service directory is the intended destination, inspect the path first and use the host's normal deployment process rather than copying a random archive into it as root.

4. Test integrity without restoring a file

Use -t or --test when you need to check the compressed data before extracting it:

$ unzstd -t /path/to/report.txt.zst
/path/to/report.txt.zst: 123456 bytes
$ printf '%s\n' "$?"
0

Test mode decompresses and checks the data but discards the result. It creates no output file and removes no input file. A zero status means this integrity check completed successfully. A non-zero status means the archive should not be treated as a valid restored file; keep the diagnostic and obtain a fresh copy or investigate the transfer before retrying.

Do not use ls alone as an integrity check. It only proves that a directory entry exists. The checksum stored in the Zstandard frame is checked by -t, which is the useful pre-flight operation for an archive received from another system.

5. Stream the result to another command

Use -c or --stdout when you want bytes on standard output and no restored file:

$ unzstd -c /path/to/report.txt.zst | less

This keeps the source unchanged and is useful for logs, text searches and pipelines. For example, search a compressed log without creating a plain copy:

$ unzstd -c /var/log/example.log.zst | rg 'timeout|failed'

For a file supplied through standard input, use - as the input name:

$ curl -fsS https://example.invalid/archive.zst | unzstd -c - > /tmp/archive.txt

The URL above is a placeholder, not a command to run as written. Replace it with a trusted source and consider saving the archive first if you need to verify its origin or retry the operation. Never send untrusted decompressed output into a command interpreter. A pipeline changes where the bytes go, but it does not make their content safe.

6. Handle several archives carefully

You can pass several input files to one invocation:

$ unzstd /path/to/january.txt.zst /path/to/february.txt.zst

Each archive is decompressed according to its own name. If you use a shell wildcard, inspect what it expands to first:

$ printf '%s\n' /path/to/reports/*.zst
$ unzstd /path/to/reports/*.zst

Recursive processing with -r includes files below a directory. That can be convenient, but it also widens the set of files being read and the set of destinations that may be created. Prefer an explicit list until you have checked the directory contents.

7. Remove the archive only after checking the result

The --rm option removes each source after successful decompression. It is destructive and is ignored when output is sent to standard output:

$ unzstd --rm /path/to/report.txt.zst
/path/to/report.txt.zst: 123456 bytes

Before using it, confirm that the restored file is readable and complete. If you combine --rm with -o, zstd asks for confirmation because the source removal is destructive. Adding -f suppresses that prompt, so do not use both flags in a script unless the deletion and overwrite policy is deliberate.

There is no undo command for a source file removed by --rm. Recovery means obtaining another copy from backup or the system that supplied the archive. The safer workflow is to keep the archive until a separate backup or application-level check confirms the restored file.

Done means