使用Linux dd在指定位置复制和读取文件


1

我想使用该dd命令在硬盘驱动器的任何位置写入一个文件,然后从该位置读取相同的文件。我需要独立于任何文件系统或分区。这样做似乎并不容易。先决条件是:

  1. 为了做到这一点,我需要能够在硬盘上导航。指南针将是扇区,假设1扇区= 512 B.
  2. 文件大小,比方说150 B.简单文本文件。
  3. 我想从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?或者也许有另一个命令或方法来做到这一点?我需要独立于任何类型的文件系统和分区。

Answers:


0

你可以用这个来寻求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 

不幸的是我的dd版本似乎没有这个标志。
ncheltsov 2013年

0

初步说明

只是要清楚:

  • 如果您“想要从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退出后尝试写入管道,它将获得一个signal(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与管道传输到stdin的存档有关的事情; 例如,你可以列出内容:

dd if=/dev/sdb ibs=512 skip=2099199 | tar -tvf -
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.