====quick dd primer====
Those with little patience and low observation skills are often quick to label **dd** a difficult or weird tool. While it is true that **dd** is no **ls**, it is a powerful tool, quite useful in its particular domain.
**dd** is referred to as a **d**ata **d**ump or **d**ata **d**uplicator... namely, its task is to copy information, and to do so very well.
In some respects, it is like **cp**, only vastly more capable, as it sees and allows you control over more of the file (a file is made up of bytes-- **cp** just copies the whole file, because it works in units of files; **dd**, on the other hand, sees a file as a sequence of bytes).
In other respects, it is like **cat** (then again, one can also perform file copies with **cat**)... in that it reads input and produces output.
Unlike **cp** and **cat**, **dd** specializes in byte-level operations. Both **cat** and **cp** are limited to operating on the entire file as a basic operation. **dd** goes a bit deeper.
===Example 0: dd as cp===
If we had a file, **/etc/motd**, and we wanted to make a copy of it in our current working directory under the name **thing**, we could do this:
lab46:~/src/unix/udr0$ dd if=/dev/motd of=thing
1+1 records in
1+1 records out
859 bytes (859 B) copied, 0.000149696 s, 5.7 MB/s
lab46:~/src/unix/udr0$
As previously stated, **dd** specializes in byte level operations. So it is a far more articulate file copy.
We see two options being used with **dd**:
* if= this specifies what the input file will be
* of= this specifies what the output file will be
And with this, **dd** will read from /etc/motd and output to thing (in current directory).
As it is, **dd** was able to operate on the file as one chunk (similar to how **cp** or **cat** would work), but we can go deeper.
===Example 1: Fine-Grained cp with dd===
For example, to specifically copy the file byte-by-byte:
lab46:~/src/unix/udr0$ dd if=/etc/motd of=thing bs=1
859+0 records in
859+0 records out
859 bytes (859 B) copied, 0.00400408 s, 215 kB/s
lab46:~/src/unix/udr0$
Notice the number of records has changed to match the file size (there are 859 bytes in the file, so a byte by byte copy would result in 859 records). Also note the transfer speed went down... 859 byte transfers is a lot more expensive than 1 larger information transaction.
That new option, **bs**, allows for the setting of the block size. In this case, we're setting the block size of that **dd** transaction to 1 byte from its default.
===Example 2: dd as cat===
To simulate **cat** using **dd**, we merely instruct it where to send its data:
lab46:~/src/unix/udr0$ dd if=/etc/motd of=/dev/tty
##############################################################################
## __ _ _ _ __
## | | __ _| |__ / | |_/ / LAIR Public Shell Machine
## | |__/ _` | '_ \\_ _/ _ \
## |_____\__,_|_.__/ |_|\___/ Lab46 is the CCC Computer & Information
## --------------------------- Science public shell box for student course-
## c o r n i n g - c c . e d u work, projects, and skills exploration.
##
## PLEASE USE THE SYSTEM, LAIR, AND RELATED RESOURCES RESPONSIBLY!
##
## LAB46 RESOURCES:
## website: http://lab46.corning-cc.edu/
## help form: http://lab46.corning-cc.edu/help_request
## help contact: haas@corning-cc.edu or wedge@lab46.corning-cc.edu
##
## USAGE INFORMATION:
## basic usage: type 'usage' at the prompt
## check mail: type 'alpine' at the prompt; broken? type 'fixmail'
##
1+0 records in
1+0 records out
859 bytes (859 B) copied, 0.000158424 s, 5.4 MB/s
lab46:~/src/unix/udr0$
Due to "everything being a file", displaying to STDOUT is merely specifying a file that corresponds to your terminal screen.
And if you wanted to redirect it to a file? It's STDOUT, so your I/O redirectors will work as expected.
There are many additional options in **dd**, so it is highly recommended you read through the manual page and experiment.
===example 3: grabbing the last 200 bytes===
Let's say we wanted to only grab the last 200 bytes of that 859 byte file.
**cp** and **cat** would have some difficulty easily doing this on their own... perhaps with other tools this could be facilitated, but it falls within the capabilities of what **dd** can do (it does what it does extremely well).
It turns out there is a **skip** option to **dd**, that let's it skip ahead some number of blocks in the input before it starts processing. We want to use that to grab the last 200 bytes in the file.
First, we need to figure out how much to skip... knowing the file is 859 bytes, and desiring only the last 200 bytes, we use a little math:
859
-200
===
659
So, let's give it a shot:
lab46:~/src/unix/udr0$ dd if=/etc/motd of=/dev/tty skip=659
dd: ‘/etc/motd’: cannot skip to specified offset
0+0 records in
0+0 records out
0 bytes (0 B) copied, 0.000252174 s, 0.0 kB/s
lab46:~/src/unix/udr0$
Wut rohs! Seems there is some problem.
This is what tends to throw beginners for a loop with **dd**, they forget that **dd** does not assume a block size of 1 byte, but something larger. Well, we just told **dd** to skip 659 blocks into the file... and if a block is more than 1 byte (we saw in our first examples it was at least 859 bytes), then this would be an unreasonable/nonsensical request.
So let us fix it, by specifying a block size of 1:
lab46:~/src/unix/udr0$ dd if=/etc/motd of=/dev/tty bs=1 skip=659
s@corning-cc.edu or wedge@lab46.corning-cc.edu
##
## USAGE INFORMATION:
## basic usage: type 'usage' at the prompt
## check mail: type 'alpine' at the prompt; broken? type 'fixmail'
##
200+0 records in
200+0 records out
200 bytes (200 B) copied, 0.00165582 s, 121 kB/s
lab46:~/src/unix/udr0$