dd: different unit for bs, skip and count?
Sebastian Wright
I am trying to copy a partition from an entire disk image.
This command is working: dd if=image.iso of=test bs=512 skip=1161215 count=32768
In order to increase the speed, I'd like to set a bigger bs.
dd if=image.iso of=test bs=1M skip=1161215 count=32768
skip and count's unit is bs, is it possible to set a separate unit ?
I could then make this command:
dd if=image.iso of=test bs=4M skip=1161215*512 bytes count=32768*512 bytes
4 Answers
Specify Different Units
Yes, it is possible to specifiy different units for bs and skip and count. However, there are only two choices for the skip and count units. skip and count must match the bs value or be specified in bytes. To set the units to bytes you must add an additional operand of iflag=skip_bytes for skip and iflag=count_bytes for count or iflag=skip_bytes,count_bytes for both.
In your case, this command should accomplish your goal:
dd if=image.iso of=test iflag=skip_bytes,count_bytes bs=4M \ skip=$((1161215*512)) count=$((32768*512))It appears you want to extract exactly 16M. Set bs=4M count=4 and use only skip_bytes:
dd if=input.file of=output.file iflag=skip_bytes bs=4M \ skip=$((1161215*512)) count=4Example for testing:
An input file with the contents:
aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzzWith count_bytes (extract exactly count bytes):
$ dd if=input.file of=output.file iflag=skip_bytes,count_bytes bs=8 skip=5 count=20yields 20 characters:
cddeeffgghhiijjkkllmWithout count_bytes (count is multiplied by bs):
dd if=input.file of=output.file iflag=skip_bytes bs=8 skip=5 count=3yields 24 characters:
cddeeffgghhiijjkkllmmnnoYour version of dd may not include iflag, skip_bytes, or count_bytes.
These examples were tested on Debian 9 using dd (coreutils) 8.26.
It is possible by combining dd commands.
dd if=image.iso bs=4M | { dd bs=1161215 count=1 of=/dev/null; dd bs=${16*512} count=${32768/16} of=partition.dump; }
We can just use the count size as a dividable without remainder instead of both, offset and size.
Or use the end sectors.
2What you want to achieve seems impossible to me.
From man dd:
bs=BYTES read and write up to BYTES bytes at a time ibs=BYTES read up to BYTES bytes at a time (default: 512) obs=BYTES write BYTES bytes at a time (default: 512) count=N copy only N input blocks skip=N skip N ibs-sized blocks at start of inputWhile bs (or ibs and obs) has an argument BYTES which determines the block size i.e. the amount of bytes that gets processed at once, the count and seek parameters have an argument N which determines the number of blocks to process/skip.
So as dd can always only copy or skip whole blocks of data (block size determined by bs/ibs&obs), you must set the block size to a value by which the skip offset and the count size are dividable without remainder.
is it possible to set a separate unit?
AFAIK, with dd only, no.
but you can use losetup to achieve your goal, like this:
dd if=$(losetup --sector-size 512 --offset $((1161215*512)) --sizelimit $((32768*512)) --find --show image.iso) of=test bs=4Mor, more concisely, like this:
dd if=$(losetup -b 512 -o $((1161215*512)) --sizelimit $((32768*512)) -f --show image.iso) of=test bs=4MEven more...
In order to increase the speed, I'd like to set a bigger bs
if you just want to 'forget about' "blocksize optimization", and it's available for you, simply use pv, like this:
pv $(losetup -b 512 -o $((1161215*512)) --sizelimit $((32768*512)) -f --show image.iso) > test 1