‘seek’ argument in command dd

dd

Can some explain me what is happening in the following lines?

dd if=/dev/urandom bs=4096 seek=7 count=2 of=file_with_holes

especially seek part is not clear

Man pages says :

 seek=BLOCKS
              skip BLOCKS obs-sized blocks at start of output

What is obs-sized block?

Best Answer

dd is designed to copy blocks of data from an input file to an output file. The dd block size options are as follows, from the man page:

ibs=expr
    Specify the input block size, in bytes, by expr (default is 512).
obs=expr
    Specify the output block size, in bytes, by expr (default is 512).
bs=expr
    Set both input and output block sizes to expr bytes, superseding ibs= and obs=.

The dd seek option is similar to the UNIX lseek() system call1. It moves the read/write pointer within the file. From the man page:

seek=n
    Skip n blocks (using the specified output block size) from the beginning of the output file before copying. 

Ordinary files in UNIX have the convenient property that you do not have to read or write them starting at the beginning; you can seek anywhere and read or write starting from there. So bs=4096 seek=7 means to move to a position 7*4096 bytes from the beginning of the output file and start writing from there. It won't write to the portion of the file that is between 0 and 7*4096 bytes.

Areas of ordinary files that are never written to at all aren't even allocated by the underlying filesystem. These areas are called holes and the files are called sparse files. In your example, file_with_holes will have a 7*4096-byte hole at the beginning. (h/t @frostschutz for pointing out that dd truncates the output file by default.)

It is OK to read these unallocated areas; you get a bunch of zeroes.

[1] back when dd was written, the analogous system call was seek().