我想使用dd
命令将一个文件写入硬盘的任意位置,然后从该位置读取同一个文件。我需要独立于任何文件系统或分区。这似乎并不容易。先决条件是:
- 为了做到这一点,我需要能够在硬盘上导航。指南针将是扇区,假设 1 个扇区 = 512 B。
- 文件大小假设为 150 B。简单文本文件。
- 我想从 2099200 扇区开始写入此文件。
我尝试了这个:
sudo dd if=my.txt of=/dev/sdb obs=512 seek=2099199
sudo dd if=/dev/sdb of=my.txt obs=150 count=1 ibs=512 skip=2099199
但它不起作用,因为我无法让它只读取 150 B,因为计数ibs
是 512 B。我需要这个计数才能轻松在硬盘上导航,所以它必须是 512 B。
有没有简单的方法可以处理这种情况dd
?或者也许有其他命令或方法可以做到这一点?我需要独立于任何类型的文件系统和分区。
答案1
您可以使用这个来寻求bytes
(2099199*512)
不bs
计数。
dd if=your.txt of=/dev/sdb count=1 bs=150 oflag=seek_bytes seek=1074789888
和
dd if=/dev/sdb of=your.txt count=1 bs=150 iflag=skip_bytes skip=1074789888
看man dd
。
那么:
dd if=your.txt of=/dev/sdb bs=1 count=150 seek=1074789888
和
dd if=/dev/sdb of=your.txt bs=1 count=150 skip=1074789888
答案2
初步说明
需要明确的是:
- 如果您“想从 2099200 扇区开始写入此文件”,则应使用
obs=512 seek=2099200
。扇区从 0 开始编号。“从扇区 0 开始”可以使用seek=0
;“从扇区 1 开始”可以使用seek=1
等。 - 此答案中的命令不包括
sudo
。这是为了便于阅读。只需sudo
在需要时使用即可。
实际答案
我同意,在像你一样写入数据之后,读取时导航的最佳方式是使用ibs=512
。当count=1
你读取 512 个字节时,obs
不能影响这一点。从这 512 个字节中检索出 150 个字节实际上相当容易:
dd if=/dev/sdb ibs=512 skip=2099199 | dd of=my.txt ibs=1 count=150
笔记:
- 第一个
dd
不需要count=1
。如果它在第二个退出后尝试写入管道dd
,它将收到信号(SIGPIPE
)并退出。如果您需要第二个dd
处理例如 9999 个字节,那么只需count
在那里更改就足够了。您不需要count
为第一个计算dd
。管道机制会让它知道其输出是否丢失了接收器。 - 另一种方法是
… | head -c 150
但这不是 POSIX。 一般情况下
dd
可能会读取部分块,因此我使用了ibs=1 count=150
,而不是ibs=150 count=1
(比较这个答案)后者将大概在这种情况下,仍然需要记住,dd
通常可以读取小于的块,ibs
并且每个块仍会增加计数。iflag=fullblock
有帮助,但 POSIX 不需要此功能,您dd
可能不支持它。第一个dd
应该是安全的,尽管ibs=512
有两个原因:- 输入文件是可寻址的,因此
dd
只需计算并请求适当的偏移量。如果它从管道读取,则实际上需要读取 2099199 个块,并且通常其中任何一个都可能是部分的,因此丢弃的数据量可能比您预期的要少。可寻址的输入文件在这方面不会带来任何风险。 - 实际读取一个应该覆盖设备一个逻辑扇区的块时,无法得到部分块。设备要么读取整个扇区,要么什么也不读(读取错误)。请注意,“应该覆盖一个逻辑扇区的块”需要适当的大小和偏移量,它不能从扇区的中间开始。 在你的情况下,这些条件是满足的。
- 输入文件是可寻址的,因此
改进
tar
创建包含两个 512 字节块的档案,其中填充了二进制零作为文件结束标记。这意味着它稍后能够检测到档案的结束位置,可以轻松忽略任何尾随垃圾。此外,它存储元数据(路径、权限等),不限于一个文件,可以存储目录……因此有一些开销,但以下过程似乎很有希望:
档案my.txt
:
tar -cf my.txt.tar my.txt
将档案写入设备:
dd if=my.txt.tar of=/dev/sdb obs=512 seek=2099199
或者您可以在管道中执行两个步骤,而无需创建my.txt.tar
:
tar -cf - my.txt | dd of=/dev/sdb obs=512 seek=2099199
(请注意,存档比原始文件大。唯一的文件结束标记将占用 1 KiB。如果所选扇区之后的某处有数据,则应考虑到这一点。my.txt.tar
在使用之前,应先创建并将其大小与可用空间进行比较dd
。)
无论如何,要检索原始文件,请调用:
dd if=/dev/sdb ibs=512 skip=2099199 | tar -xf -
就是这样。您不需要记住它的大小或名称。您可以tar
对通过管道传输到其标准输入的任何档案执行任何操作;例如,您可以列出内容:
dd if=/dev/sdb ibs=512 skip=2099199 | tar -tvf -