Linux – dd with obs and seek makes file of unexpected size

ddlinux

I'm learning to use dd by experimentally playing with its arguments. I would like to create a 10-byte file. I thought the following would work:

dd if=/dev/zero of=./foo count=1 bs=1 obs=9 seek=1

…because of these comments from the man page:

   obs=BYTES
          write BYTES bytes at a time (default: 512)
   seek=N skip N obs-sized blocks at start of output

…but it does not; it creates a 2-byte file:

>ls -l foo
-rw-rw-r-- 1 user user 2 Mar 28 16:05 foo

My workaround has been:

dd if=/dev/zero of=./foo count=1 bs=1 obs=1 seek=9

But for my learning, I'd like to understand why the first version does not work. Thank you.

Best Answer

Your command dd if=/dev/zero of=./foo count=1 bs=1 obs=9 seek=1 creates a two-byte file rather than a 10-byte file because of poorly-defined interaction between bs and obs. (Call this a program bug if you like, but it's probably better defined as a documentation bug.) You are supposed to use either bs or ibs and obs.

Empirically it appears that bs overrides obs, so what gets executed is dd if=/dev/zero of=./foo count=1 bs=1 seek=1, which creates a two-byte file as you have seen.

If you had used dd if=/dev/zero of=./foo count=1 ibs=1 obs=9 seek=1 you would have got a 10-byte file as expected.

As an alternative, if you want to create an empty file that doesn't take any data space on disk you can use the counter-intuitively named truncate command:

truncate --size=10 foo