disk dump. And a nice cup size. As the man page says it's for converting and copying files, if we go by the name specifically to clone disks. Which means just copying a file - since we know on Linux, everything is a file. It can convert character encoding (from EBCDIC to ASCII and back, not sure how handy that is these days) or uppercase to lowercase for example, or make a copy of the content of a disk to another, or create iso images of disks, or the other way around copy an iso to a device such as an USB. It can copy a specified part of a file, or - by ommitting the output file - display (copy it to stdout) specific part of a file.
How useful 'dd' is for our purpose? I use it quite rarely, and I imagine basically oldschool and old sysadmins are the main userbase of it. First thing comes to mind is creating bootable usb sticks from an iso of a Linux distro. That can be achieved with other CLI tools such as 'cp' and 'cat'. It is still worth to talk about for it looks quite irregular.
Let's see a generic example, which should be harmless if you try it yourself, "according to my readings" awfully lot can go wrong in case of 'dd'. But again, mistakes can be done with 'cp' the same, I don't see huge warnings about that.
dd if=.bashrc of=testcopy bs=1024 conv=noerror,sync status=progress
This is an unusual syntax! Each option takes a parameter, no '-' or '--' anywhere. To be honest in the line above the last three options are unnecessary we just duplicate a tiny file, but those are the often used options, better get used to them, and they demonstrate well how they should be written. Note 'conv' which we supplied with two parameters, separated by a comma. See the 'man' page for the complete list of parameters and "symbols" - how it calls the parameters.
So how 'dd' differs from other tools beyond the syntax? It can do nifty things, such as read from the keyboard and output to the screen. If you issue...
dd
...in its naked self you get a prompt where you can type stuff, hit enter type some more, and again, and perhaps one more time, and then press Ctrl-D (EOT = End of Transmission), and lo it will repeat everything you wrote and close it with a report of records (in and out), byte copied, time elapsed, and copy speed in Kb/s. Okay, this is not very interesting or useful in itself, but a feature. Issue:
dd if=.bashrc
See, we can print files to the screen as well. But we can print part of a file too:
dd if=.bashrc bs=1024 count=1
Maybe this is more useful if we know which part of the file we need.
So, 'bs' is bytes - default is 512 -, literally how many bytes are read and wrote by 'dd'. Not just bytes can be used, values like 'bs=4k', 'bs=4K', 'bs=4kB', 'bs=8MB', etc. are valid as well, see the 'man' page of 'dd', take note that some of these multipliers are decimal (1000x1000) and some based on 1024 (binary).
The 'count' option means how many times those bytes from the start of the file will be read and written, how many blocks of data we work with. This opens up some interesting possibilities for us, because, well, you know, everything is a file on Linux. For the next command - and the following iterations of it - you need elevated rights, so 'su -' or 'sudo'. We're gonna print some data from the very beginning of our first disk, where the master boot record resides.
dd if=/dev/sda bs=1024 count=5
If this doesn't print out some gibberish try changing the count, start at 1, and increase it by steps of 1 until you get something. All these should be binary data so don't expect anything recognisable. If the terminal starts to look a bit wonky or too much data is displayed try paging through the result by piping the output into 'less':
dd if=/dev/sda bs=1024 count=20 | less
Don't forget: this is 1Kb of data 20 times (so 20Kb, right?). If your home folder is on a specific partition - you can check it with the 'lsblk' command -, let's say on 'sda5' or 'sda6', then you could try:
dd if=/dev/sda6 bs=1024 count=20 | less
Somewhere at the beginning it should clearly say:
/home
I tried to come up with another way of reading he home partition, so added the directory path. I got an error message:
dd: error reading '/home/bestuserever/': Is a directory
So this is a no go. But we could try something else to get something readable. Let's go back to sda's master boot record. We're gonna pipe the output into 'od' which stands for "octal dump" if we go after the man page, elsewhere I read "octal display". The '-a' option will "translate" the result to readable format.
dd if=/dev/sda bs=1024 count=1 | od -a
In theory the command we pipe the output into should be:
od -a -
The last hyphen makes 'od' to take input from stdin instead of a file, but did not see any difference in the output in this case. Anyway.
Another feature of 'dd' is that it can jump given amount of 'bs' sized blocks:
dd if=/dev/sda bs=1024 count=1 skip=3 | od -a -
Again, this is more useful if we know what we are looking for.
These are short tasks but cloning a whole disk can take a while. 'dd' has a handy progress display so we can know things are happening we just need to be patient. If you are following this by typing each command and checking what it does, you should stop, this will be a fictious command. We're returning to the addition of an output file, and add one option from the first example.
dd if=/dev/sda1 of=/dev/sdb1 bs=4k status=progress
This will print transfer statistics, updating every second. It counts the bytes copied, elapsed time, and the speed of the operation in MB/s. There is two other 'status' setting: 'none' and 'noxfer'. The latter will suppress the final statistics report you could observe if you issued any of the commands above, the first suppresses all.
Now, about the conversion possibilities. Quite a lot, so we'll just take a look at that lower/upper case conversion. Let's go back to .bashrc:
dd if=.bashrc count=1 conv=ucase
My result:
# ~/.BASHRC: EXECUTED BY BASH(1) FOR NON-LOGIN SHELLS.
# SEE /USR/SHARE/DOC/BASH/EXAMPLES/STARTUP-FILES (IN THE PACKAGE BASH-DOC)
# FOR EXAMPLES
Stop screaming, dude! Jesus!
All right enough of the fun. We printed to the stdout again, and omitted the block size, the default 512 is enough. But we wanted to print just the first block, so added that 'count' option. The 'conv=ucase' told the command to convert everything to uppercase, surprisingly.
Perhaps we should note how to "burn" an iso to an USB stick. It is not much different from the things above.
dd if=debian-11.1.0-amd64-DVD.iso of=/dev/sdb bs=1M status=progress
See how I changed the block size. In theory using larger blocks will make the process faster, to a certain block size. It's quicker to copy larger chunks fewer times, with the cost of a bit higher RAM usage. There are some tests published online (for example on stackexchange) that suggests at 64M the effectiveness starts to wane. If you stick to 4 megabytes every time, it won't be a mistake.
Now that I mentioned stackexchange, I remembered a comment there how it is possible to create sparse files with 'dd'. A "sparse file" is a file when the contents of a file don't match the size of the file, so the actual filesize is smaller thant the stated. You'll understand in a sec. Firs create a directory for this experiment, then add some files to create some content there. Here I'll use 'dd' for that.
mkdir test
dd if=/dev/random of=test/content bs=64k count=218
Now check the size of the directory, with 'du':
du -d 0 -h test
We should get:
14M test
Now the command. What I saw was this:
dd if=/dev/zero of=test/sparse-file bs=1 count=1 seek=10GB
The block size is 1 byte, and we call it only once. The 'seek' option tells to skip a certain amount of blocks - in our case in the size of 10GB -, from the start of the file before writing. So essentially we appended 1 byte of data at the end of 10GB of nothing. List the files in the 'test' directory:
ls -alh test
There should be a line saying 'sparse-file' with 9,4G exists in that directory. Now check directory size with du again:
du -d 0 -h test
14M test
Nice!
Okay. I think we saw enough examples to get familiar with the syntax, and to see some possibilities in the usage.
Note: the suggestion that you can wipe data from a disk with 'dd' - for example in case you wish to sell a hard drive - is not entirely true. Even after several pass of the wiping process the data is recoverable. One can f*ck up his system by overwriting something important, but as far as secure data destroyer... 'dd' is a no go.