Extract Selected Files from a SquashFS Image with sqfscat

Need one file out of a SquashFS image without mounting the thing or unpacking the whole archive? sqfscat prints it straight to standard output. Examples use Squashfs-tools 4.6.1, package version 1:4.6.1-1build1.

Ten minutes. You need a readable SquashFS image and a Linux shell. Reading an image and writing to your working directory normally need no elevated privileges; use sudo only when ordinary permissions block you, never as a fix for a wrong path.

1. Confirm the installed command

Check the executable and record its version, both ordinary read-only commands:

$ command -v sqfscat
/usr/bin/sqfscat
$ dpkg-query -W -f='${Package} ${Version}\n' squashfs-tools
squashfs-tools 1:4.6.1-1build1
$ sqfscat -version
sqfscat version 4.6.1 (2023/03/25)

The general shape is sqfscat [OPTIONS] FILESYSTEM [files]: an image, then a list of paths. It writes the selected contents to standard output with no filename, separator or newline between multiple files, so stick to one file at a time whenever the output needs to stay unambiguous.

Checkpoint: if command -v finds nothing, install Squashfs-tools through your normal package process before continuing. Nothing here touches packages.

2. Print one known file

Image path first, path inside the image second. This example uses a path relative to the image root:

$ sqfscat /path/to/image.sqfs etc/issue
<the exact contents of etc/issue in your image>

The output is raw bytes straight to your terminal, so its contents depend entirely on the image you supply. Text files are convenient for a first check, but the command happily emits binary data too. For anything binary, redirect to a file rather than dumping it into a terminal.

Quote any path with spaces or shell metacharacters:

$ sqfscat /path/to/image.sqfs 'opt/example file.txt'

Do not reach for sudo unless the image or destination is genuinely protected. Denied access? Check permissions first:

$ ls -l /path/to/image.sqfs
$ test -r /path/to/image.sqfs && echo readable

3. Select several files with a quoted wildcard

By default sqfscat matches filenames inside the image with shell-style wildcards. Quote the pattern so your own shell does not expand it first:

$ sqfscat /path/to/image.sqfs '*.[ch]'
/* contents of matching .c and .h files, concatenated */

The pattern matches names inside the image, not files in your current directory. It can pull in hello.c and hello.h from the image root, concatenated with no marker between them. Need to know which file produced which bytes? Run separate commands, or use a tool that records names as it extracts.

Add -no-wildcards (also -no-wild) to treat wildcard characters literally:

$ sqfscat -no-wildcards /path/to/image.sqfs 'literal*name'

That option only changes sqfscat's own matching, not the shell's, which is why quoting stays the safe habit regardless.

4. Use a POSIX regular expression when you need more control

Use -regex to have filenames interpreted as POSIX regular expressions instead of the default wildcards:

$ sqfscat -regex /path/to/image.sqfs 'logs/[0-9][0-9][0-9][0-9]-[0-9][0-9]\.log'
/* contents of matching monthly log files */

Quote it for the same reason as a wildcard; in that example the backslash reaches sqfscat and makes the dot literal. Keep expressions narrow when the image holds a lot of files, since every match adds bytes to the same standard-output stream. Do not confuse -no-wildcards with -regex: one disables wildcard matching, the other switches to a different matching language entirely.

5. Save output without destroying an existing file

Redirect standard output for a reusable copy:

$ sqfscat /path/to/image.sqfs etc/issue > extracted-issue.txt
$ test -s extracted-issue.txt && echo 'extracted-issue.txt is non-empty'

Warning: shell redirection truncates an existing destination before sqfscat even runs, and that loss is permanent if the old file held something useful. Pick a new name, or write to a temporary one and replace the destination only after checking it:

$ sqfscat /path/to/image.sqfs etc/issue > extracted-issue.txt.new
$ test -s extracted-issue.txt.new
$ mv extracted-issue.txt.new extracted-issue.txt

If extraction fails, leave the old destination alone and read the error. Only remove the incomplete .new file once you have confirmed it is disposable.

6. Read the exit status before trusting the result

sqfscat has three status classes worth knowing:

Capture the status right after the command runs:

$ sqfscat /path/to/image.sqfs missing-file > /tmp/missing-output
cat: no matches for /missing
$ status=$?
$ printf 'sqfscat status: %s\n' "$status"
sqfscat status: 2

Status 2 matters in scripts: it is not licence to treat a partial multi-file result as complete. Check every requested path, or use -strict-errors to make any error fatal:

$ sqfscat -strict-errors /path/to/image.sqfs present missing-file > extracted.txt
$ printf 'sqfscat status: %s\n' "$?"
sqfscat status: 2

Only use -ignore-errors when failed writes to standard output are genuinely meant to be non-fatal. -no-exit-code suppresses non-zero status for non-fatal errors, which makes it a poor fit for any automation that needs reliable failure detection.

7. Use offsets only for embedded images

A normal SquashFS image starts at offset zero. If the filesystem is embedded in another file, pass the byte offset with -offset or -o; suffixes K, M and G are all accepted:

$ sqfscat -offset 4M /path/to/container.bin etc/issue

Never guess an offset. Confirm it from the image format or whatever tool created the container. A wrong offset just looks like a corrupt filesystem and burns time on the wrong problem. The default is zero bytes.

Done means