1. Overview
The dd command is a well-known tool for converting and copying data. It’s helpful in tasks like disk cloning, creating ISO images, recovering data, and others. Furthermore, dd offers the seek option enabling us to leave the first blocks of the output file intact.
In this tutorial, we’ll look at examples of real-life use cases with the dd command and its seek option.
2. Basic Use of the seek Option
Setting a value n for the seek option makes the dd command skip the first n blocks of the output file and begins copying data after them.
Let’s look at how this affects the behavior of dd.
2.1. The seek Option
In summary, if we set n as the value of the seek option, we can keep the first n blocks of the output file unmodified. In this case, the command starts adding data, if any, after the n-th block of the output file.
Critically, dd performs data copying in blocks, which means that it copies chunks of data. Thus, any skipping of blocks is multiplied by the block size to arrive at the final byte count that we’re going to seek to.
To determine the size of each block we use the options bs, ibs, and obs:
- ibs: set block size for reading data from the input file
- obs: set block size for writing data to the output file
- bs: set both input and the output block size, overriding the ibs and obs options
Having said that, let’s proceed with an example.
2.2. Example Use of the seek Option
Let’s create both an input and an output text file to examine the functionality of dd with the seek option:
$ echo 'of Linux!!!' > inputf
$ echo 'Hello World ' > outputf
Here, we write the ‘of Linux!!!’ string value to the inputf file. Similarly, we write the ‘Hello World ‘ string value to outputf.
Next, let’s execute the dd command to copy data from inputf to outputf.
$ dd if=inputf of=outputf bs=1 seek=12
12+0 records in
12+0 records out
12 bytes copied, 8.38e-05 s, 143 kB/s
$ cat outputf
Hello World of Linux!!!
As we can see, the output file contains the concatenation of the two string values. Let’s examine the options that we used:
- if: set input file
- of: set output file
- bs: set block size
- seek: offset of the copied data in blocks
The above example has two essential aspects. Firstly, we set the block size to 1 byte so that dd copies each character individually. Secondly, we set the seek option to be equal to the size of the output file. As a result, the dd command starts copying data at the end of the output file. Consequently, the string value of the input file is appended to the string value of the output file.
3. Creating Sparse Files
We can use the dd command with the seek option to create sparse files in a similar way to the truncate command. With sparse files, although the resulting file is empty, it has a file size that’s greater than zero.
The idea is to set the seek option to the desired size of the output file while instructing the dd command to copy zero blocks:
$ dd of=sparsefile bs=1 seek=100 count=0 status=none
$ ls -al
total 8
drwxrwxr-x 2 ubuntu ubuntu 4096 Jul 18 10:27 .
drwxr-x--- 6 ubuntu ubuntu 4096 Jul 18 10:07 ..
-rw-rw-r-- 1 ubuntu ubuntu 100 Jul 18 10:27 sparsefile
$ cat sparsefile
$
Indeed, we created an empty file called sparsefile with a size of 100 bytes, as confirmed by ls. Since we don’t need an input file, we can skip the if option.
A key point here is that we set the seek option to 100 so that an empty offset of 100 bytes is created for the output file. Additionally, we specify the count option as 0, so that no data is copied. That’s because the count option sets the number of blocks that the dd command will copy.
4. Creating Backups
Next, we’ll use the dd command with the seek option to back up and restore a filesystem.
4.1. Creating a Filesystem
Linux provides the tools to create a filesystem in a file and mount it to the existing filesystem.
First, let’s create the myfs file as we did in the previous section:
$ dd of=myfs bs=4K seek=64 count=0 status=none
Here, we created the myfs file which is empty and has a size of 256K.
Next, let’s create an ext4 filesystem:
$ sudo mkfs.ext4 myfs
mke2fs 1.46.5 (30-Dec-2021)
Filesystem too small for a journal
Discarding device blocks: done
Creating filesystem with 64 4k blocks and 32 inodes
Allocating group tables: done
Writing inode tables: done
Writing superblocks and filesystem accounting information: done
As we can see, we used the mkfs.ext4 command to create the filesystem in myfs. Notably, the block size of the filesystem is 4K. To ensure that no data is missed due to misalignment, it’s important to set the same block size to the dd command when we execute it.
Next, let’s create the mount point and then mount the filesystem:
$ mkdir mnt
$ sudo mount myfs mnt
As expected, we mounted our new filesystem at the mnt directory.
Finally, we can create a test file in our filesystem:
$ cd mnt
$ echo "Hello World of Linux" | sudo tee testfile
Hello World of Linux
At this point, we’ve created a filesystem in a file and a test file within this filesystem. In addition, we wrote a string value in the test file using echo and tee.
4.2. Creating a Backup File
After creating and possibly using it, we’re ready to create a backup file of our filesystem with the dd command.
Before creating the backup file let’s unmount the filesystem:
$ sudo umount mnt
Now, let’s create the backup file:
$ dd if=myfs of=myfs.bak bs=4K skip=1
63+0 records in
63+0 records out
258048 bytes (258 kB, 252 KiB) copied, 0.0003089 s, 835 MB/s
Here, we named the backup file myfs.bak. Importantly, the skip parameter is set to 1, so the dd command won’t copy the first block of the input file to the output file.
Before proceeding with the restoration process, let’s modify testfile:
$ sudo mount myfs mnt
$ echo "Error in file" | sudo tee mnt/testfile
Error in file
$ sudo umount mnt
As we can see, we modified the testfile file so that we can restore its original content from the backup file.
4.3. Restoring the Backup File
At this point, we use the dd command to restore our filesystem from the backup file:
$ dd if=myfs.bak of=myfs bs=4K seek=1
63+0 records in
63+0 records out
258048 bytes (258 kB, 252 KiB) copied, 0.0002998 s, 861 MB/s
Now, we’ve restored the backup file. The key point here is the use of the seek option instead of skip. During the backup process, we skipped copying the first block of the filesystem. Thus, the restore should now start copying the backup data after the first block of the filesystem. This is accomplished by the seek option.
To verify the restoration process, let’s mount the filesystem and print the contents of the testfile file. The file should contain its original message:
$ sudo mount myfs mnt
$ cat mnt/testfile
Hello World of Linux
Indeed, the file contains the Hello World of Linux message, which was contained in the file when we created the backup file.
5. Conclusion
In this article, we examined the functionality of the seek option of the dd command.
Initially, we looked at the basic use of the option, and then we saw an example of creating a sparse file. Finally, in the last example, we created a filesystem within a file and then performed both a backup and a restore operation using the seek option.