Skip to content
shellhacks.dev
Linux

How to Use dd to Copy Disks and Create Images Safely

Use dd on Linux to copy disks and make images safely: block size, status=progress, conv options, verifying the copy, and the mistakes that destroy data.

6 min read
Summarize in AI
Illustration for "How to Use dd to Copy Disks and Create Images Safely": a terminal session, a disk usage gauge, file permission bits.

The command is nicknamed "disk destroyer" for a reason: it does exactly what it is told, with no confirmation. Used carefully, it is the simplest way to image a disk or write an installer to a USB stick. This post covers the safe invocation, and the follow-up backing up a disk covers the strategy. The commands assume GNU coreutils 9.x.

Identify the device first

Shell
lsblk -o NAME,SIZE,TYPE,MOUNTPOINT,MODEL
Text
NAME   SIZE TYPE MOUNTPOINT MODEL
sda  476.9G disk            Samsung SSD
├─sda1 512M part /boot/efi
└─sda2 476G part /
sdb   14.9G disk            USB Flash Drive
└─sdb1 14.9G part /media/usb

Match by size and model, not by letter. The device letters can change between boots when you plug a drive in or out. If a partition is mounted, unmount it first with sudo umount /dev/sdb1 so nothing writes to it while it is copied.

Write an image to a USB stick

Shell
sudo dd if=debian-13-netinst.iso of=/dev/sdb bs=4M status=progress conv=fsync
sync
Text
678428672 bytes (678 MB, 647 MiB) copied, 38 s, 17.9 MB/s
162+1 records in
162+1 records out
679477248 bytes (679 MB, 648 MiB) copied, 38.9 s, 17.5 MB/s

Write to the whole device (/dev/sdb), not a partition (/dev/sdb1), because an installer image carries its own partition table. status=progress prints a running rate; without it dd is silent until the end. conv=fsync makes dd flush its writes before it reports done, so removing the stick right after is safe.

Make an image of a disk

Shell
sudo dd if=/dev/sdb of=usb-backup.img bs=4M status=progress conv=sync,noerror
sha256sum usb-backup.img
sudo cmp /dev/sdb usb-backup.img

Reading from the device and writing a file gives you a bit-exact image. conv=noerror,sync continues past read errors and pads the unreadable blocks with zeros, which keeps offsets aligned but hides damage, so use it only on a failing disk and prefer ddrescue for that job. cmp compares the copy to the device and prints nothing when they match. Restore by swapping if and of, with the same care. An image can be inspected without restoring, as in mounting an image.

Wipe and test

Shell
sudo dd if=/dev/zero of=/dev/sdb bs=1M count=10 status=none
dd if=/dev/zero of=/tmp/speed.bin bs=1M count=1024 oflag=direct

Zeroing the first megabytes removes a partition table and file system signature, which is enough to make a drive look blank to most tools. oflag=direct bypasses the page cache so a throughput test measures the device rather than memory, though a proper benchmark tool gives better numbers, as explained in the page cache.

Why dd is dangerous

The command copies bytes from an input to an output with no questions asked. It does not check that the output is the right device, that it is not mounted, or that it is not your system disk. A mistyped of=/dev/sda instead of /dev/sdb overwrites the wrong disk and nothing brings the data back. Nicknamed "disk destroyer" for a reason, it deserves a routine before every use: list devices with lsblk -o NAME,SIZE,MODEL,SERIAL,MOUNTPOINT, confirm the size and model match the target, unmount any partitions, and read the command back before pressing Enter. Using the stable names under /dev/disk/by-id/ instead of /dev/sdX avoids the problem of device letters changing between boots and when you plug in another drive.

Some people alias or wrap dd to demand confirmation. A small script that prints the target's model and size and asks for the device name to be typed is cheap insurance for a command that is used rarely and carries high consequences.

Block size, progress and syncing

The default block size of 512 bytes is slow. A larger value such as bs=4M reduces the number of system calls and speeds up copying to a typical USB stick or disk. Very large values do not help and use memory. The option status=progress prints a running count of bytes and speed, which is useful for long operations that otherwise look hung. At the end, conv=fsync or a separate sync flushes buffered data to the device. Without it, dd can finish while the data still sits in the page cache, and removing the USB stick early produces a corrupt image. Wait for the prompt to return after the flush before unplugging.

Direct IO flags such as oflag=direct bypass the cache and give an honest progress figure, at the cost of speed on some devices. Use them when you want to measure real device throughput.

Verifying a copy

A copy that was not verified is a hope. After writing an image to a device, compare the first bytes of the device against the image with cmp, limiting the comparison to the image's size: cmp -n SIZE image.iso /dev/sdX. Alternatively, compute a checksum of the image and a checksum of the same number of bytes read back from the device, using head -c to cut it. When cloning a disk, compute checksums of both source and destination with the source not mounted for writes. For failing disks, ddrescue is the better tool: it retries bad areas intelligently, records progress in a map file and can be resumed, where dd stops or pads errors in ways that hide damage.

Never write to the source of a recovery attempt. Work on an image or a copy, and keep the original untouched until the data is safely recovered.

Other uses and safer alternatives

The same command makes files of a given size for tests, with if=/dev/zero of=file bs=1M count=100, backs up a boot sector with count=1 and wipes partition table remnants. For random data, /dev/urandom is the source, which is slow as a wiping method and unnecessary on modern drives: a single pass of zeros suffices for general use, and devices with built-in secure erase commands are best sanitised with them. For writing installer images, many distributions recommend dedicated tools that verify the result and refuse to write to system disks, and those are friendlier for occasional use. Where a file-level copy is enough, rsync is safer, since it never overwrites a whole device. Reserve dd for the cases that need exact bytes, and treat each use as a ritual with the same checks every time.

Write down the procedure when you do this regularly, with the exact device naming scheme and the verification step. For imaging a fleet of identical machines, a tool designed for it, with multicast support and file system awareness that skips unused space, finishes in a fraction of the time that a raw copy takes. A raw copy of a mostly empty 1 TB disk transfers 1 TB, while a file-system-aware tool transfers only the used blocks. Compress images on the fly with gzip or zstd when storing them, and remember the decompression step when restoring.

Where this does not apply

For a disk with a failing sector, ddrescue retries intelligently and keeps a map file, which dd cannot. Copying a mounted, live file system produces an inconsistent image; snapshot it or use file-level tools. SSDs and compressed targets gain nothing from zero-filling. The GNU dd manual lists every operand and conversion.

For long copies, send the process a signal to see progress without restarting: sudo kill -USR1 $(pidof dd) makes GNU dd print its counters once. The GNU ddrescue manual describes the better tool for damaged media.

Taggedddlinux
Share

Keep reading

Get new posts by email

One email when a new post is published. No spam.

Unsubscribe in one click. No spam, ever.