Skip to content
shellmap

ddBlock-level copy and convert — disk imaging, raw I/O, test files across all 5 shells

Equivalents in every shell

Bashunix
dd if=input.bin of=output.bin bs=1M status=progress

Block-level copy. `if=` input file, `of=` output file, `bs=` block size, `count=` block count. `status=progress` (GNU coreutils) prints throughput / ETA to stderr while running — without it `dd` is silent until completion. Send SIGUSR1 (`kill -USR1 <pid>`) on older `dd` to force a one-shot progress line.

Zshunix
dd if=input.bin of=output.bin bs=1M status=progress

Same `/bin/dd`. macOS `dd` is BSD-derived — `status=progress` is NOT supported (BSD lacks it); the equivalent on macOS is to `kill -INFO <pid>` from another terminal, which prints one progress line. Or install `coreutils` via Homebrew and use `gdd`.

Fishunix
dd if=input.bin of=output.bin bs=1M status=progress

Same external binary. Fish parses `bs=1M` as a single argument — no special quoting. `1M` is 1024×1024 in GNU `dd`; use `1MB` for the 1000×1000 SI unit. Common bug: writing `bs = 1M` (with spaces) — `dd` then sees three arguments and complains about unknown operand.

PowerShellwindows
[IO.File]::WriteAllBytes("output.bin", [byte[]]::new(1MB))

No native `dd` cmdlet. For file-to-file byte copies: `[IO.File]::Copy("in.bin","out.bin")`. For "fill a file with zeros": `fsutil file createnew zeros.bin 1048576` (Windows builtin, creates a SPARSE file with bytes-on-demand). For real block-device imaging (writing an .iso to a USB stick), no PowerShell-native path exists — use the `dd` build from Cygwin / Git for Windows or invoke `wsl dd …`.

cmd.exewindows
fsutil file createnew zeros.bin 1048576

cmd has no native `dd`. `fsutil file createnew <path> <bytes>` creates a sparse file of the requested length (instant, regardless of size). For writing real bytes, `copy /b a.bin + b.bin out.bin` concatenates two binary files. Writing an `.iso` to a USB drive from cmd: shell out to `wsl dd if=image.iso of=/dev/sdX bs=4M` or use the `Rufus` GUI.

Worked examples

Create a 100 MB file filled with zeros (test / scratch)

Bash
dd if=/dev/zero of=test.bin bs=1M count=100 status=progress
PowerShell
fsutil file createnew test.bin 104857600
cmd.exe
fsutil file createnew test.bin 104857600

Write a bootable ISO to a USB drive (Linux only — destructive)

Bash
sudo dd if=ubuntu.iso of=/dev/sdX bs=4M status=progress conv=fsync

Image a partition to a compressed file

Bash
sudo dd if=/dev/sda1 bs=4M | gzip > sda1.img.gz
PowerShell
wsl bash -c "sudo dd if=/dev/sda1 bs=4M | gzip > /mnt/c/sda1.img.gz"

Gotchas

  • The historical nickname "disk destroyer" is earned — `of=/dev/sdX` with the wrong device letter wipes the wrong disk in seconds. ALWAYS confirm with `lsblk` (or `diskutil list` on macOS) immediately before running. Tip: paste the entire `dd` line into the terminal but DELETE the leading `sudo ` while you re-check the device — the device-letter check is the failure mode, not the password prompt.
  • `bs=` (block size) tuning matters enormously for throughput — `bs=512` (the default) is often 10–50× slower than `bs=4M` on modern disks. But a too-large `bs` can exceed kernel buffer limits on some kernels (`Cannot allocate memory`). `bs=1M` to `bs=4M` is the safe modern default for full-disk imaging.
  • `count=` is in BLOCKS, not bytes — `dd if=/dev/zero of=f bs=1M count=10` creates a 10-MB file, NOT a 10-byte file. Forgetting this is the canonical "why is my test file 100 GB" mistake.
  • GNU `dd` accepts `status=progress` only since coreutils 8.24 (2015). BSD `dd` (macOS) never accepted it — send `SIGINFO` from another terminal (`kill -INFO <pid>`) for one-shot progress lines, or install GNU coreutils via Homebrew (`brew install coreutils`) and use `gdd`.
  • `dd` writes are NOT durable on exit by default — the kernel page cache may still hold the last megabytes. Pass `conv=fsync` (or follow with `sync`) when imaging removable media; without it, pulling the USB stick the moment `dd` finishes can produce a corrupt image. `oflag=direct` skips the page cache entirely at the cost of throughput.

WSL & PowerShell Core notes

pwshNo native pwsh equivalent to `dd` for raw-device I/O on any platform — `Mount-DiskImage` / `Get-Disk` operate at the volume level, not the byte level. For sparse-file creation on Windows pwsh: `fsutil file createnew` (cmd builtin) or `(New-Object byte[] 1048576)` piped to `[IO.File]::WriteAllBytes`. For real disk imaging from pwsh, shell out to `wsl dd …` on Windows or `& dd …` on Linux/macOS pwsh.
WSLInside WSL2 you CAN `dd` to `/dev/sdX` BUT only AFTER `wsl --mount` has attached the disk — by default WSL only sees its own VHD. `wsl --mount \\.\PHYSICALDRIVEn --bare` from admin pwsh exposes the disk as `/dev/sdb` (or similar) for full byte-level access. Writing to `/mnt/c/` from `dd` works but pays the DrvFs overhead (~3× slower than the WSL-native VHD). For one-shot Windows-side imaging from Windows pwsh: `wsl --user root dd if=/dev/sdX of=/mnt/c/image.bin bs=4M status=progress`.

Related commands