16

What tools other than dd should I use to read and write files with truncation, seeking and skipping? dd's command line options seem inconvenient and foreign and I don't like choosing between slow, but precise seeking mode (bs=1) and fast, but inflexible mode (bs=4k or whatever).

Are there more modern tools to read 555 bytes from one file (or pipe or socket or dev) from position 31337 and write them to the other file at position 128205 (using blocks 512+43), with or without truncation?

12
  • 2
    I still don't see what is wrong with dd. You could always put a shell script wrapper around it if you don't like the interface. dd is in the POSIX standard, which is a huge plus.
    – jw013
    Jul 31, 2012 at 18:55
  • 3
    The main wrong thing is inability to seek to or skip fractional blocks. Second wrong thing that status=noxfer is not default and is broken and that I need iflag=fullblock (omit in some script => broken data).
    – Vi.
    Jul 31, 2012 at 20:25
  • 4
    1. bs=1 => the whole pipeline is slow. For example I may want to dump video file starting from some exact frame. 2. "It takes some arithmetic" => not very suitable for oneliners and routine shell commands.
    – Vi.
    Jul 31, 2012 at 20:58
  • 1
    PSA: dd conv=seek_bytes will make seek work with byte precision.
    – i336_
    Jun 6, 2017 at 10:30
  • 1
    @i336_ I think it just means that the safest option for us would be to avoid using a shell script and write a standalone statically-linked executable. I was just shopping around for alternatives because from time to time I hear about crazy stuff being possible directly in bash, and wondered whether direct file access might be one of those crazy things.
    – Hakanai
    Oct 24, 2018 at 5:09

4 Answers 4

5

There is the tool ddrescue (watch out, there is also dd_rescue which is a different program with almost the same functionality). It uses the more familiar syntax with the single dash for short or double dash for long options. From the man page:

   -i, --input-position=<bytes>
          starting position in input file [0]

   -K, --skip-size=<bytes>
          initial size to skip on read error [64 KiB]

   -M, --retrim
          mark all failed blocks as non-trimmed

   -o, --output-position=<bytes>
          starting position in output file [ipos]
4
  • 2
    ddrescue - - -> Infile and outfile are the same., ddrescue /dev/stdin /dev/stdout -> Infile and outfile are the same.. Bad beginning of the story...
    – Vi.
    Jul 31, 2012 at 20:59
  • I just tried with dd_rescue. It throws a warning that the file (stdin) is not seekable, but proceeds. You can give it a try. However, ddrescue feels more full-featured and mature.
    – Marco
    Jul 31, 2012 at 21:32
  • 3
    @Vi.: Don't shoot the messenger. ddrescue is right, pipes aren't seekable. If you want to start reading at a specific point in a file, you need to give it access to the file in question, not data piped from another program. Also beware that using pipes fights against this wish of yours for ultimate speed, since the only way to emulate seeking in a pipe is to read and throw away the parts you don't want to process. Seeking within an actual file is far more efficient. Aug 1, 2012 at 10:53
  • Indeed, since the tool is designed for rescuing broken data, there is no pipe capability. This is a bit of a shame when you want the flexibility of seeking through an input file but just want to pipe the result to stdout. For its intended purpose, though, it's great. Jun 25, 2015 at 12:53
5

dcfldd is another dd alternative. It doesn't address the OP's question about input/output seek flexibility, but may be useful to others arriving here via google search.

It's based on gnu dd, with the following additional features:

  • Hashing on-the-fly - dcfldd can hash the input data as it is being transferred, helping to ensure data integrity.
  • Status output - dcfldd can update the user of its progress in terms of the amount of data transferred and how much longer operation will take.
  • Flexible disk wipes - dcfldd can be used to wipe disks quickly and with a known pattern if desired.
  • Image/wipe Verify - dcfldd can verify that a target drive is a bit-for-bit match of the specified input file or pattern.
  • Multiple outputs - dcfldd can output to multiple files or disks at the same time.
  • Split output - dcfldd can split output to multiple files with more configurability than the split command.
  • Piped output and logs - dcfldd can send all its log data and output to commands as well as files natively.
3

A good alternative is pv. Not only does it automatically calculate the most efficient block size, essentially speeding things up, but it also provides progress, among other things. It's use is simple:

pv < /dev/sda > sda.img

It plays well with compression too. A fast way to backup and compress a disk in one move is like so:

pv < /dev/sdb | pigz -9 > disk.img.gz

You can learn more here.

1
  • 4
    Main expected feature is seeking in output and input files, which pv (pipe view) does not provide, as there is no seek for pipes.
    – Vi.
    Mar 23, 2016 at 11:53
3

You can actually use a dd pipe to accomplish this, without the performance penalty, without truncation or rounding errors, and with byte-level accuracy:

dd iflag=skip_bytes,count_bytes skip=1234 count=42 | dd oflag=seek_bytes conv=notrunc seek=12340 of=test.bin

On the left side, dd will skip the first 1234 bytes and read exactly 42 bytes. It will perform with efficient sector buffering and alignment. Exactly 42 bytes will be read at offset 1234 with no rounding errors. On the right side, dd will seek past exactly 12340 bytes on the output and write only the 42 bytes it receives from the pipe. It will perform with efficient sector buffering and alignment. In the pipeline, the two dd instances will send+receive data in sector-sized chunks for good performance, except for the last few bytes which are handled properly.

Note that there is no oflag for count_bytes, so this pipeline is required!

Here is an example attempting to count only 2 bytes, but without the pipeline. Notice that extra data is consumed on the input and written to the output:

$ printf aaa | dd oflag=seek_bytes conv=notrunc seek=0 count=2 | xxd
0+1 records in
0+1 records out
00000000: 6161 61                                  aaa
3 bytes copied, 0.000158916 s, 18.9 kB/s
1
  • Add "iflag=count_bytes" to your example counting only 2 bytes, and it indeed only counts two bytes. So, I don't think the pipe is needed. (It makes sense that dd takes in the same number of bytes as it sends out.) Aug 31 at 15:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .