Home / Alt manpages / grub-fstest(1)

  • grub-fstest(1)
  • User command
  • linux

Read Files Inside a Disk Image with grub-fstest

When you need to know what GRUB actually sees inside a filesystem image, grub-fstest reads it directly, with no mount needed. It can list a directory, read a file, compare it with a local copy, calculate a CRC32 value, show hexadecimal bytes and copy the file out.

Allow about fifteen minutes. You need the grub-common package, a filesystem image that GRUB can read, and read access to that image. This guide uses the installed Ubuntu build, grub-fstest 2.12-1ubuntu7.3. The command is a diagnostic reader: it does not repair a filesystem or make an image safe to modify.

Checkpoint

The workflow below reads an existing image and writes only a separate output file. It does not need elevated privileges unless your image or destination is restricted. Do not point it at a block device until you have confirmed the device path and intend to read that device.

1. Check the installed command

Confirm the binary and its version before relying on an example. These are ordinary, read-only commands:

$ command -v grub-fstest
/usr/bin/grub-fstest
$ grub-fstest --version
grub-fstest (GRUB) 2.12-1ubuntu7.3
$ dpkg-query -W -f='\${Package} \${Version}\n' grub-common
grub-common 2.12-1ubuntu7.3

The general shape is grub-fstest IMAGE_PATH COMMAND, with the image path always first. A missing image, an unsupported filesystem or a path that does not exist inside the image produces an error and a non-zero exit status.

2. Confirm the image and its filesystem

Use a separate inspection tool to identify the input before handing it to GRUB. This does not alter the image:

$ file /path/to/disk.img
/path/to/disk.img: Linux rev 1.0 ext2 filesystem data, ...

Replace /path/to/disk.img with the real path; the output will vary with the image. Treat a result such as a disk image, encrypted container or unknown data as a stop point until you know which GRUB filesystem and device options apply. Do not guess a partition offset or use sudo to make an uncertain image readable.

For an image containing several input files, the installed command accepts --diskcount=NUM. The default is suitable for the single-image examples here. Multiple-disk arrangements are layout-specific, so establish the image order and root device before using --diskcount or --root.

3. List the root directory

Start with ls rather than guessing a path; it accepts a path inside the image:

$ grub-fstest /path/to/disk.img ls /
boot/ etc/ home/

The names and spacing are image-specific. If the image has a boot directory, inspect it with another listing:

$ grub-fstest /path/to/disk.img ls /boot
grub/ vmlinuz

Use the exact path and spelling shown by the listing. A trailing slash is useful when you mean a directory, but it does not turn a file into one.

Checkpoint

You have identified one real file inside the image, such as /boot/example.txt. Keep that path for the remaining checks.

4. Read a file without extracting it

The cat command writes the file's contents to standard output:

$ grub-fstest /path/to/disk.img cat /boot/example.txt
grub-fstest demo
second line

This is convenient for text, but binary data will be sent directly to your terminal. Use hex for a bounded visual inspection of binary content, or redirect cat to a new file when you deliberately want raw bytes. Shell redirection can overwrite an existing destination, so choose a new name first:

$ grub-fstest /path/to/disk.img cat /boot/example.txt > extracted.txt
$ test -s extracted.txt && echo 'extracted file is non-empty'
extracted file is non-empty

This changes your local destination, not the image. If extracted.txt already contains useful data, move it aside or pick another name before running the command. There is no GRUB undo for a shell redirection that truncates a local file.

5. Compare and checksum the contents

Use cmp when you have a trusted local reference and want an exact comparison:

$ grub-fstest /path/to/disk.img cmp /boot/example.txt /path/to/example.txt
$ printf 'exit status: %s\n' "$?"
exit status: 0

No output and status 0 mean the two byte streams matched; a difference produces a non-zero status. Check the status immediately if you are putting this into a script, since another command can replace $?.

The crc command prints a CRC32 checksum in hexadecimal:

$ grub-fstest /path/to/disk.img crc /boot/example.txt
effb5afd

Use CRC32 as a quick comparison value, not as a security-grade authenticity proof. For evidence or tamper detection, extract the file and calculate a cryptographic hash with a tool and process you trust. The CRC output is data from this particular file, not a universal expected value.

6. Inspect bytes and block locations

hex displays offsets, hexadecimal bytes and a printable character column:

$ grub-fstest /path/to/disk.img hex /boot/example.txt
00000000  67 72 75 62 2d 66 73 74  65 73 74 20 64 65 6d 6f  |grub-fstest demo|
00000010  0a 73 65 63 6f 6e 64 20  6c 69 6e 65 0a           |.second line.|

The exact rows depend on the file. This view is useful for checking headers, line endings and small offsets without asking a shell or text editor to interpret the bytes.

blocklist reports the filesystem blocks used by a file:

$ grub-fstest /path/to/disk.img blocklist /boot/example.txt
2136[0-29]

Block numbers and ranges vary with filesystem creation history. Do not treat them as stable identifiers across a copy, resize or rewrite: a block list is a diagnostic detail for GRUB and filesystem analysis, not a portable way to recover a file from an unrelated image.

7. Copy a file out safely

The cp command copies an image file to a local path:

$ grub-fstest /path/to/disk.img cp /boot/example.txt extracted-copy.txt
$ cmp extracted-copy.txt /path/to/example.txt
$ printf 'exit status: %s\n' "$?"
exit status: 0

The destination is created or overwritten by the command. This is the one example that changes local state, so check the destination first:

$ test ! -e extracted-copy.txt && echo 'destination is unused'
destination is unused

If you need to replace an existing file, copy to a new temporary name, verify it, then use your normal file replacement process. Preserve the original until the result has been checked. No operation in this guide writes back into the image, so there is nothing to undo inside the image itself.

8. Read only a selected range

For large files, --skip=NUM skips bytes before output and --length=NUM limits the number of output bytes. These options affect output commands such as cat:

$ grub-fstest --skip=7 --length=6 /path/to/disk.img cat /boot/example.txt
test d

The numbers are byte counts, not filesystem block numbers, line numbers or hexadecimal offsets. If you want a hexadecimal offset, convert it to a decimal byte count first. A request beyond end of file may produce no data, so check the status and the size of any redirected output.

9. Diagnose a failure without changing the image

For a missing path, expect a non-zero status and an error similar to this:

$ grub-fstest /path/to/disk.img cat /boot/missing.txt
grub-fstest: error: cannot open /boot/missing.txt: file not found.
$ printf 'exit status: %s\n' "$?"
exit status: 1

If ls fails at the root, check the image path and the filesystem type first. If the image is on a protected path, grant the smallest required read permission or run only the read command with the necessary privilege. Do not use sudo for every subsequent command by habit, and never run a write-capable filesystem tool against the image while investigating.

Warning

--crypto and --zfs-key=FILE|prompt are for encrypted devices and are security-sensitive; do not place a secret key in shell history or a world-readable file. --verbose prints more diagnostic messages, --debug=STRING sets the GRUB debug environment variable depending on the subsystem under investigation, and --uncompress should only be used when the stored data is confirmed to be compressed.

Done means

  • Confirmed the version and image type. The installed GRUB build and what file reports about the image.
  • Listed before reading. The image was listed before using an internal path.
  • Read or copied without mounting. The image itself was never modified.
  • Used the right diagnostic. cmp, crc, hex or blocklist for a specific purpose.
  • Checked exit statuses. And protected any existing local destination.
  • Know the limits. Block lists are image-specific and CRC32 is not an authenticity guarantee.