Isso é lento devido ao tamanho pequeno do bloco. Usando um GNU dd
recente ( coreutils v8.16 + ), a maneira mais simples é usar o skip_bytes
e count_bytes
opções:
in_file=1tb
start=12345678901
end=19876543212
block_size=4096
copy_size=$(( $end - $start ))
dd if="$in_file" iflag=skip_bytes,count_bytes,fullblock bs="$block_size" \
skip="$start" count="$copy_size"
Atualizar
fullblock
opção adicionada acima conforme @Gilles answer . No começo eu pensei que poderia estar implícito em count_bytes
, mas este não é o caso.
Os problemas mencionados são um possível problema abaixo, se dd
s chamadas de leitura / gravação forem interrompidas por qualquer motivo, os dados serão perdidos. Isso não é provável na maioria dos casos (as chances são reduzidas um pouco desde que estamos lendo de um arquivo e não de um pipe).
Usar uma dd
sem as opções skip_bytes
e count_bytes
é mais difícil:
in_file=1tb
start=12345678901
end=19876543212
block_size=4096
copy_full_size=$(( $end - $start ))
copy1_size=$(( $block_size - ($start % $block_size) ))
copy2_start=$(( $start + $copy1_size ))
copy2_skip=$(( $copy2_start / $block_size ))
copy2_blocks=$(( ($end - $copy2_start) / $block_size ))
copy3_start=$(( ($copy2_skip + $copy2_blocks) * $block_size ))
copy3_size=$(( $end - $copy3_start ))
{
dd if="$in_file" bs=1 skip="$start" count="$copy1_size"
dd if="$in_file" bs="$block_size" skip="$copy2_skip" count="$copy2_blocks"
dd if="$in_file" bs=1 skip="$copy3_start" count="$copy3_size"
}
Você também pode experimentar diferentes tamanhos de bloco, mas os ganhos não serão muito dramáticos. Veja - Existe uma maneira de determinar o valor ideal para o parâmetro bs para dd?