Home / Alt manpages / dd(1)

  • dd(1)
  • User command
  • linux

Use dd Safely for Exact Copies, Blocks and Conversions

dd earned the nickname "disk destroyer" one typo in of= at a time. Learn to copy exact bytes, count blocks and convert text with dd without guessing what its operands mean. Allow about fifteen minutes.

  • You need: a shell and enough space under /tmp for a few small test files.
  • What it touches: the practice commands change only files you create there. The disk-device examples later are warnings and inspection commands, not commands to paste unchanged.
  • Tested on: GNU coreutils dd 9.4, from package version 9.4-3ubuntu6.3.

1. Check the installed command

Find out which executable your shell runs and note its version:

$ command -v dd
/usr/bin/dd
$ dd --version | head -1
dd (coreutils) 9.4

dd takes operands like if= and of= rather than the usual option style. The core shape is dd if=INPUT of=OUTPUT.

  • No if=: it reads standard input.
  • No of=: it writes standard output.

Checkpoint

Never run it until the input and output paths are visibly different and the output is one you intend to create or replace.

2. Copy a file to a new destination

Make a small source file and copy it to a new path. No elevated privileges needed:

$ work_dir=$(mktemp -d /tmp/dd-guide.XXXXXX)
$ printf '%s\n' 'dd copy check' > "$work_dir/source.txt"
$ dd if="$work_dir/source.txt" of="$work_dir/copy.txt" status=none
$ cmp -- "$work_dir/source.txt" "$work_dir/copy.txt"
$ printf 'copy verified: %s\n' "$work_dir/copy.txt"
copy verified: /tmp/dd-guide.XXXXXX/copy.txt

The random part of the directory name changes on every run. cmp prints nothing and returns status 0 when the files match, so the final message only follows a successful comparison.

  • Block sizes: input and output both default to 512 bytes. That is a detail of the transfer, not a claim that the file is made of 512-byte records.
  • status=none: hides the transfer summary dd normally prints to standard error, while still showing errors. Drop it when you want the statistics.

3. Count blocks, not guesses

count=N stops after N input blocks. A block is the current input block size: 512 bytes by default, or whatever ibs= or bs= says. So count=1 does not always mean one byte:

$ printf '0123456789abcdef' > "$work_dir/sixteen.txt"
$ dd if="$work_dir/sixteen.txt" of="$work_dir/first-eight.txt" bs=1 count=8 status=none
$ wc -c < "$work_dir/first-eight.txt"
8
$ od -An -tc "$work_dir/first-eight.txt"
   0   1   2   3   4   5   6   7

Here bs=1 makes each block one byte, so count=8 means eight bytes. Without it, a short regular file would normally be copied in one short input block, and the result would not express the same selection.

Size suffixes are part of dd's syntax, and they bite:

  • kB means 1000.
  • K and KiB mean 1024.
  • MB is decimal; M is binary.
  • A trailing B on a number counts bytes rather than blocks.

Write the unit explicitly when a boundary matters:

$ dd if="$work_dir/sixteen.txt" of="$work_dir/first-four.txt" bs=1 count=4 status=none
$ wc -c < "$work_dir/first-four.txt"
4

Checkpoint

Verify the byte count with wc -c, or compare a digest, before using the pattern on a large file.

4. Convert data while copying

The conv= operand applies a documented conversion during the transfer. A harmless one, lower case to upper:

$ printf '%s\n' 'mixed Case' > "$work_dir/mixed.txt"
$ dd if="$work_dir/mixed.txt" of="$work_dir/upper.txt" conv=ucase status=none
$ cat "$work_dir/upper.txt"
MIXED CASE

Others include lcase, swab, sync, sparse, and character-set conversions such as ascii and ebcdic. Yes, EBCDIC: dd still speaks mainframe.

Tip

The installed manual accepts a comma-separated list of its own conversion symbols. Do not borrow names from another tool's documentation.

Warning

An existing destination is opened for writing and can be truncated. Write to a new temporary file when the original matters, inspect the result, then replace the old file as a separate deliberate step. If the destination must not already exist, add conv=excl and the command fails instead of overwriting.

5. Use offsets without mixing up units

  • skip=N skips input blocks.
  • seek=N skips output blocks.

Their units follow the input and output block sizes. This pulls four bytes starting at byte offset four:

$ dd if="$work_dir/sixteen.txt" of="$work_dir/offset.txt" bs=1 skip=4 count=4 status=none
$ od -An -tc "$work_dir/offset.txt"
   4   5   6   7

Warning

With bs=4096, skip=1 skips 4096 input bytes, not one. If input and output need different units, set ibs= and obs= separately rather than quietly relying on one shared bs=.

Short reads matter when the input is a pipe or device. iflag=fullblock makes dd accumulate input until a full input block is available. It matters for streamed block counts; it will not fix a mistaken offset.

6. Treat devices as destructive targets

Destructive action

Writing to a device can destroy a partition table, filesystem, boot loader or every file on the disk, and a typo in of= is enough. There is no undo for overwritten device data. Elevated privileges may be required, but sudo does not make an unsafe destination safe.

Before any device-writing command:

  • Identify the device. Independently, not by its size alone.
  • Unmount anything that must not be written.
  • Confirm the destination twice.
  • Have a recovery plan.

Inspect block devices without writing to them:

$ lsblk -o NAME,PATH,SIZE,TYPE,MOUNTPOINTS
$ findmnt --source /dev/EXAMPLE

Replace /dev/EXAMPLE only with a path you have independently identified.

For imaging:

  • Keep the source read-only where your hardware and procedure allow it.
  • Write the image to a separate destination.
  • Hash or otherwise verify the result. dd reports that bytes moved; it does not prove the source was the disk you meant or that no storage error happened later.

Tip

Need progress from a running job? Send it USR1 from another terminal using its process ID. The manual documents that it prints I/O statistics and then carries on.

Recovery

Stop a mistaken job promptly, then preserve the output and investigate rather than immediately trying another write.

7. Diagnose failures and clean up

Capture the status straight after dd. Non-zero means the copy or conversion failed, so do not treat a partly written destination as complete:

$ dd if="$work_dir/missing" of="$work_dir/result" status=none
dd: failed to open '/tmp/dd-guide.XXXXXX/missing': No such file or directory
$ printf 'dd status: %s\n' "$?"
dd status: 1

The temporary directory name in the error will vary. Check paths with ls -l and readability with test -r; do not jump to sudo before confirming the path.

When you are done, remove only the temporary directory you created:

$ rm -rf -- "$work_dir"
$ test ! -e "$work_dir" && echo 'temporary test files removed'
temporary test files removed

Warning

This is safe here only because mktemp assigned work_dir. Never swap in an empty variable, a broad directory, or a path copied from an untrusted source.

Done means

  • Paths confirmed: you checked the GNU coreutils version and the exact input and output paths.
  • Units clear: you can say whether count, skip and seek are counting bytes or blocks in your command.
  • Copies verified: you checked a small copy with cmp and selected sizes with wc -c.
  • Originals protected: conversions go to a new destination, with conv=excl for no-overwrite cases.
  • Devices respected: you treat device writes as destructive, identify devices independently and know dd has no undo.
  • Clean finish: you captured the exit status and removed only the temporary files you made.