Inspect Binary Files Safely with GNU od
A file will not open in your editor and you need to know what is actually sitting inside it, byte for byte: that is the job od does. You will finish with a small, repeatable toolkit for looking at binary data: hexadecimal bytes with an ASCII view, bounded reads, offsets, printable strings and multi-byte integers. The examples use GNU coreutils 9.4, the installed version checked for this guide.
The route
Jump straight to the step you need, or tick off Done means at the end.
- Time: about fifteen minutes.
- You need: a shell and a file you are allowed to read. The examples create a disposable file under
/tmp. - Safe to run: none of this needs
sudoand none of it alters the input being inspected. Do not use this workflow to edit a binary file.
1. Check the installed command
Confirm which executable will run and record its version. Both commands are read-only:
$ command -v od
/usr/bin/od
$ od --version | head -1
od (GNU coreutils) 9.4
The portable name od has several implementations, and their options or output can differ. This guide describes the GNU implementation shown above. If yours is different, check its local manual with man od before copying an option into a script.
Checkpoint
You have confirmed the command and version. Keep the original input file available; od only ever reads it.
2. Make a known input for a first test
Use a controlled byte sequence so you can recognise every value in the output. This creates a new file, replacing that path if it already exists, so pick a disposable one:
$ printf 'ABC\000hello\n' > /tmp/od-demo.bin
$ wc -c /tmp/od-demo.bin
10 /tmp/od-demo.bin
The file contains the bytes for ABC, a NUL byte, hello and a newline. If /tmp/od-demo.bin matters on your machine, stop and choose another destination before running the command. The file you inspect for real can be anywhere you have permission to read.
3. Start with a readable hex dump
Use -t x1z for hexadecimal one-byte values plus printable characters at the right. -A x makes the byte address hexadecimal, and -v stops repeated lines being replaced by an asterisk:
$ od -A x -t x1z -v /tmp/od-demo.bin
000000 41 42 43 00 68 65 6c 6c 6f 0a >ABC.hello.<
00000a
The address on the left is the offset of the first byte on that line. The final address is the offset after the last byte, so it reads 0x0a, ten bytes. The dot in the character column represents the non-printable NUL byte, and the angle brackets are output markers, not bytes in the file.
Without an explicit -t, GNU od uses octal output, useful for traditional Unix diagnostics but often awkward when comparing a file with a protocol spec or hex editor. Make the format explicit in scripts and notes.
4. Limit the view with an offset and byte count
Use -j to skip input bytes and -N to stop after a fixed number of bytes. Both accept the size suffixes documented by the manual, but plain decimal counts keep this example obvious:
$ od -A d -t u1 -j 3 -N 5 /tmp/od-demo.bin
0000003 0 104 101 108 108
0000008
This starts at byte offset 3, the NUL, and reads five bytes. The values are unsigned decimal one-byte units: 0, then the ASCII values for h, e, l and l. The address column is decimal because of -A d.
Bound the read when investigating a very large or unusual file. It stops an accidental full dump from flooding your terminal, but it does not make a device or named pipe safe to read; treat non-regular files as potentially blocking or hardware-sensitive and identify them with file or stat first.
Checkpoint
Compare the first address and the number of values against your intended range. An offset is zero-based, so -j 3 means the fourth byte.
5. Choose formats for the question you have
-t can be repeated, so one command can show more than one interpretation. These are the most useful types for routine inspection:
| Type | Meaning | Typical use |
|---|---|---|
x1 | hexadecimal one-byte units | raw bytes and file signatures |
u1 | unsigned decimal one-byte units | byte values without hexadecimal conversion |
o2 | octal two-byte units | GNU od's traditional default style |
d4 | signed decimal four-byte units | checking a signed integer interpretation |
c | printable characters or escapes | seeing text and control bytes |
s | NUL-terminated printable strings | quick strings triage |
For a character-oriented view of the test file, drop the address column with -A n:
$ od -A n -t c /tmp/od-demo.bin
A B C \0 h e l l o \n
That is useful for compact output, but keep addresses enabled when you need to report where a value occurs.
6. Find embedded strings without dumping everything
Use -S to show only NUL-terminated strings of at least a chosen length. GNU od defaults this minimum to three printable characters when the byte count is omitted:
$ od -S 5 /tmp/od-demo.bin
0000004 hello
The address is octal by default here, so 0000004 is decimal offset four. The command finds hello but not ABC, because the latter is shorter than five characters. Strings output is a triage aid, not proof a file is text or that a discovered value means anything: binary data can contain misleading fragments.
7. Check byte order with multi-byte units
When a file stores integers, byte order matters. GNU od provides --endian=big and --endian=little for swapping the input bytes used by multi-byte types. Create four known bytes and read them as two-byte hexadecimal units:
$ printf '\001\002\003\004' > /tmp/od-words.bin
$ od -An -t x2 --endian=big /tmp/od-words.bin
0102 0304
$ od -An -t x2 --endian=little /tmp/od-words.bin
0201 0403
Do not guess a file's byte order from whichever output looks familiar. Use the file format specification, a known marker or a trusted parser; the endian options affect interpretation, they do not rewrite the input.
Safety boundary
Reading a regular file is normally unprivileged. If a path is protected, first ask whether your account should have access. Avoid casually using sudo od, especially in scripts, because it can hide an ownership or permissions problem and expose sensitive contents to the terminal or logs.
Common traps
If the output is too large, add -N, reduce the width with -w16, or select a narrower type. -w controls bytes per output line; without a value, GNU od uses 32 bytes. For a compact four-byte-per-line hex view:
$ od -A x -t x1z -w4 /tmp/od-demo.bin
000000 41 42 43 00 >ABC.<
000004 68 65 6c 6c >hell<
000008 6f 0a >o.<
00000a
- Address looks wrong. Check both
-Aand whether you used-j. - Multi-byte value looks reversed. Confirm the format's byte order before reaching for
--endian. - File cannot be opened. Check the path with
ls -l --and the access decision withtest -r; do not solve a typo with elevated privileges.
When a command's output ends up in a ticket, record the exact command, the GNU coreutils version, the input path and whether offsets are decimal, octal or hexadecimal. That small bit of context stops a correct byte dump being misread later.
Done means
- Version confirmed: the installed
odis GNU coreutils 9.4, or you checked the manual for your implementation. - Bounded dump: you can produce a hex dump with byte offsets and an ASCII view, limited to the bytes you need.
- Offsets understood: you know offsets are zero-based and that address radix is set separately from data format.
- Strings triaged, not trusted: you can inspect printable strings without treating them as proof about the file.
- Byte order verified: you checked it with a known byte sequence before interpreting multi-byte values.
- Input untouched: you avoided unnecessary elevated privileges throughout.