Skip to content
shellmap

cmpCompare two files byte-by-byte and report the first difference across all 5 shells

Equivalents in every shell

Bashunix
cmp a.bin b.bin

Silent on identical files (exit 0); prints `a.bin b.bin differ: byte N, line M` on first byte mismatch (exit 1); errors out on read failure (exit ≥ 2). `-l` lists EVERY differing byte (not just the first); `-s` (silent) suppresses output for use in shell tests like `cmp -s a b && echo "same"`.

Zshunix
cmp a.bin b.bin

Same external `cmp` (POSIX). macOS BSD cmp has the same `-l` and `-s` flags as GNU coreutils. Differences are marginal — GNU adds `--print-bytes` (`-b`) which shows the differing byte values in addition to offsets; BSD cmp lacks `-b`.

Fishunix
cmp a.bin b.bin

Same external. Fish's exit-code idiom — `if cmp -s a b; echo same; else; echo differ; end` — reads cleaner than bash's `&&`/`||` chain. Fish does NOT auto-export `$status` to subshell positions, so always check explicitly.

PowerShellwindows
(Get-FileHash a.bin).Hash -eq (Get-FileHash b.bin).Hash

pwsh has no byte-by-byte file comparator. `Get-FileHash` (SHA-256 default) gives a same/differ verdict but not WHERE the difference is. For "where does it differ" use `Compare-Object` on `[byte[]]` arrays, or shell out to `fc /b a b` (cmd.exe binary compare). For large files, `Get-FileHash` is fastest (single-pass hash).

cmd.exewindows
fc /b a.bin b.bin

`fc /b` (binary mode) is cmd.exe's built-in byte comparator — outputs each differing byte offset + values in hex. Without `/b`, fc does line-mode comparison (defaults to text). Always pass `/b` for binary files; `/n` for line numbers; `/c` for case-insensitive text.

Worked examples

Silent test: did the two files match?

Bash
cmp -s a.bin b.bin && echo "identical" || echo "differ"
PowerShell
if ((Get-FileHash a.bin).Hash -eq (Get-FileHash b.bin).Hash) { "identical" } else { "differ" }
cmd.exe
fc /b a.bin b.bin > nul && echo identical || echo differ

List EVERY differing byte (not just the first)

Bash
cmp -l a.bin b.bin
PowerShell
Compare-Object ([IO.File]::ReadAllBytes('a.bin')) ([IO.File]::ReadAllBytes('b.bin')) -IncludeEqual:$false
cmd.exe
fc /b a.bin b.bin

Compare two file streams (e.g. from network) without writing to disk

Bash
cmp <(curl -s https://a.example.com/file) <(curl -s https://b.example.com/file)
PowerShell
(Invoke-WebRequest a -OutFile a.tmp; Invoke-WebRequest b -OutFile b.tmp; (Get-FileHash a.tmp).Hash -eq (Get-FileHash b.tmp).Hash)

Gotchas

  • Exit codes are documented but easy to misread: `0` = identical, `1` = differ (NOT an error), `≥ 2` = read / argument error. Scripts that treat non-zero as failure will wrongly report identical-vs-different as a failure — use `cmp -s; case $? in 0) echo same;; 1) echo differ;; *) echo error;; esac`.
  • `-l` (list all) without `-b` (print bytes) outputs `byte_offset octal_a octal_b` — OCTAL by default, which surprises everyone (people expect hex or decimal). Use `-b` on GNU cmp for `byte_offset decimal_a "value_a" decimal_b "value_b"` format; BSD cmp has no `-b`.
  • `cmp` reads BOTH files in parallel, stopping at the first byte difference (without `-l`). For huge files that differ early, this is fast (no need to read the rest). For huge files that differ LATE (or not at all), it reads both files in full — slower than `Get-FileHash` (which can use hardware-accelerated SHA-NI on x86_64 / ARM crypto extensions for ~10× throughput).
  • cmd `fc /b` writes the offset in HEX, but cmp on Linux writes byte-counts in DECIMAL. Cross-comparing tool output is confusing — pick one tool for a script and stick with it.
  • Files with one-byte length differences: `cmp` reports `EOF on a.bin after byte N` for the SHORTER file — useful diagnostic. `Get-FileHash` just says "different hash" with no clue about the cause. For length-then-content comparison, `cmp` is more informative.

WSL & PowerShell Core notes

pwshNo native byte-cmp. The closest cross-OS idiom is `(Get-FileHash a).Hash -eq (Get-FileHash b).Hash` (works on every pwsh) — fast but no "where does it differ" diagnostics. For full cmp parity, install via Git for Windows (`C:\Program Files\Git\usr\bin\cmp.exe`) or WSL.
WSLWSL `cmp /mnt/c/a.bin /mnt/c/b.bin` works transparently. For comparing a Windows-side file against a WSL-side file, both paths in the same command resolve through DrvFs vs ext4 — `cmp` doesn't care about the filesystem, just byte order. DrvFs reads are slow on multi-GB files; copy to `/tmp` for speed.

Common tasks using cmp

Related commands