Skip to content
Linux Basics: Inspect Hidden Bytes and Binary Fields with GNU od

Linux Basics: Inspect Hidden Bytes and Binary Fields with GNU od

October 24, 2026

Two files can look identical in a terminal while containing different bytes. GNU od makes those bytes visible, which is useful for checking line endings, examining a small file header, or diagnosing an incorrectly interpreted binary field. It reads data without modifying the input.

These examples were tested on Linux with GNU Bash 5.2.37 and GNU coreutils 9.7. They create tiny local fixtures. Use Bash rather than sh because the scripts rely on Bash printf handling hexadecimal escapes.

Prepare a scratch directory

You need Bash, GNU od, a text editor, and the mktemp, rm, and rmdir utilities. Keep using the same terminal. Save each named source file here and run it once in order. No administrator access or executable-permission change is needed.

start_dir="$PWD"
work_dir="$(mktemp -d)" || exit 1
cd -- "$work_dir" || exit 1

1. See different line endings

Save this as od-line-endings.sh:

#!/usr/bin/env bash
set -eu
export LC_ALL=C
printf 'OK\r\n' > crlf.txt
printf 'OK\n' > lf.txt
printf 'CRLF bytes:\n'
od -An -tx1 crlf.txt
printf 'LF bytes:\n'
od -An -tx1 lf.txt

Run it:

bash od-line-endings.sh

Output:

CRLF bytes:
 4f 4b 0d 0a
LF bytes:
 4f 4b 0a

The letters OK have the same two bytes in both files. The first file then contains carriage return (0d) followed by line feed (0a); the second has only line feed. This is an inspection step, not a conversion.

-An suppresses offset labels, and -tx1 displays each one-byte unit in hexadecimal. Specifying the format avoids relying on the default octal representation. See the GNU od manual for its supported output types.

2. Inspect a bounded slice

Save this as od-byte-range.sh:

#!/usr/bin/env bash
set -eu
export LC_ALL=C
printf '\x4d\x41\x47\x43\x01\x02\x03\x04' > packet.bin
od -Ax -tx1 -j4 -N3 packet.bin

Run it:

bash od-byte-range.sh

Output:

000004 01 02 03
000007

This invented packet starts with the four ASCII bytes MAGC. The inspection skips those four bytes and displays at most the next three. Offsets are hexadecimal because of -Ax, so the first displayed byte is at offset four. The final offset is seven, the position immediately after the inspected slice, not the full file length of eight.

Bounding the read is useful when you only need a header or a small suspect region of a large file. Here, -j4 and -N3 are unambiguous decimal counts; GNU od also recognizes other numeric forms, so avoid casually adding leading zeros to these arguments.

3. Choose the byte order explicitly

Save this as od-byte-order.sh:

#!/usr/bin/env bash
set -eu
export LC_ALL=C
printf '\x01\x02\x00\x10' > counters.bin
printf 'Big-endian unsigned 16-bit values:\n'
od -An -tu2 --endian=big counters.bin
printf 'Little-endian unsigned 16-bit values:\n'
od -An -tu2 --endian=little counters.bin

Run it:

bash od-byte-order.sh

Output:

Big-endian unsigned 16-bit values:
   258    16
Little-endian unsigned 16-bit values:
   513  4096

-tu2 interprets two-byte units as unsigned decimal integers. The first pair, 01 02, is 258 when its first byte is most significant, but 513 when its first byte is least significant. The second pair demonstrates the same distinction with 00 10.

The file did not change between these reads. Only the interpretation changed. Select the order specified by the file format rather than assuming that the machine running the command uses the same convention.

Keep in mind

This is a byte viewer, not a complete binary-format parser. A plausible number does not establish that you selected the correct field, width, signedness, or offset. Consult the format specification before interpreting real data.

By default, repeated output rows can be abbreviated with an asterisk; the -v option disables that abbreviation when you need every row. These short fixtures do not trigger it. Byte values also do not directly tell you how many user-perceived characters a Unicode string contains.

Do not dump secret-bearing files into shared logs or screenshots. Inspecting locally is different from publishing the resulting bytes, which may reveal the original data.

Clean up

Remove only these practice files and return to your original directory:

rm -- od-line-endings.sh od-byte-range.sh od-byte-order.sh \
  crlf.txt lf.txt packet.bin counters.bin
cd -- "$start_dir" || exit 1
rmdir -- "$work_dir"
unset start_dir work_dir

Acknowledgements

This post was created with assistance from AI.

Last updated on