dd to read and write one byte at a time. There is an overhead for each
write call, which makes this slow. Use a larger block size for decent performance.
When you copy a whole file, at least under Linux, I've found that
cat are faster than
dd, even if you specify a large block size.
To copy only part of a file, you can pipe
head. This requires GNU coreutils or some other implementation that has
head -c to copy a specified number of bytes (
tail -c is in POSIX but
head -c isn't). A quick benchmark on Linux shows this to be slower than
dd, presumably because of the pipe.
tail -c $((2345678901+1)) | head -c $((19876543212-2345678901))
The problem with
dd is that it is not reliable: it can copy partial data. As far as I know,
dd is safe when reading and writing to a regular file — see When is dd suitable for copying data? (or, when are read() and write() partial) — but only as long as it isn't interrupted by a signal. With GNU coreutils, you can use the
fullblock flag, but this is not portable.
Another problem with
dd is that it can be hard to find a block count that works, because both the number of skipped bytes and the number of transferred bytes count need to be a multiple of the block size. You can use multiple calls to
dd: one to copy the first partial block, one to copy the bulk of aligned blocks and one to copy the last partial block — see Graeme's answer for a shell snippet. But don't forget that you when you run the script, unless you're using the
fullblock flag, you need to pray that
dd will copy all the data.
dd returns a nonzero status if a copy is partial, so it's easy to detect the error, but there's no practical way to repair it.
POSIX has nothing better to offer at the shell level. My advice would be to write a small special-purpose C program (depending on exactly what you implement, you can call it