我正在尝试做一个克隆的“高级案例”。
有一个管道写入块设备,在其末端有一个不应触及的分区。我知道这个分区从哪里开始。在这种情况下,我想覆盖分区表。
为了简单起见,管道以 开头dd if=myfile
。
dd if=myfile > /dev/sda
我可以做类似的事情
dd if=myfile | dd bs=1B count=startofmypartition-~1000000 > /dev/sda
但是有没有更好的方法可以做到这一点,并且这种方法有什么缺点吗?
pv
有一个大小选项,但它声明它仅用于计算 ETA,所以我不确定这是否有效:(来自联机帮助页:)
-s SIZE, --size SIZE Assume the total amount of data to be transferred is SIZE bytes when calculating percentages and ETAs. The same suffixes of "k", "m" etc can be used as with -L.
我知道会有更多的写入操作,但结果应该是使用相同空间量的磁盘上的相同数据 - 只要它不是磁带驱动器。
答案1
dd bs=1
效率非常低,因为它每个字节执行一次read()
又一次的write()
系统调用。dd
在块设备上使用无论如何都没有多大意义(除非您想使用特殊标志(例如conv=noerror,sync...
处理错误或偏移量))
在这里你可以这样做:
offset=$(($(cat /sys/class/block/sda3/start) * 512)) &&
pv -trabSs "$offset" < myfile > /dev/sda
head -c "$offset"
(或者如果您不关心进度信息则使用)。
pv
并head
会选择足够的缓冲区大小来优化性能。
(请注意,由于您在磁盘的开头写入数据,因此您将有效地覆盖分区表!)。
/dev/sda
另一种选择可能是创建一个新的块设备,仅映射您愿意覆盖的部分
喜欢:
echo "0 $(cat /sys/class/block/sda3/start) linear /dev/sda 0" |
dmsetup create writable_sda &&
cp myfile /dev/mapper/writable_sda